في 13 سبتمبر 2020 ، أقيم يوم تصويت واحد في روسيا. في بعض المناطق ، استخدمت المعارضة استراتيجية "التصويت الذكي" ، حيث يصوت الناخبون ذوو التوجهات المعارضة لمرشح واحد لديه أعلى فرصة لهزيمة ممثل من السلطات.
للسنة الثانية على التوالي ، تسببت عملية اختيار المرشحين لـ "التصويت الذكي" في مناقشات حول موضوع الشفافية. بالإضافة إلى ذلك ، أنا شخصياً في حيرة من أمري بسبب الصعوبات في تلخيص الاستراتيجية التي قد يواجهها المحللون المستقلون. لا ينشر منظمو UMG النتائج التفصيلية للاستراتيجية ، ولكن فقط الرسوم البيانية التي توضح عدد مرشحي المعارضة الذين دخلوا البرلمان الإقليمي.
على موقع "التصويت الذكي"لا يمكنك الحصول على قائمة المرشحين المدعومين من خلال تحديد ، على سبيل المثال ، المدينة والمنطقة. إذا أراد شخص ما جمع البيانات للمنطقة ، فسيتعين عليه العمل بجد لاختيار عناوين لكل منطقة.
في أي حال من الأحوال لا أعيب مطوري موقع UMG على الويب ، فهو يمتلك كل الوظائف المطلوبة لتنفيذ استراتيجية التصويت. ولكن نظرًا لحقيقة أنه في عام 2019 لم يشارك أحد في جمع ونشر بيانات مفصلة عن نتائج UMG (خارج انتخابات موسكو) ، فقد قررت في هذه الانتخابات أخذ زمام المبادرة بيدي.
والنتيجة هي جدول ملخص مثل هذا . في هذه المقالة ، سأخبرك كيف تم الحصول على مجموعة البيانات المحددة ، وكيف تم جمع المعلومات من مواقع التصويت الذكي وخدمة الويب الجديدة لـ CEC .
موقع التصويت الذكي
أولاً ، دعنا نرى ما هي البيانات التي يمكننا استخراجها من موقع التصويت الذكي. يوجد في الصفحة الرئيسية للموقع حقل لإدخال عنوان تسجيل المستخدم. عند إدخال سلسلة ، تظهر قائمة بالعناوين المقترحة بالتنسيق التالي:

عند اختيار أحد العناوين المقترحة ، يتم توجيهنا إلى صفحة مركز الاقتراع التي تم إرفاق العنوان المحدد بها:

تسرد الصفحة الحملات الانتخابية التي تجري في هذه المنطقة. لكل حملة ، هناك قائمة بالمرشحين / ضدهم:

