
خط أنابيب آلي يحلّ نطاقات البلديات السويسرية، ويستخرج عناوين البريد الإلكتروني من المواقع الإلكترونية، ويصنّف مزوّدي البريد الإلكتروني عبر فحوصات MX وSPF وDKIM وDMARC وSMTP لرسم خرائط التبعيات الرقمية.
[!IMPORTANT] لدى MXmap خليفة. تطوّر هذا المشروع ليصبح جهداً بحثياً لفريق يغطي جميع البلديات في ألمانيا والنمسا وسويسرا: secassure2026.mxmap-project.org (المصدر). تبقى خريطة سويسرا على mxmap.ch متاحة عبر الإنترنت، لكن بياناتها مجمّدة اعتباراً من أبريل 2026 ولن يتم تحديثها.
خرائط تفاعلية تُظهر أين تستضيف البلديات السويسرية بريدها الإلكتروني، ومدى ارتباط نظام أسماء النطاقات (DNS) لديها بشركات الحوسبة السحابية العملاقة في الولايات المتحدة (Microsoft وGoogle وAWS) مقارنة بالموفرين السويسريين والحلول ذاتية الاستضافة.
يتكون خط معالجة البيانات من مرحلتين:
حلّ النطاقات — يجلب جميع البلديات السويسرية البالغ عددها ~2100 من Wikidata وواجهة برمجة تطبيقات BFS (المكتب الفيدرالي السويسري للإحصاء)، ويطبّق تجاوزات يدوية، ويستخرج عناوين البريد الإلكتروني من مواقع البلديات، ويخمّن النطاقات من أسماء البلديات، ويتحقق من المرشحين عبر استعلامات MX. يقيّم توافق المصادر لاختيار أفضل نطاق. يُخرج municipality_domains.json.
تصنيف الموفرين — لكل نطاق تم حله، يبحث عن جميع مضيفي MX ويجري مطابقة أنماط عليها، ثم يشغّل 10 فحوصات متزامنة (SPF، DKIM، DMARC، Autodiscover، سلسلة CNAME، ترحيب SMTP، Tenant، ASN، التحقق من TXT، IP الخاص بـ SPF). يجمع الأدلة الموزونة ويحسب درجات الثقة (0–100). يُخرج data.json (كامل) وdata.min.json (مصغّر للواجهة الأمامية).
flowchart TD
subgraph resolve ["1 · Resolve domains"]
bfs[/"BFS Statistics API"/] --> merge["Merge ~2100 municipalities"]
wikidata[/"Wikidata SPARQL"/] --> merge
overrides[/"overrides.json"/] --> per_muni
merge --> per_muni["Per municipality"]
per_muni --> scrape["Scrape website for<br/>email addresses"]
per_muni --> guess["Guess domains<br/>from name"]
scrape --> mx_verify["MX lookup to<br/>verify domains"]
guess --> mx_verify
mx_verify --> score["Score source<br/>agreement"]
end
score --> domains[("municipality_domains.json")]
domains --> classify_in
subgraph classify ["2 · Classify providers"]
classify_in["Per unique domain"] --> mx_lookup["MX lookup<br/>(all hosts)"]
mx_lookup --> mx_match["Pattern-match MX<br/>+ detect gateway"]
mx_match --> concurrent["10 concurrent probes<br/>SPF · DKIM · DMARC<br/>Autodiscover · CNAME chain<br/>SMTP · Tenant · ASN<br/>TXT verification · SPF IP"]
concurrent --> aggregate["Aggregate weighted<br/>evidence"]
aggregate --> vote["Primary vote<br/>+ confidence scoring"]
end
vote --> data[("data.json + data.min.json")]
data --> frontend["Leaflet map<br/>mxmap.ch"]
انظر classifier.py للحصول على تفاصيل التنفيذ الكاملة، لكن باختصار، نستخدم نظام أدلة موزونة يساهم فيه كل فحص بإشارات متفاوتة القوة نحو تصنيفات مختلفة للموفرين.
uv sync
# Stage 1: resolve municipality domains
uv run resolve-domains
# Stage 2: classify email providers
uv run classify-providers
# Serve the map locally
python -m http.server
uv sync --group dev
# Run tests (90% coverage threshold enforced)
uv run pytest --cov --cov-report=term-missing
# Lint & format
uv run ruff check src tests
uv run ruff format src tests
فوركات خاصة بدول محددة، مرتبة أبجدياً حسب رمز الدولة:
الفوركات الجديدة لدول أخرى مرحّب بها — فكّر في البدء من خط معالجة الخليفة، الذي يضيف مرحلة فحص DANE/DNSSEC/SPF/DMARC.
مشاريع ذات صلة:
انظر أيضاً فوركات هذا المستودع.
إذا رصدت تصنيفاً خاطئاً، فيرجى فتح issue مع ذكر رقم BFS والموفر الصحيح. بالنسبة للبلديات التي يفشل فيها الاكتشاف الآلي، يمكن إضافة التصحيحات إلى overrides.json.