في هذه الحالة ، نرى انتخاب المحافظ ، الذي لم يشر فيه الاتحاد العام الاتحادي إلى مرشح معارض. ويرجع ذلك إلى أن انتخابات المحافظين تجري على دورتين ولا يهم أي من مرشحي المعارضة سيصوت الناخبون في الجولة الأولى.
كما نرى ثلاثة مرشحين في وقت واحد ، يُعرض عليهم التصويت في انتخابات برلمان المدينة. ويرجع ذلك إلى حقيقة أن الانتخابات في سوتشي تضم دوائر انتخابية متعددة الأعضاء.
في جميع الحملات الانتخابية الأخرى ، التي شاركت في UMG هذا العام ، كانت هناك دوائر انتخابية ذات عضو واحد فقط.
لنلقِ نظرة على رمز الصفحة ونجد أن جميع البيانات الموصوفة مجمعة بتنسيق JSON مناسب. في العنصر بالمعرف = "__ NEXT_DATA__"، والتي تستخدم لرسم الصفحة ، هناك معلومات حول قلم الاقتراع والحملات الانتخابية والمرشحين:
محتوى عنصر __NEXT_DATA__
{
"props":{
"pageProps":{
"id":"440384",
"settings":{
"id":1,
"share_photo":"/ganimed-media/share_photo/smartvote_sharepic_1200x628.jpg",
"video_on_main_page":"https://youtu.be/w8gapDGwWMY",
"fake_mode":false,
"title_share":", ",
"text_share":" , — « ». — .",
"telegram_bot_link":"https://tlinks.run/smartvotebot",
"viber_bot_link":"viber://public?id=smartvote",
"facebook_bot_link":"https://facebook.com/umnoegolosovanie/",
"alice_link":null,
"vk_bot_link":null
},
"serverData":{
"commission":{
"id":440384,
"number":"4317",
"address":"354340, , , , , 24",
"descr":" № 49 . .. ",
"lat":"43.425923",
"lon":"39.920152",
"region_id":26,
"region_intid":"135637827259064320000372513"
},
"campaigns":[
{
"id":26,
"code":"krasnodar-gub-2020",
"title":" ",
"is_regional":true,
"ready_date":null,
"district":{
"id":458,
"code":"oik-0",
"name":"0",
"leaflet":""
},
"candidates":[
{
"id":998,
"name":" ",
"share_image":"/elections-api-media/share/26/998.png",
"anticandidate":true,
"self_nominated":false,
"has_won":false,
"has_second_round":false,
"party":{
"title":" ",
"antiparty":true
}
}
]
},
{
"id":28,
"code":"krasnodar-sochi-gorduma-2020",
"title":" ",
"is_regional":false,
"ready_date":null,
"district":{
"id":526,
"code":"oik-2",
"name":"2",
"leaflet":"/elections-api-media/28/526-1334-1335-5385.pdf"
},
"candidates":[
{
"id":1334,
"name":" ",
"share_image":"/elections-api-media/share/28/1334.png",
"anticandidate":false,
"self_nominated":true,
"has_won":false,
"has_second_round":false,
"party":null
},
{
"id":1335,
"name":" ",
"share_image":"/elections-api-media/share/28/1335.png",
"anticandidate":false,
"self_nominated":true,
"has_won":false,
"has_second_round":false,
"party":null
},
{
"id":5385,
"name":" ",
"share_image":"/elections-api-media/share/28/5385.png",
"anticandidate":false,
"self_nominated":false,
"has_won":false,
"has_second_round":false,
"party":{
"title":"",
"antiparty":false
}
}
]
}
]
},
"error":null,
"currentUrl":"https://votesmart.appspot.com/candidates/440384"
}
},
"page":"/candidates/[id]",
"query":{
"id":"440384"
},
"buildId":"U8hjaoxZw8TINu-DU_Ixw",
"runtimeConfig":{
"HOST":"https://votesmart.appspot.com"
},
"isFallback":false,
"customServer":true,
"gip":true
}
بالنسبة لمحطة الاقتراع ، يتم الإشارة إلى رقم (رقم) لجنة الانتخابات العامة المقابلة ومعرفها في قاعدة بيانات موقع ويب UMG. المعرف = 440834 يطابق الرقم الموجود في عنوان URL للصفحة (/ المرشحين / 440834).
هل يمكننا ، بمعرفة رقم PEC والمنطقة ، حساب معرّف العمولة على موقع UMG؟ لم أتمكن من العثور على تبعية واضحة ، حيث يتم توزيع المعرفات بطريقة فوضوية تمامًا:
Sochi، PEC # 4512 -> id = 440834
Sochi، PEC # 4513 -> id = 441403
Sochi، PEC # 4514 -> id = 1781216
كيفية جمع قائمة من انعكاسات الأرقام PEC في صفحات الهوية؟ يبدو من غير المجدي للغاية تكرار وفحص جميع أنواع المعرفات من 1 إلى 2،000،000 ، معظم هذه المعرفات لا تعمل.
ولكن ، إذا كانت لدينا قائمة بالعناوين ، فيمكننا بسهولة نسبيًا وضع قائمة بمراكز الاقتراع ذات الصلة. عند إدخال سلسلة في الشاشة الأولية ، يتم إرجاع قائمة بالعناوين المناسبة من الخادم ، جنبًا إلى جنب مع معرفات العمولة المقابلة:
ابحث عن موقع حسب العنوان
https://votesmart.appspot.com/api/v1/cik/addresses?query=ADDRESS
- العنوان - العنوان ، ويفضل أن يكون بالصيغة "الموضوع ، المدينة ، الشارع ، المنزل". من المستحسن أيضًا بدون الاختصارات "شارع" ، "د." ، نظرًا لأن المحلل اللغوي على الخادم لا يتعامل معها جيدًا
طلب مثال:
https://votesmart.appspot.com/api/v1/cik/addresses؟query= Lenin Smolensk
نتيجة الاستعلام
{
"suggestions":[
{
"value":" , , , ",
"data":{
"fullname":" , , , ",
"level":"7",
"region_id":69,
"commission_id":null,
"intid":"138474570115456000000347353",
"path":"135637827259064320000359815,135637827259064320000359819,135637827259064320000359820,138474570115456000000347353",
"snippet":" , <em></em>, , <em></em> ",
"score":118.84238
}
},
{
"value":" , , , , 12",
"data":{
"fullname":" , , , , 12",
"level":"8",
"region_id":69,
"commission_id":1124357,
"intid":"135659820348349440000359937",
"path":"135637827259064320000359815,135637827259064320000359819,135637827259064320000359822,135659820348349440000359708,135659820348349440000359937",
"snippet":" , <em></em>, , <em></em> , 12",
"score":115.14931
}
},
...
]
}
أين يمكنني الحصول على قائمة عناوين لاستخراج البيانات من الموقع؟ يبدو أن تعداد قاعدة البيانات لجميع العناوين في البلد هو حل غير فعال ، لأنه لحل مشكلتنا ، نحتاج فقط إلى عنوان واحد لكل دائرة انتخابية.
كل دائرة لها متوسط من 2 إلى 8 دوائر انتخابية. على الرغم من أن عنوان مركز الاقتراع ، في حالات نادرة ، قد لا يتوافق مع الدائرة الانتخابية التي ينتمي إليها ، فقد طرحت الفرضية التالية: من خلال الاطلاع على عناوين PEC على موقع UMG ، يمكنك جمع المعلومات حول كل دائرة انتخابية.
لاحقًا ، وبمساعدة هذه الفرضية ، تمكنت من جمع المعلومات عن جميع الفئات المستهدفة تقريبًا. نظرًا لعدم تجانس تنسيق العنوان في قاعدة بيانات لجان الانتخابات ، فقط عناوين 10 من أصل 1100 دائرة انتخابية كان علي اختيارها يدويًا.
على الإنترنت ، يمكنك العثور على قاعدة بيانات محدثة بانتظام للجان الانتخابات في الاتحاد الروسي ، تحتوي على معلومات حول العناوين وحتى تكوين اللجان الانتخابية المستقلة. ولكن لمزيد من الأهمية والموثوقية للبيانات (وأيضًا نظرًا لحقيقة أنني لم أكن راضيًا عن تنسيق حقل معين) ، فقد قررت جمع قائمة العناوين بنفسي ، لأنه ، كما اتضح فيما بعد ، يتمتع موقع CEC على الويب بجميع الوظائف اللازمة لذلك.
خدمة ويب CEC جديدة. طرق API
GAS "Vybory" هو نظام آلي ، تم تطويره في عام 1995 ، يهدف إلى التحضير وإجراء الانتخابات والاستفتاءات في الاتحاد الروسي.
إذا كنت مهتمًا في أي وقت مضى بمسار حملة انتخابية ، فمن المحتمل أنك صادفت هذا الموقع ، الذي ينشر المعلومات الأساسية من نظام GAS "Vybory" ، بما في ذلك عد الأصوات ، حتى قبل الموافقة على نتائج الانتخابات:
وإذا كان الأمر سابقًا ، لاستخراج نتائج الانتخابات ، يقوم مراقبو البيانات استخدم هذا الموقع ، خلال أيام التصويت على تعديلات الدستور ، ظهرت كلمة التحقق فجأة على الموقع . كلمة التحقق ثابتة للغاية ، تظهر عندما تذهب إلى كل صفحة من صفحات الموقع:

نظرًا لأنك تستطيع أنت بنفسك التقييم بصريًا ، فإن اختبار captcha بسيط للغاية ، وبالتأكيد وجد شخصًا طرقًا لتجاوزه. بدلاً من التعلم الآلي ، انتقلت إلى قسم جديد على موقع CEC ، والذي يعرفه القليل من الناس حتى الآن: الخدمات الرقمية
ظهر هذا القسم فقط أثناء التصويت على التعديلات ويحتوي على العديد من خدمات الويب التي ، عبر HTTP طلب التواصل مع واجهة برمجة التطبيقات الداخلية لتلقي البيانات من نظام "فيبوري" GAS. لقد انتبه مستخدم Habr بالفعل لهذه الوظيفة. دعونا ننظر في الأمر بمزيد من التفصيل.
فيما يلي وصف للطلبات الرئيسية لواجهة برمجة التطبيقات الجديدة التي تم استخدامها في هذا المشروع:
تحتوي كل بنية بيانات في النظام على مفتاح VRN- معرّف فريد للكائن ، سواء كان موقعًا أو حملة أو منطقة أو مرشحًا .
معلومات PEC
http://cikrf.ru/iservices/voter-services/committee/subjcode/SUBJECT_CODE/num/COMMITTEE_NUM
- SUBJECT_CODE - رمز موضوع RF
- COMMITTEE_NUM - رقم PEC
طلب مثال:
http://cikrf.ru/iservices/voter-services/committee/subjcode/ 01 / num / 2
نتيجة الاستعلام
{
"vrn":"4014001117979",
"name":" №2",
"subjCode":"01",
"numKsa":"01T001",
"vid":"5",
"address":{
"address":"385200, , , , .., 16",
"descr":" №1",
"phone":"8-87772-9-23-72",
"lat":"44.882893",
"lon":"39.187187"
},
"votingAddress":{
"address":"385200, , , , .., 16",
"descr":" №1",
"phone":"8-87772-9-23-72",
"lat":"44.882893",
"lon":"39.187187"
}
}
معلومات عن الحملات الانتخابية في الموقع
http://cikrf.ru/iservices/voter-services/vibory/committee/COMMITTEE_VRN
- COMMITTEE_VRN - معرف PEC
مثال للطلب:
http://cikrf.ru/iservices/voter-services/vibory/committee/ 4544028162533
نتيجة الاستعلام
[
{
"vrn":"100100163596966",
"date":"2020-07-01",
"name":" ",
"subjCode":"0",
"pronetvd":null,
"vidvibref":"0"
},
{
"vrn":"25420001876696",
"date":"2020-09-13",
"name":" ",
"subjCode":"54",
"pronetvd":"0",
"vidvibref":"2"
},
{
"vrn":"4544220183446",
"date":"2020-09-13",
"name":" ",
"subjCode":"54",
"pronetvd":null,
"vidvibref":"2"
}
]
قائمة الدوائر الانتخابية
http://cikrf.ru/iservices/sgo-visual-rest/vibory/CAMPAIGN_VRN/tvd
- CAMPAIGN_VRN - معرف الحملة
مثال للطلب:
http://cikrf.ru/iservices/sgo-visual-rest/vibory/ 457422069597 / tvd
نتيجة الاستعلام
{
"_embedded":{
"tvdDtoList":[
{
"vrn":457422069601,
"namtvd":" ",
"namik":" ",
"numtvd":"0",
"vidtvd":"ROOT",
"_links":{
"results":{
"href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/457422069597/results/457422069601/proportion"
}
}
},
{
"vrn":457422069602,
"namik":" № 1",
"numtvd":"1",
"vidtvd":"OIK",
"_links":{
"results":{
"href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/457422069597/results/457422069602/major"
}
}
},
...
]
},
"_links":{
"self":{
"href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/457422069597/tvd"
}
}
}
NUMTVD هو رقم المقاطعة. عادة ما يكون الرقم صفر مسؤولاً عن نتائج دائرة واحدة. على سبيل المثال ، إذا أجريت الانتخابات في ظل نظام مختلط ، فإن "الدائرة الصفرية" هي المسؤولة عن التصويت في ظل نظام نسبي. بقية الدوائر هي عضو واحد أو متعدد الأعضاء.
كما ترى ، تحتوي بنية البيانات أيضًا على ارتباط يمكن استخدامه لمعرفة نتائج الانتخابات. يتم إنشاء الرابط حتى قبل نشر نتائج التصويت.
قائمة المرشحين المشاركين في الحملة الانتخابية
http://cikrf.ru/iservices/sgo-visual-rest/vibory/CAMPAIGN_VRN/candidates/?page=PAGE_NUM&numokr=NUMTVD
- CAMPAIGN_VRN - معرف الحملة
- PAGE_NUM - رقم صفحة القائمة
- NUMTVD - رقم المقاطعة (اختياري)
مثال للطلب:
http://cikrf.ru/iservices/sgo-visual-rest/vibory/ 4674220125616 / المرشحين /؟ الصفحة = 1 & numokr = 11
نتيجة الاستعلام
{
"_embedded":{
"candidateDtoList":[
...
{
"index":50,
"vrn":4674020270868,
"fio":" ",
"datroj":"23.04.1964 00:00:00",
"vidvig":"",
"registr":"",
"vrnio":4674220132098,
"namio":" \" \" ",
"numokr":11,
"tekstat2":"1",
"_links":{
"self":{
"href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates/4674020270868"
}
}
},
{
"index":56,
"vrn":4674020269642,
"fio":" ",
"datroj":"15.02.1986 00:00:00",
"vidvig":"",
"registr":" ",
"namio":"",
"numokr":11,
"tekstat2":"1",
"_links":{
"self":{
"href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates/4674020269642"
}
}
},
{
"index":105,
"vrn":4674020271181,
"fio":" ",
"datroj":"15.07.1994 00:00:00",
"vidvig":"",
"registr":"",
"vrnio":4674220134054,
"namio":" \" \"",
"numokr":11,
"tekstat2":"1",
"_links":{
"self":{
"href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates/4674020271181"
}
}
},
...
]
},
"_links":{
"self":{
"href":"http://cikrf.ru/iservices/sgo-visual-rest/vibory/4674220125616/candidates?page=1&numokr=11"
}
},
"page":{
"size":20,
"totalElements":9,
"totalPages":1,
"number":1
}
}
يحتوي هيكل الصفحة على العدد الإجمالي للصفحات ، ويمكن استخدامه لتحديد متى تصل إلى الصفحة الأخيرة (أو من خلال قائمة فارغة يتم إرجاعها من الخادم).
يحتوي API على طرق أخرى ، بشكل أساسي لمعرفة المزيد من المعلومات حول الانتخابات / المرشحين. إذا لزم الأمر ، يمكنك بسهولة تتبع الطلبات المطلوبة. الآن ، يمكنك البدء في تحميل البيانات.
تنزيل البيانات من موقع CEC
قبل الشروع في تنزيل البيانات الضرورية ، كان من الضروري تجميع قائمة بالحملات الانتخابية التي سنستخدمها في المشروع. الحقيقة أن "التصويت الذكي" لم يحدث في كل مكان ، بل في الانتخابات:
— ,
— ,
— ( 200 )
( 4 ).
//
قررت تجاهل الانتخابات الفرعية لمجلس الدوما ، بسبب عدم أهمية هذه المعطيات. ساعد مقال ويكيبيديا في يوم الانتخابات في تجميع قائمة انتخابات المجالس المحلية ، لأنها أدرجت للتو الانتخابات في المدن الكبيرة.
بالانتقال إلى صديق (ساعدني في تنفيذ هذا المشروع من خلال القيام بالعمل اليدوي المطلوب) ، طلبت منه تجميع قائمة عناوين URL للحملات الانتخابية المعنية ، مع أخذها من الصفحة الرئيسية لموقع CEC الكلاسيكي . الحقيقة هي أن عنوان URL يحتوي على معرّفات المنطقة والحملة التي سنحتاجها لمزيد من التحليل.
vybory.izbirkom.ru/region/izbirkom?action=show&vrn=21120001136916&
region=11&prver=1&pronetvd=1
ونتيجة لذلك ، تكونت القائمة من 43 حملة انتخابية. إجمالاً ، أقيمت أكثر من 9000 حملة انتخابية منفصلة في الهيئات على مختلف المستويات في يوم الانتخابات الواحدة.
الآن ، مع وجود قائمة الخيارات وطرق واجهة برمجة التطبيقات المدرجة سابقًا في متناول اليد ، كان من السهل تنزيل البيانات. بعد كتابة برنامج نصي بلغة Python ، وتقديم طلبات منتظمة باستخدام وحدة الطلبات ، قمت بحفظ البيانات حول المرشحين ومحطات الاقتراع بتنسيق JSON الأصلي.
الشيء الرئيسي الذي يجب مراعاته عند تنزيل معلومات حول محطات الاقتراع: لا يكفي استعراض جميع الأرقام الممكنة بدءًا من 1 حتى يقوم الخادم بإرجاع قيمة فارغة. الحقيقة هي أنه يمكن مقاطعة ترقيم PECs في المنطقة والذهاب ، على سبيل المثال ، بالشكل التالي:
... # 1001 - # 1016 ، # 1101 - # 1136 ، 1138 ...
أو:
# 0 - # 700، # 900 - # 1002، 1004 ...
لتحديد الحد الأقصى لرقم PEC في المنطقة وعدم تقديم طلبات غير ضرورية ، جمعت البيانات على النحو التالي: حاولت تحميل البيانات على أول 1000 رقم ، ثم تحقق مما إذا كنت + 1 ، i + 5 ، i + 100 ، i + 500 ، i + 1000 رقم يتوافق مع أي PEC (في هذه الحالة ، استمرار التنزيل).
أوصي أيضًا بالاحتفاظ برقم PEC الذي قمت بتنزيل البيانات حول المنطقة من خلاله. الحقيقة هي أن البيانات التي تم إرجاعها لا تحتوي على رقم PEC ، ولكن فقط الاسم الموجود في النموذج: "دائرة الانتخابات رقم 100" . أدت عملية الحصول على رقم PEC الأصلي ، والذي كان علي التعامل معه لاحقًا ، إلى أخطاء وإحباط على المدى القصير. كما اتضح ، فإن الترقيم في اسم PECs في بعض المناطق له تنسيق مختلف.
على سبيل المثال ، في Udmurtia ، كان لاسم PEC الترقيم التالي: "№1 / 01 ، №1 / 02 ، №1 / 03" ، في منطقة ليبيتسك: "№01-01 ، №01-02 ، 01-03" . في منطقة أورينبورغ ، صادفت غريبًا حقيقيًا: كانت المنطقة الوحيدة التي تم فيها تسمية عدد من اللجان الانتخابية على اسم شخص ما. على سبيل المثال ، "سميت لجنة الانتخابات رقم 1696 باسم" Pustovitov Brothers "
تحميل البيانات من موقع "التصويت الذكي"
الآن ، لكل عنوان PEC تم جمعه ، سنقوم بتنزيل بيانات التصويت من موقع UMG. قبل ذلك ، يجدر النظر في العديد من الميزات (التي تعلمتها في هذه العملية):
أولاً ، من الضروري مراعاة أن العناوين الموجودة في قاعدة بيانات CEC لها تنسيق مختلف ، أحيانًا حتى في مناطق معينة من المناطق. اضطررت إلى إزالة الاختصارات "d." و "G." و "st." ، نظرًا لأن موقع "Smart Voting" لم يكن قادرًا على الإطلاق على التعامل مع البحث عن عناوين لمثل هذه الاستفسارات. أوصي أيضًا بإزالة الرمز البريدي من العنوان ، بالإضافة إلى البادئة التي تصادف أحيانًا "الاتحاد الروسي".
ثانيًا ، يتمتع موقع UMG الإلكتروني بحماية قوية ضد هجمات DDoS ، وحتى إذا قدمت مئات الطلبات بفاصل زمني قدره 0.3 ثانية ، فسيتم حظر عنوان IP الخاص بك. سيكون من الممكن استخدام مجموعة من الوكلاء المدفوعين ، لكنني شخصيًا استخدمت للتو وكلاء مجانيين وطلبات بديلة من IP الخاص بي ومن طرف ثالث. لكي لا يتم حظره ، كان هناك فاصل زمني يبلغ حوالي 0.7 ثانية بين الطلبات. نتيجة لذلك ، استغرق تنزيل جميع البيانات يومًا تقريبًا.
باستخدام الاستعلامات من الفصل الأول ، تكون الخوارزمية كما يلي:
- تنسيق عنوان PEC
- نتقدم بطلب للحصول على قائمة بالعناوين المناسبة
- نحصل على قائمة تحتوي على معرّفات صفحات الموقع
- نتحقق مما إذا كنا قد قمنا بالفعل بتنزيل البيانات حول الموقع بواسطة هذا المعرف
- قم بتحميل صفحة HTML الخاصة بالموقع لهذا المعرف
- نقوم باستخراج العنصر "__NEXT_DATA__" وحفظ البيانات بتنسيق JSON
تم تحليل الصفحة باستخدام مكتبة beautifulsoup4 .
هذه العملية ليست خالية من العيوب: عادةً لا يجد البرنامج النصي عشرات مراكز الاقتراع في المنطقة على موقع الويب ، أو على عنوان PEC واحد تجد معلومات حول PEC مختلفة تمامًا.
لا يهم ، لأنه بالنسبة لكل منطقة ، نحتاج فقط إلى العثور على صفحة مقابلة واحدة على الأقل على الموقع.
للتحقق من صحة اكتمال البيانات ، نكتب نصًا بسيطًا يتحقق مما إذا كانت مجموعة البيانات التي تم تنزيلها من موقع UMG تحتوي على معلومات حول كل دائرة انتخابية. إذا كان هناك شيء مفقود ، فسنقوم بتجديد مجموعة البيانات يدويًا. مرة أخرى ، كان هناك أقل من 10 مثل هذه الحالات الاستثنائية من أصل 1100 مقاطعة.
الجمع بين البيانات من مواقع UMG و CEC
في هذه المرحلة ، نقوم بجمع بنية بيانات ملائمة ، مع معلومات حول كل مرشح حسب المنطقة: معرف المرشح ، الاسم الكامل ، الحزب ، العلامة مع معلومات حول ما إذا كان مدعومًا من UMG.
مثال على مجموعة بيانات مرشح تم جمعها
{
"33": [
{
"name": " ",
"vrn": 4444032121758,
"birthdate": "05.05.1958 00:00:00",
"party": "",
"smart_vote": 0
},
{
"name": " ",
"vrn": 4444032122449,
"birthdate": "16.11.1977 00:00:00",
"party": "",
"smart_vote": 0
},
{
"name": " ",
"vrn": 4444032122782,
"birthdate": "27.02.1996 00:00:00",
"party": "",
"smart_vote": 0
},
{
"name": " ",
"vrn": 4444032123815,
"birthdate": "20.11.1991 00:00:00",
"party": "",
"smart_vote": 1
},
{
"name": " ",
"vrn": 4444032124060,
"birthdate": "21.07.1996 00:00:00",
"party": "",
"smart_vote": 0
},
{
"name": " ",
"vrn": 4444032123597,
"birthdate": "21.05.1974 00:00:00",
"party": "",
"smart_vote": 0
}
],
...
}
الخوارزمية واضحة إلى حد ما:
- استنادًا إلى مصفوفة البيانات من موقع UMG على الويب ، نقوم بإنشاء قائمة بالمرشحين المدعومين لكل منطقة
- باستخدام مصفوفة البيانات من موقع CEC ، نقوم بإنشاء قائمة تمت تصفيتها بالمرشحين المقبولين لكل دائرة انتخابية
- في كل منطقة ، بالاسم الكامل ، نحسب المراسلة المرشح- UMG- المرشح- CEC
بالطبع ، يجب أن تأخذ مثل هذه الخوارزمية البسيطة في الاعتبار العديد من مواقف المشكلات المحتملة.
أولاً ، هناك احتمال أن يكون هناك مرشحون في دائرة انتخابية بأسماء متطابقة تمامًا. لحسن الحظ ، من بين 5000 مرشح ، كان مثل هذا الموقف في حالة واحدة فقط ، ولم يتم دعم أي من المرشحين من قبل UMG.
ثانيًا ، يجب الأخذ في الاعتبار احتمال وجود أخطاء في قاعدة بيانات موقع CEC. الخطأ الأكثر شيوعًا: فواصل الأسطر والمسافات الإضافية في الاسم الكامل. أيضًا ، عند جمع البيانات حول نتائج التصويت ، كان هناك موقف تم فيه استبدال الحرف "" في اللقب بالحرف "e".
ثالثًا ، يجب أن تؤخذ أهمية البيانات في الاعتبار. تم تغيير البيانات الموجودة على موقع الويب الخاص بـ CEC و UMG وتحديثها حتى يوم السبت: تمت إزالة / استعادة بعض المرشحين ، في بعض الدوائر الانتخابية تم تغيير دعم UMG.
للتحقق من صحة قوائم UMG ، تمت كتابة نص بسيط يقدم طلبًا واحدًا لكل منطقة (بعد كل شيء ، تتيح لنا مجموعة البيانات التي جمعناها الآن تحديد الصفحة المخصصة لكل منطقة بشكل فريد) والتحقق مما إذا كانت الأسماء تتطابق مع تلك التي تلقيناها سابقًا.
كانت مهمة مثيرة للاهتمام تحديد الأطراف من خلال أسماء فروعهم. يمكن تخطي هذه النقطة ، لكنني قررت أن أفعل ذلك لتوحيد المعلومات. المشكلة هي أن المرشحين من حزب واحد قد يكون لديهم أسماء مختلفة في قاعدة بيانات لجنة الانتخابات المركزية. على سبيل المثال ، في حالة KPRF ، كان هناك أكثر من 40 خيارًا:
() " "
- ""
" "
...
يتحول الموقف إلى مشكلة تحليل مثيرة للاهتمام ، عندما يكون هناك 25 دفعة ولكل منها تقريبًا تهجئة مختلفة لكل منطقة. لحسن الحظ ، بمساعدة صديقي ، الذي ساعدني في كل الأعمال اليدوية ، قمنا بإعداد قائمة بالكلمات الرئيسية التي يتم من خلالها تحديد حزب المرشح بشكل فريد.
تحميل نتائج الانتخابات من موقع لجنة الانتخابات المركزية
كانت مجموعة البيانات التي تم جمعها كافية لتحقيق الهدف الأولي للمشروع - قمنا بتجميع قوائم المرشحين UMG-2020 لكل دائرة انتخابية. ولكن إذا كانت هناك فرصة فنية للحصول على نتائج الانتخابات فلماذا لا تستغلها؟
نتائج انتخابات المقاطعات
http://cikrf.ru/iservices/sgo-visual-rest/vibory/CAMPAIGN_VRN/results/DISTRICT_VRN/major
- CAMPAIGN_VRN - معرف الحملة
- DISTRICT_VRN - معرف المنطقة
مثال للطلب:
http://cikrf.ru/iservices/sgo-visual-rest/vibory/ 457422069597 / results / 457422069602 / major
نتيجة الاستعلام
{
"report":{
"tvd":"",
"date_sign":"none",
"vrnvibref":"457422069597",
"line":[
{
"txt":" ",
"kolza":"8488",
"index":"1"
},
{
"txt":" , ",
"kolza":"6700",
"index":"2"
},
...
{
"txt":" ",
"kolza":"65",
"index":"9"
},
{
"txt":" ",
"kolza":"1948",
"index":"10"
},
...
{
"delimetr":"1"
},
{
"txt":" ",
"numsved":"1",
"kolza":"112",
"index":"11",
"namio":" ",
"perza":"5.56",
"numsvreestr":"4574030258379"
},
{
"txt":" ",
"numsved":"2",
"kolza":"186",
"index":"12",
"namio":" ",
"perza":"9.24",
"numsvreestr":"4574030258723"
},
{
"txt":" ",
"numsved":"3",
"kolza":"54",
"index":"13",
"namio":"",
"perza":"2.68",
"numsvreestr":"4574030258555"
},
...
],
"data_gol":"13.09.2020 00:00:00",
"is_uik":"0",
"type":"423",
"version":"0",
"sgo_version":"5.6.0",
"isplann":"0",
"podpisano":"1",
"versions":{
"ver":{
"current":"true",
"content":"0"
}
},
"vibory":" ",
"repforms":"1",
"generation_time":"14.09.2020 07:59:21",
"nazv":" () ",
"datepodp":"14.09.2020 05:44:00"
}
}
كما ترى ، يتم إرجاع النتائج في شكل بروتوكول اللجنة الإقليمية. تختلف كل منطقة في تنسيق البروتوكول وعدد الأسطر التمهيدية فيه ، لذلك يجب إجراء التحقق الدقيق من صحة البيانات التي استخرجتها.
عندما بدأت GAS "Vybory" في نشر النتائج الأولية ، أصبت ببعض الإحباط. اتضح أنه من خلال واجهة برمجة التطبيقات (API) ، يمكنك الحصول على بيانات فقط عن تلك النتائج التي تمت الموافقة عليها رسميًا. لا يزال من الممكن الاطلاع على النتائج الأولية على الموقع القديم للجنة الانتخابات ، ولكن ليس من خلال خدمات الويب الجديدة.
بعد ذلك بيوم ، عُرِفت نتائج 50٪ ، وبحلول نهاية الأسبوع تم تلخيص نتائج جميع الانتخابات تقريبًا ، ولا تزال بعض المناطق ترفض الموافقة على النتائج. حتى كتابة هذه السطور ، مرت سبعة أيام ، ولم تتم الموافقة بعد على نتائج الانتخابات في تامبوف. بالإضافة إلى ذلك ، هناك إعادة فرز في بعض الدوائر الانتخابية ، وهذا هو سبب عدم توفر هذه النتائج أيضًا من خلال واجهة برمجة التطبيقات.
الخلاصة: أساليب API ليست مناسبة حاليًا لتلقي نتائج التصويت على الفور. سيتعين عليك إما الانتظار أكثر من أسبوع حتى تتم الموافقة على النتائج ، أو سيتعين عليك تحليل الموقع القديم للجنة الانتخابات ، وإيجاد طريقة لتجاوز اختبار captcha.
لقد سئمت انتظار الموافقة على الانتخابات في حوالي 30 دائرة انتخابية من أصل 1100 دائرة انتخابية ، لذلك كتبت نصًا باستخدام مكتبة السيلينيوم لتنزيل البيانات من الموقع الكلاسيكي للجنة الانتخابات وطلبت مني حل اختبار captcha يدويًا لكل طلب. مع هذا العدد الصغير من الطلبات ، لن يستغرق الأمر وقتًا طويلاً لحل اختبار captcha يدويًا.
نتيجة لذلك ، قمت بجمع البيانات الخاصة بنتائج التصويت في الهيكل التالي :
مثال على نتائج تصويت المقاطعة
{
...
"33": {
"candidate_total": {
"4444032121758": 880,
"4444032122449": 236,
"4444032122782": 143,
"4444032123597": 152,
"4444032123815": 149,
"4444032124060": 72
},
"is_final": 1,
"non_valid_votes": 132,
"registered_voters": 6928,
"valid_votes": 1632
},
...
}
لكل دائرة انتخابية ، قمت بحفظ العدد الإجمالي للناخبين في القوائم (لحساب الإقبال) ، وعدد البطاقات الصحيحة وغير الصالحة. يحتوي الهيكل على قاموس: معرّف المرشح -> عدد الأصوات التي كتبها.
نشر نتائج UMG-2020
أولاً ، قمت بنشر البيانات التي تم جمعها بتنسيق JSON على GitHub . سيتم تحديث البيانات حتى يتم التحقق من صحة النتائج في جميع المناطق.
ثانيًا ، للفت الانتباه إلى المشروع ، قررت إنشاء جدول بيانات Google ، والذي يحتوي على جميع البيانات التي تم جمعها في نموذج مناسب للتحليل المرئي.
لن أخوض في التفاصيل ، ولن تظهر أي صعوبات (باستثناء دراسة واجهة برمجة تطبيقات جداول بيانات Google). أوصي بهذه المقالة ، التي توضح تفاصيل التفاعل مع Google Sheets API في Python.
ونتيجة لذلك حصلنا على الجدول التالي الذي يحتوي على:
- قائمة الانتخابات المشاركة
- قائمة الأطراف المعنية
- قائمة المرشحين حسب المنطقة
- نتائج الانتخابات حسب المنطقة
- بيانات موجزة جافة
خاتمة
نشأت فكرة هذا المشروع المصغر قبل 3 أيام من يوم التصويت ، وأنا شخصياً مسرور بالطريقة التي تمكنت من خلالها من دراسة وتنفيذ كل شيء في أقصر وقت ممكن (على الرغم من أن الكود اتضح أنه فظيع).
لن أستخلص أي استنتاجات حول نتائج استراتيجية التصويت الذكي ، لقد قدمت للتو أدوات لمحبي الإحصاءات الانتخابية. أنا متأكد من أنه سيكون هناك البعض بينكم وقريبًا سنرى دراسات رائعة ، برسوم بيانية ومخططات شيقة.