كيفية استخراج بيانات Redfin باستخدام Python (من دون التعرض للحظر)

آخر تحديث في August 7, 2026
كيفية استخراج بيانات Redfin باستخدام Python (من دون التعرض للحظر)

يقوم Redfin بتحديث 70% من إعلانات MLS الجديدة في الولايات المتحدة خلال خمس دقائق من ظهورها. هذا المستوى من حداثة البيانات هو حلم كل من يبني خط أنابيب لبيانات العقارات، وهو تحديدًا السبب الذي يجعل الكثير من أدوات التجريف تستهدف Redfin ثم تُحجب خلال دقائق.

قضيت سنوات في العمل على أدوات استخراج البيانات في Thunderbit، ويمكنني أن أخبرك: الفجوة بين «تجريف Redfin» و«تجريف Redfin دون أن تُحجب» هي بالضبط النقطة التي تنهار عندها معظم الشروحات. فهي تعرض عليك كود BeautifulSoup، وتتخطى الجزء الذي تلتهم فيه Cloudflare طلباتك حيّة، وتتركك تحدّق في صفحة 403 متسائلًا عمّا حدث. هذا الدليل مختلف. سأشرح لك ثلاث مقاربات حقيقية: تحليل HTML، وواجهة Redfin المخفية، والمسار بلا أكواد عبر Thunderbit، وسأخصص وقتًا جادًا لدفاعات مكافحة الروبوتات التي تهمّ فعلًا. وبنهاية المقال، ستعرف بالضبط أي طريقة تناسب مستوى مهارتك، وحجم عملك، ومدى تحمّلك لصداع الصيانة.

جرّب Thunderbit لاستخراج بيانات Redfin

ما هو Redfin، ولماذا تهمّ بياناته؟

Redfin هي وساطة عقارية مدعومة بالتقنية، يعمل بها وكلاء برواتب ثابتة يسحبون الإعلانات مباشرةً من تغذيات MLS. وتغطي أكثر من 100 منطقة حضرية في الولايات المتحدة وكندا عبر 42 ولاية وتخدم نحو 50 مليون زائر شهريًا. وعلى عكس البوابات التي تكتفي بالتجميع، بيانات Redfin موثّقة من الوكلاء، ويغطي نموذج التقييم الآلي الخاص بها Redfin Estimate أكثر من 95 مليون عقار بمتوسط خطأ لا يتجاوز 1.96% للمنازل المعروضة حاليًا في السوق.

redfin_stats_f3c7fb5cbd.png

هذا المزيج — حداثة بسرعة MLS، وجودة موثّقة من الوسطاء، ونموذج تقييم دقيق — هو ما يجعل المستثمرين العقاريين والوكلاء وشركات البروبتك الناشئة ومحللي البيانات جميعًا يرغبون في وصول برمجي إلى بيانات Redfin. وPython هي الخيار الطبيعي لهذه المهمة: منظومة التجريف فيها (requests وBeautifulSoup وSelenium وPlaywright) ناضجة، ودعم المجتمع هائل، وهي تتكامل مباشرةً مع pandas وJupyter للتحليل.

لماذا تجرّف Redfin باستخدام Python؟

حالات الاستخدام متنوعة بتنوّع الأشخاص الذين يحتاجون البيانات. إليك كيف تستخدم الفئات المختلفة بيانات Redfin المجرَّفة عادةً:

الفئةالهدف الأساسي من التجريفمثال على حالة الاستخدام
الوكلاء العقاريونتوليد العملاء المحتملين، استخبارات السوقالإعلانات الجديدة والمنتهية في منطقة الخدمة؛ دليل الوكلاء للمقارنة التنافسية
المستثمرون العقاريونتدفق الصفقات، تحليل معدل الرسملةفلاتر العائد الإيجاري، رصد العقارات المقوَّمة بأقل من قيمتها، تنبيهات يومية بالإعلانات الجديدة
شركات البروبتك الناشئةخطوط أنابيب بيانات المنتجبيانات تدريب نماذج التقييم، لوحات معلومات السوق، محركات الاستحواذ لدى iBuyer
محللو البياناتأبحاث السوق، ذكاء الأعمالاتجاهات متوسط السعر على مستوى الرمز البريدي، السلاسل الزمنية لأيام العرض في السوق، نسب سعر البيع إلى سعر الطلب
تجار الجملة / مُعيدو التأهيلتتبّع العقارات المتعثّرةرصد تخفيضات الأسعار، حالات حبس الرهن، المقارنات خارج السوق

والاتجاه العام يدعم ذلك: أكثر من 72% من شركات العقارات تستخدم اليوم التحليلات التنبؤية لتحديد الفرص وإدارة المخاطر. ومن المتوقع أن يصل سوق البروبتك إلى 47 مليار دولار في 2025 بمعدل نمو سنوي مركّب قدره 16.4%. لم تعد بيانات العقارات المنظّمة ميزة إضافية، بل صارت شرطًا أساسيًا للمشاركة.

كل حقل بيانات يمكنك تجريفه من Redfin (مرجع كامل)

قبل أن تكتب سطرًا واحدًا من الكود، عليك أن تعرف ما هو متاح فعليًا. لقد دققت في صفحات نتائج البحث في Redfin، وصفحات تفاصيل العقارات، وملفات الوكلاء، وقارنتها بمغلّفات Stingray API مفتوحة المصدر مثل مشروعَي reteps/redfin وRedfinPlus. ليصل الإجمالي إلى 117 حقلًا مميزًا موزّعة على أنواع الصفحات.

هذا الجدول مصمّم كي تحفظه في المفضلة. معرفة مخطط بياناتك قبل البرمجة توفّر عليك ساعات من التجربة والخطأ في البحث عن المحددات.

حقول صفحة نتائج البحث

هذه هي الحقول الخفيفة المتاحة على بطاقات الإعلانات، ويمكن استخراجها غالبًا دون الحاجة إلى تصيير JavaScript كاملًا:

الحقلنوع البياناتملاحظات
معرّف العقاررقمعدد صحيح داخلي لدى Redfin، يُستخرج من /home/{id} في الرابط
سعر الطلبرقم
العنوان الكاملنص
غرف النوم / الحمامات / المساحة بالقدم المربعرقمثلاث قيم متتالية
نوع العقاراختيار مفردمنزل مستقل، شقة، تاون هاوس، متعدد الوحدات
الحالةنصنشط، قيد الانتظار، مشروط
أيام العرض في السوقرقم
مؤشر تخفيض السعررقمالفرق عن السعر الأصلي
الصورة الرئيسيةرابط صورةصورة واحدة لكل بطاقة
شارة Hot Homeقيمة منطقية
تاريخ/وقت البيت المفتوحنص
نسبة الوساطة العقاريةنص

حقول صفحة تفاصيل العقار

صفحة التفاصيل هي حيث يكمن العمق الحقيقي. وكثير من هذه الحقول يتطلب تصيير JavaScript أو استخدام Stingray API:

الحقلنوع البياناتملاحظات
تقدير Redfin (معروض في السوق)رقمعبر /stingray/api/home/details/avm
تقدير Redfin (خارج السوق)رقمعبر /stingray/api/home/details/owner-estimate؛ متوسط خطأ 7.52%
سنة البناء / التجديدرقم
مساحة الأرضرقم
رسوم اتحاد الملاك (HOA)رقمشهريًا، إن وُجدت
الضريبة العقارية (سنويًا)رقم
القيمة الضريبية المقدَّرةرقم
جدول تاريخ البيعجدولالسعر، التاريخ، نوع الحدث
وصف العقارنصالفقرة التسويقية
روابط الصور (العارض)روابط صورأكثر من 20 لكل إعلان
اسم وكيل الإعلان وهاتفه وبريدهنص / هاتف / بريدالهاتف مخفي غالبًا
تقييمات المدارس (ابتدائي/متوسط/ثانوي)رقمإضافةً إلى اسم المنطقة التعليمية
درجات المشي / النقل / الدراجاترقم
درجات المخاطر المناخيةرقمالفيضان، الحريق، الحرارة، الرياح
منازل مشابهة نشطة / مباعة / قريبةروابطبيانات العارض
المواقف والمرآب والتدفئة والتبريدنصمجموعات المرافق

حقول ملف الوكيل

الحقلنوع البياناتملاحظات
اسم الوكيل وصورته ووساطته ونبذتهنص / صورة
الهاتف، نموذج التواصلهاتف / نصيظهر بالنقر
عدد الإعلانات النشطةرقم
المبيعات خلال آخر 12 شهرًا / إجمالي الحجمرقم
متوسط نسبة سعر الطلب إلى سعر البيعرقم
تقييم النجوم / عدد المراجعاترقم
سنوات الخبرة / رقم الترخيصنص / رقم

عندما تستخدم ميزة اقتراح الحقول بالذكاء الاصطناعي (AI Suggest Fields) في Thunderbit على صفحة Redfin، فإنها تكتشف معظم هذه الأعمدة تلقائيًا وتعيّن لها أنواع البيانات الصحيحة، دون الحاجة إلى ربط محددات CSS يدويًا. سنعود إلى ذلك لاحقًا.

تفكيك دفاعات Redfin ضد الروبوتات (وليس مجرد «استخدم بروكسي»)

هنا أريد أن أزرع راية، لأن معظم الشروحات تمرّ مرور الكرام على مشكلة الحجب وتقفز مباشرةً إلى «اشترِ بروكسيات من راعينا». هذا غير مفيد. إذا لم تفهم ماذا يفعل Redfin لكشف أدوات التجريف، فستستنزف رصيد البروكسيات وتظل محجوبًا. يقيّم ScrapeOps صعوبة مكافحة الروبوتات في Redfin بـ 7.5 من 10، بينما يصنّفها Scraperly بأنها متوسطة (3/5) — «أقل عدوانية من جدار الحماية المؤسسي لدى Zillow، وتعتمد على تحديد معدل مخصص وتحديات JavaScript».

يشغّل Redfin منظومة متعددة الطبقات: Cloudflare على الحافة (تحدي JS، وTurnstile، وبصمة TLS/JA3) إضافةً إلى محدِّد معدل خاص بـ Redfin على مستوى التطبيق. ولا يوجد توجيه Crawl-delay في ملف robots.txt لديهم لأن التطبيق يتم على مستوى جدار حماية تطبيقات الويب.

لماذا يفشل requests + BeautifulSoup البسيط مع Redfin

إذا أطلقت طلب requests.get() أساسيًا إلى صفحة عقار في Redfin بالترويسات الافتراضية، فإليك ما يحدث عادةً:

  • HTTP 403 — لم يُحلّ تحدي JS الخاص بـ Cloudflare، فتحصل على صفحة التحدي بدلًا من الإعلان.
  • صفحة تحدٍّ اعتراضية — يحتوي جسم HTML على أداة Turnstile من Cloudflare، لا على بيانات العقار.
  • HTTP 200 مع HTML جزئي — تحصل على هيكل يتضمّن كتلة JSON مضمّنة كبيرة تحت root.__reactServerState.InitialContext، لكن دون بطاقات بحث مصيَّرة مسبقًا، ودون تاريخ الأسعار، ودون تقييمات المدارس.

يستخدم Redfin إطار React SSR الخاص به (وليس Next.js)، ومفتاح الترطيب (hydration) خاص بـ Redfin: root.__reactServerState.InitialContext مع بيانات الإعلانات المتداخلة تحت ReactServerAgent.cache.dataCache. وهذا ليس __NEXT_DATA__ ولا window.__INITIAL_STATE__.

وما السبب الأكثر شيوعًا لأخطاء 403 الصامتة؟ غياب ترويسات Sec-Fetch-*. فـ Redfin/Cloudflare يتحققان صراحةً من Sec-Fetch-Site وSec-Fetch-Mode وSec-Fetch-Dest وSec-Fetch-User. وإذا غابت، تُوسم فورًا.

دليل المواجهة: التأخيرات والترويسات والبروكسيات والجلسات

إليك التفصيل الكامل، دفاعًا بدفاع، مع إجراءات مضادة محددة لكل منها:

دفاع Redfinماذا يفعلإشارة الكشفاستراتيجية المواجهة
تحدي JS من Cloudflareصفحة اعتراضية تصدر كوكي cf_clearance403 + جسم HTML من Cloudflarecurl_cffi مع impersonate="chrome120"؛ تسخين الجلسة عبر الصفحة الرئيسية؛ بروكسي سكني أمريكي
Cloudflare Turnstileكابتشا تفاعلية للجلسات عالية المخاطر403 + أداة Turnstileمتصفح بلا واجهة مع وضع التخفي + بروكسي سكني
خطأ Cloudflare 1020 (حظر ASN)يحجب عناوين IP/ASN الموسومة على مستوى WAFجسم 403 يحمل "Error 1020 Access Denied"التبديل إلى بروكسي سكني/جوّال؛ لا تستخدم ASN لمراكز البيانات أبدًا
بصمة TLS/JA3تكشف حِزم TLS غير الخاصة بالمتصفحات403 صامت حتى مع ترويسات مثاليةانتحال curl_cffi أو متصفح حقيقي
بصمة HTTP/2تفحص إعدادات HTTP/2 وترتيب HPACKحجب صامتcurl_cffi يتحدث HTTP/2 مثل Chrome
التحقق من الترويسات (UA، Sec-Fetch-*)مجموعة ترويسات متسقة مع المتصفح403 من أول طلبمجموعة ترويسات Chrome كاملة تشمل Sec-Fetch-Site/Mode/Dest/User وReferer واقعي
استمرارية الكوكيز/الجلسةتتبّع cf_clearance وRF_BROWSER_IDتحديات عند الدخول البارد إلى روابط عميقةجلسة دائمة؛ سخّن عبر الصفحة الرئيسية أولًا
تحديد المعدل على مستوى التطبيقمحدِّد طلبات لكل IP429تأخير 2–5 ثوانٍ مع تشويش عشوائي؛ تراجع أُسّي
سمعة عناوين مراكز البياناتتحجب ASN معروفة لمراكز البيانات1020/403 فوريبروكسيات سكنية أو جوّالة أمريكية فقط
كشف التزامنطلبات متوازية متعددة من IP واحدتصعيد مفاجئ إلى Turnstileما لا يزيد عن طلبين متزامنين لكل IP

عتبات عملية من اختبارات المجتمع:

  • الإيقاع الآمن: طلب واحد كل 2–3 ثوانٍ لكل IP
  • تجاوز 20–30 طلبًا في الدقيقة بشكل مستمر من عنوان IP واحد لمركز بيانات يُطلق تحديًا خلال دقائق
  • تُرفع حدود المعدل المرنة خلال 5–15 دقيقة إذا توقفت حركة الطلبات
  • قد يستمر حظر عناوين مراكز البيانات (AWS، GCP، Azure، OVH) من ساعات إلى أيام

مكتبة requests القياسية في Python (urllib3 + OpenSSL) تنتج بصمة JA3 لا تطابق أي متصفح، وتُحجب صامتة حتى مع ترويسات مثالية. والحل المعتمد في المجال هو curl_cffi مع impersonate="chrome120"، الذي يتحدث TLS + HTTP/2 بدقة مطابقة لـ Chrome.

ثلاث طرق لتجريف Redfin باستخدام Python (وأيها تختار)

redfin_methods_dc0828acd4.png

لم أجد شرحًا منافسًا واحدًا يقارن المقاربات الثلاث جنبًا إلى جنب. إليك مصفوفة القرار:

المعيارتحليل HTML (BS4 + Selenium)واجهة Stingray المخفيةThunderbit (بلا أكواد)
صعوبة الإعدادمتوسطة (بيئة Python + مشغّل المتصفح)مرتفعة (هندسة عكسية لنقاط النهاية)منخفضة (تثبيت إضافة Chrome)
خطر مكافحة الروبوتاتمرتفع (طلبات DOM هي الأكثر وضوحًا)متوسط (الطلبات الشبيهة بالـ API تبدو أنظف)الأدنى (يستخدم جلسة متصفحك الحقيقية)
جودة بنية البياناتمتوسطة (HTML غير منظّم ← تحليل يدوي)ممتازة (JSON منظّم مسبقًا)عالية (الذكاء الاصطناعي يكتشف الحقول والأنواع تلقائيًا)
عبء الصيانةمرتفع — تغيير واحد في التخطيط يكسر المحدداتمتوسط — قد تتغير نقاط النهاية دون إشعارالأدنى — الذكاء الاصطناعي يتكيّف مع تغيّر التخطيط
القابلية للتوسّعمنخفضة إلى متوسطة (مئات الصفحات مع بروكسيات)متوسطة إلى عالية (آلاف، بطلبات أنظف)متوسطة (50 صفحة لكل دفعة عبر التجريف السحابي)
الأنسب لـالمطورين الراغبين في تحكّم كاملالمطورين الذين يحتاجون JSON نظيفًاغير المبرمجين، المشاريع السريعة، البيانات المستمرة دون موارد تطوير

يستحق جانب الصيانة تأكيدًا خاصًا. فقد أطلق Redfin جيلين من DOM البطاقات: القديم (homecardV2Price) والحالي (span.bp-Homecard__Price--value). ويُظهر سجل مشكلات GitHub لدى المجتمع أن محددات CSS تنكسر كل 6 إلى 12 شهرًا تقريبًا. وعندما يحدث ذلك، ينهار سكربت BeautifulSoup بين ليلة وضحاها. أما كاشف الحقول القائم على الذكاء الاصطناعي، فيتكيّف.

قبل أن تبدأ

  • الصعوبة: متوسطة (المقاربتان 1 و2)، مبتدئة (المقاربة 3)
  • الوقت المطلوب: نحو 30 دقيقة للمقاربة 1 أو 2؛ ونحو 5 دقائق للمقاربة 3
  • ما ستحتاجه:
    • Python 3.8 أو أحدث مع pip (المقاربتان 1 و2)
    • متصفح Chrome (جميع المقاربات)
    • إضافة Thunderbit لمتصفح Chrome (المقاربة 3)
    • بروكسيات سكنية أمريكية للتجريف واسع النطاق (المقاربتان 1 و2)

استخرج بيانات Redfin بالذكاء الاصطناعي Get Started Free

المقاربة 1: تجريف Redfin بلغة Python عبر تحليل HTML (BeautifulSoup + Selenium)

هذا هو مسار «التحكّم الكامل». أنت من يكتب المحددات، وأنت من يدير المتصفح، وأنت من يعالج الأخطاء.

إنها المقاربة الأكثر إفادة تعليميًا. وهي أيضًا الأكثر هشاشة.

الخطوة 1: إعداد بيئة Python

أنشئ بيئة افتراضية وثبّت المكتبات المطلوبة:

python -m venv redfin-scraper
source redfin-scraper/bin/activate  # على Windows: redfin-scraper\Scripts\activate
pip install requests beautifulsoup4 selenium webdriver-manager pandas curl_cffi

مكتبة curl_cffi أساسية هنا، فهي ما يتيح لطلبات HTTP لديك انتحال بصمة TLS الخاصة بمتصفح Chrome حقيقي، بدلًا من بصمة requests القياسية في Python التي تحجبها Cloudflare من أول نظرة.

الخطوة 2: ضبط ترويسات المتصفح والجلسة

هنا يفشل معظم المبتدئين. أنت بحاجة إلى مجموعة ترويسات Chrome الكاملة، بما فيها ترويسات Sec-Fetch-* التي يتحقق منها Redfin/Cloudflare صراحةً:

from curl_cffi import requests as curl_requests

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-User": "?1",
}

session = curl_requests.Session(impersonate="chrome120")
session.headers.update(HEADERS)

# تسخين الجلسة — جمع كوكيز cf_clearance و RF_BROWSER_ID
session.get("https://www.redfin.com/")

خطوة تسخين الجلسة حاسمة، فالدخول البارد إلى رابط عقار عميق (دون كوكيز سابقة ودون Referer) يخفّض تقييمك لدى Cloudflare.

ابدأ دائمًا من الصفحة الرئيسية.

الخطوة 3: تجريف نتائج البحث في Redfin

بعد تسخين جلستك، يمكنك جلب صفحة بحث لمدينة ما وتحليل بطاقات الإعلانات. المحددات من الجيل الحالي (2024–2026):

import time
import random
from bs4 import BeautifulSoup

base_url = "https://www.redfin.com/city/17151/CA/San-Francisco"
listings = []

for page_num in range(1, 6):  # الصفحات من 1 إلى 5
    url = f"{base_url}/page-{page_num}" if page_num > 1 else base_url
    resp = session.get(url)

    if resp.status_code != 200:
        print(f"Blocked on page {page_num}: HTTP {resp.status_code}")
        break

    soup = BeautifulSoup(resp.text, "html.parser")
    cards = soup.select("[data-rf-test-id='property-card'], a.bp-Homecard")

    for card in cards:
        price_el = card.select_one("span.bp-Homecard__Price--value")
        addr_el = card.select_one("a.bp-Homecard__Address")
        stats = card.select("span.bp-Homecard__LockedStat--value")

        listing = {
            "price": price_el.text.strip() if price_el else None,
            "address": addr_el.text.strip() if addr_el else None,
            "beds": stats[0].text.strip() if len(stats) > 0 else None,
            "baths": stats[1].text.strip() if len(stats) > 1 else None,
            "sqft": stats[2].text.strip() if len(stats) > 2 else None,
            "url": "https://www.redfin.com" + addr_el["href"] if addr_el else None,
        }
        listings.append(listing)

    # تأخير عشوائي بين 2 و5 ثوانٍ
    time.sleep(random.uniform(2, 5))

print(f"Scraped {len(listings)} listings")

من المفترض أن ترى قائمة متنامية من القواميس، يحتوي كل منها على سعر إعلان في سان فرانسيسكو وعنوانه وعدد الغرف/الحمامات/المساحة ورابط التفاصيل. وإذا حصلت على 0 بطاقة، فتحقّق من رمز حالة HTTP: الرمز 403 يعني أن Cloudflare أمسكت بك، وغالبًا ستحتاج إلى بروكسيات سكنية.

الخطوة 4: تجريف صفحات تفاصيل العقارات الفردية

نتائج البحث تعطيك الأساسيات. أما صفحات التفاصيل فتعطيك تقدير Redfin، وسنة البناء، ورسوم اتحاد الملاك، وتاريخ البيع، ومعلومات الوكيل، والصور. وهذه الصفحات تتطلب تصيير JavaScript، لذا انتقل إلى Selenium:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time

options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                     "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

for listing in listings[:10]:  # إثراء أول 10 إعلانات
    driver.get(listing["url"])
    time.sleep(random.uniform(3, 6))  # انتظار تصيير JavaScript

    try:
        estimate_el = driver.find_element(By.CSS_SELECTOR, "[data-rf-test-name='avmLdpPrice']")
        listing["redfin_estimate"] = estimate_el.text.strip()
    except:
        listing["redfin_estimate"] = None

    try:
        year_built = driver.find_element(By.XPATH, "//span[contains(text(),'Year Built')]/following-sibling::span")
        listing["year_built"] = year_built.text.strip()
    except:
        listing["year_built"] = None

driver.quit()

بعد هذه الخطوة، ينبغي أن تكون أول 10 إعلانات لديك مُثراة بقيم تقدير Redfin وبيانات سنة البناء. ومحددات XPath أكثر مرونة من CSS مع حقول المرافق المتداخلة هذه، لكنها تبقى هشّة: أي إعادة هيكلة لـ DOM ستكسرها.

الخطوة 5: التعامل مع الحجب والأخطاء

طبّق منطق إعادة المحاولة مع تراجع أُسّي:

import time

def fetch_with_retry(session, url, max_retries=3):
    for attempt in range(max_retries):
        resp = session.get(url)
        if resp.status_code == 200:
            return resp
        elif resp.status_code in (403, 429, 503):
            wait = (2 ** attempt) + random.uniform(1, 3)
            print(f"Blocked ({resp.status_code}). Retrying in {wait:.1f}s...")
            time.sleep(wait)
        else:
            print(f"Unexpected status: {resp.status_code}")
            break
    return None

علامات تدلّ على أنك حُجبت: رمز HTTP 403 مع HTML من Cloudflare في الجسم، أو HTTP 429 (تحديد معدل صريح)، أو جسم استجابة فارغ، أو ظهور "Error 1020 Access Denied" في محتوى الصفحة. وإذا كنت تواجه هذه العلامات باستمرار، فقد حان وقت إضافة بروكسيات سكنية أو التحوّل إلى مقاربة الـ API.

المقاربة 2: تجريف Redfin بلغة Python عبر واجهة Stingray المخفية

هذه مقاربتي المفضّلة. فواجهة Redfin الأمامية تتحدث إلى واجهة JSON داخلية على /stingray/api/home/details/*، وتعود الاستجابات على شكل JSON نظيف ومحدد الأنواع، دون أي حاجة إلى تحليل HTML.

كيف تكتشف نقاط النهاية المخفية في Redfin

افتح أدوات مطوّري Chrome ← تبويب Network ← فلترة حسب Fetch/XHR ← ثم انتقل إلى أي صفحة عقار في Redfin. سترى طلبات إلى نقاط نهاية مثل:

  • api/home/details/initialInfo — يحوّل الرابط إلى propertyId وlistingId
  • api/home/details/aboveTheFold — السعر، الغرف، الحمامات، المساحة، الصور، الحالة، الوكيل، رقم MLS
  • api/home/details/belowTheFold — المرافق، رسوم اتحاد الملاك، الضرائب، المواقف، سنة البناء، الأرض، التاريخ
  • api/home/details/avm — تقدير Redfin للعقارات المعروضة في السوق
  • api/home/details/owner-estimate — تقدير Redfin للعقارات خارج السوق
  • api/home/details/descriptiveParagraph — الوصف التسويقي

أما بالنسبة لصفحات الإيجار، فيُستخرج rentalId (وهو UUID مكوّن من 36 حرفًا) من رابط وسم <meta property="og:image">.

تجريف بيانات العقارات عبر Stingray API

هناك خصوصية بالغة الأهمية: استجابات Stingray بصيغة JSON تبدأ بالسلسلة الحرفية {}&& كإجراء لمكافحة تزوير الطلبات عبر المواقع (CSRF). ويجب حذفها قبل التحليل:

import json
from curl_cffi import requests as curl_requests

session = curl_requests.Session(impersonate="chrome120")
session.headers.update(HEADERS)

# تسخين الجلسة
session.get("https://www.redfin.com/")

# جلب صفحة العقار للحصول على الكوكيز ومعرّف العقار
property_url = "https://www.redfin.com/CA/San-Francisco/123-Main-St-94102/home/12345678"
page_resp = session.get(property_url)

# الآن اطلب Stingray API
api_url = "https://www.redfin.com/stingray/api/home/details/aboveTheFold?propertyId=12345678"
api_resp = session.get(api_url, headers={"Referer": property_url})

# حذف بادئة مكافحة CSRF
payload = json.loads(api_resp.text.replace("{}&&", "", 1))

# استخراج البيانات المنظّمة
listing_data = payload.get("payload", {})
print(json.dumps(listing_data, indent=2))

تتضمن الاستجابة حقولًا محددة الأنواع: السعر كعدد صحيح، والغرف والحمامات كأرقام، وروابط الصور كمصفوفات، ومعلومات الوكيل ككائنات متداخلة. لا تحليل بـ BeautifulSoup، ولا محددات CSS، ولا تخمين.

مزايا وقيود مقاربة الواجهة المخفية

المزايا:

  • JSON منظّم مسبقًا — أنظف بكثير من تحليل HTML
  • أسرع لكل طلب (حمولات أصغر، ولا عبء تصيير)
  • خطر حجب أقل (الطلبات الشبيهة بالـ API مع ترويسات سليمة تبدو أكثر طبيعية)

القيود:

  • قد تتغير نقاط النهاية دون إشعار — ولا يوجد توثيق رسمي
  • يمنع ملف robots.txt صراحةً الوصول إلى /stingray/ لوكيل المستخدم العام
  • يتطلب هندسة عكسية لاكتشاف نقاط نهاية جديدة
  • ما زال يحتاج إلى تسخين الجلسة وترويسات سليمة لتفادي Cloudflare

البديل بلا أكواد: تجريف Redfin باستخدام Thunderbit

إذا كنت تحتاج بيانات Redfin ولا ترغب في صيانة سكربتات Python، أو أردت ببساطة نتائج خلال خمس دقائق، فابدأ من هنا. لقد بنينا Thunderbit لهذا الغرض تمامًا: استخراج بيانات منظّمة من أي موقع، دون أي كود.

الخطوة 1: ثبّت Thunderbit وانتقل إلى Redfin

ثبّت إضافة Thunderbit لمتصفح Chrome من متجر Chrome الإلكتروني. افتح Redfin وانتقل إلى صفحة نتائج بحث، مثل منازل سان فرانسيسكو المعروضة للبيع.

الخطوة 2: انقر على «AI Suggest Fields»

انقر على أيقونة Thunderbit في شريط أدوات متصفحك، ثم انقر على «AI Suggest Fields». يقرأ الذكاء الاصطناعي صفحة Redfin ويقترح تلقائيًا أعمدة مثل «العنوان» و«السعر» و«غرف النوم» و«الحمامات» و«المساحة بالقدم المربع» و«نوع العقار» و«صورة الإعلان»، مع تعيين أنواع البيانات الصحيحة تلقائيًا.

ويمكنك حذف الأعمدة التي لا تحتاجها، أو إضافة أعمدة مخصصة بالنقر على «+ Add Column» ووصف ما تريده بلغة طبيعية بسيطة (مثل «اسم وكيل الإعلان» أو «أيام العرض في السوق»).

من المفترض أن ترى معاينة لجدول يحتوي على الأعمدة التي ضبطتها، جاهزًا للتعبئة.

الخطوة 3: انقر على «Scrape» وشاهد البيانات تتدفق

انقر على زر «Scrape». يعالج Thunderbit الإعلانات الظاهرة ويملأ جدولك. وفي حالة النتائج المقسّمة إلى صفحات، يتعامل مع التنقّل بين الصفحات تلقائيًا، دون الحاجة إلى أي منطق حلقات.

في اختباراتي، امتلأ جدول من 50 صفًا في نحو 45 ثانية. بيانات منظّمة، جاهزة للتصدير.

كيف يتعامل Thunderbit مع حماية Redfin ضد الروبوتات

بما أن Thunderbit يعمل داخل متصفحك أنت، فإنه يرث كوكيز Redfin الحالية لديك، وجلستك، وبصمة متصفحك. وبالنسبة لـ Cloudflare، يبدو الأمر وكأن مستخدمًا عاديًا يتصفح Redfin — لأنه من الناحية التقنية كذلك فعلًا. لا متصفح بلا واجهة، ولا عنوان IP لمركز بيانات، ولا بصمة TLS غير متطابقة. وبالنسبة للصفحات المتاحة للعموم، يستطيع وضع التجريف السحابي في Thunderbit معالجة 50 صفحة في وقت واحد.

هذا وضع مختلف جذريًا عن إطلاق طلبات requests من سكربت Python على خادم.

جلسة متصفحك موثوقة بالفعل.

تجريف الصفحات الفرعية في Redfin باستخدام Thunderbit

بعد تجريف نتائج البحث، انقر على «Scrape Subpages» ليقوم الذكاء الاصطناعي بزيارة رابط تفاصيل كل عقار وإثراء جدولك بحقول إضافية: تقدير Redfin، وسنة البناء، ورسوم اتحاد الملاك، ومعلومات الوكيل، وصور العقار، وتاريخ البيع.

وهذا يعادل حلقة Selenium المكوّنة من 40 سطرًا في المقاربة 1، باستثناء أنه يستغرق نقرة واحدة وصيانة صفرية.

وعندما يغيّر Redfin هيكل DOM من homecardV2Price إلى span.bp-Homecard__Price--value، يتكيّف الذكاء الاصطناعي. أما محددات Python لديك، فلا.

استخرج الصفحات الفرعية لـ Redfin بالذكاء الاصطناعي Get Started Free

أبعد من CSV: تصدير بيانات Redfin إلى Google Sheets وAirtable وNotion

تتوقف معظم الشروحات عند df.to_csv(). وهذا مقبول لتحليل لمرة واحدة. لكن إذا كنت ضمن فريق عقاري، فأنت بحاجة إلى بيانات تعاونية وحيّة، لا ملفات ثابتة تتراكم عليها الأتربة على سطح مكتب أحدهم.

التصدير باستخدام Python (gspread + واجهة Airtable)

Google Sheets عبر gspread:

import gspread
import pandas as pd
from gspread_dataframe import set_with_dataframe

df = pd.DataFrame(listings)
gc = gspread.service_account(filename="service_account.json")
sh = gc.open("Redfin Listings")
ws = sh.worksheet("Sheet1")
ws.clear()
set_with_dataframe(ws, df, include_index=False, resize=True)

# عرض صور العقارات داخل الخلايا عبر دالة IMAGE()
image_col = df.columns.get_loc("image_url") + 1
for row_idx, url in enumerate(df["image_url"], start=2):
    ws.update_cell(row_idx, image_col, f'=IMAGE("{url}")')

انتبه: لدى Sheets حد صارم يبلغ 10 ملايين خلية لكل جدول بيانات، وتسمح الواجهة بـ 300 طلب قراءة و300 طلب كتابة في الدقيقة لكل مشروع. استخدم ws.batch_update() بدلًا من الحلقات على مستوى الخلية لأي شيء يتجاوز بضع عشرات من الصفوف.

Airtable عبر pyairtable:

تغيير جوهري في 2024: أوقفت Airtable العمل بمفاتيح الواجهة القديمة في 1 فبراير 2024. عليك الآن استخدام رموز الوصول الشخصية (PATs)؛ وأي شرح ما زال يعرض api_key=... فهو غير صالح.

from pyairtable import Api

api = Api("patXXXXXXXXXXXXXX.yyyyyyyyyyyyyyyyyyyy")
table = api.table("appBaseId123", "Redfin Listings")

records = [
    {
        "Address": row["address"],
        "Price": row["price"],
        "Beds": row["beds"],
        "Photo": [{"url": row["image_url"]}],  # Airtable يجلبها ويعيد استضافتها
    }
    for row in listings
]
created = table.batch_create(records, typecast=True)

حد المعدل في Airtable هو 5 طلبات في الثانية لكل قاعدة، مع إيقاف لمدة 30 ثانية عند المخالفة. ويقبل حقل المرفقات حمولات بصيغة [{"url": ...}]؛ إذ تجلب خوادم Airtable الرابط، وتعيد استضافته على شبكة التوزيع الخاصة بها، وتولّد الصور المصغّرة تلقائيًا.

التصدير باستخدام Thunderbit (نقرة واحدة إلى Sheets وAirtable وNotion)

يوفّر Thunderbit تصديرًا أصليًا بنقرة واحدة إلى Google Sheets وAirtable وNotion، وإليك الجزء الذي أفخر به حقًا: تُرفع صور العقارات وتُعرض كصور مضمّنة داخل Notion وAirtable. لا حيل بدالة =IMAGE()، ولا روابط CDN مكسورة. تنقر على «Export to Airtable»، ويحصل فريقك على قاعدة بيانات عقارية بصرية بصور مصغّرة يمكنهم تصفّحها من هواتفهم.

بالنسبة للفرق العقارية التي تفرز الإعلانات بصريًا، هذا هو الفرق بين أداة مفيدة وكومة من صفوف CSV.

هل تجريف Redfin قانوني؟ ماذا تقول شروط الاستخدام وrobots.txt والسوابق القضائية

لست محاميًا، وهذا ليس استشارة قانونية. لكن بعد سنوات في مجال استخراج البيانات، يمكنني أن أقول: «هل هذا قانوني؟» هو السؤال الذي يطرحه الجميع وتتهرب منه معظم الشروحات.

ملف robots.txt لدى Redfin

ملف robots.txt لدى Redfin مفصّل. وأبرز نقاطه:

  • روبوتات محظورة كليًا: peer39_crawler/1.0 وAmazonAdBot وFireCrawlAgent — إذ يذكر Redfin بالاسم خدمة التجريف الشهيرة في عصر نماذج اللغة الكبيرة
  • أبرز ما يمنعه User-agent: * العام: /stingray/ (كامل مساحة الأسماء الخاصة بالواجهة الداخلية)، و/myredfin/، و/api/v1/rentals/، و/api/v1/properties/، و/owner-estimate/
  • لا يوجد توجيه Crawl-delay: لأي وكيل مستخدم
  • أكثر من 50 خريطة موقع معلنة — وخرائط المواقع هي أنظف طريقة لتعداد الروابط وأقلها احتكاكًا بجدار الحماية

شروط استخدام Redfin

ينص البند 2.3.5 على: «لا يجوز لك الزحف إلى الخدمات أو الاستعلام عنها بشكل آلي لأي غرض أو بأي وسيلة... ما لم تكن قد حصلت على إذن خطي صريح مسبق.»

هذه اتفاقية من نوع browsewrap، أي أن القبول يتم بمجرد الاستمرار في الاستخدام، لا بالنقر على موافقة. وقد كانت المحاكم الأمريكية تاريخيًا متشككة في إنفاذ اتفاقيات browsewrap بحق مستخدمين لم يكن لديهم علم فعلي بها (انظر قضية Nguyen v. Barnes & Noble، الدائرة التاسعة، 2014).

سوابق قضائية ذات صلة (بإيجاز)

  • Van Buren v. United States (المحكمة العليا، 2021): بند «تجاوز الوصول المصرّح به» في قانون CFAA يخضع لاختبار «البوابة مفتوحة أم مغلقة». واستخدام باب مفتوح لغرض غير مرحّب به ليس اختراقًا فيدراليًا.
  • hiQ Labs v. LinkedIn (الدائرة التاسعة، 2022): تجريف البيانات المتاحة للعموم ليس انتهاكًا لقانون CFAA. لكن hiQ دفعت في النهاية 500,000 دولار في تسوية على أساس الإخلال بالعقد، لأنها كانت تملك حسابات مسجّلة على LinkedIn ونقرت على «أوافق».
  • Meta Platforms v. Bright Data (المحكمة الفيدرالية لشمال كاليفورنيا، يناير 2024): منحت المحكمة حكمًا مستعجلًا لصالح Bright Data — فالتجريف دون تسجيل دخول للبيانات العامة لا يجعل Bright Data «مستخدمًا» ملزمًا بشروط استخدام Meta.
  • X Corp. v. Bright Data (المحكمة الفيدرالية لشمال كاليفورنيا، مايو 2024): رفض القاضي Alsup دعاوى X، معتبرًا أن دعاوى قانون الولاية التي تحاول التحكم في نسخ المحتوى العام يجبّها قانون حقوق النشر الفيدرالي.

إرشادات عملية

  • جرّف فقط البيانات المتاحة للعموم، ولا تسجّل حسابًا ثم تجرّف (فذلك يعرّضك لالتزام تعاقدي من نوع clickwrap)
  • احترم حدود المعدل — فالأحجام العدوانية تدعم دعاوى التعدي على الممتلكات المنقولة
  • لا تعِد نشر البيانات الخام أو الصور على نطاق واسع — فدعوى CoStar ضد Zillow (المرفوعة في يوليو 2025، بتعويضات محتملة تتجاوز مليار دولار) تذكير بأن حقوق نشر الصور مسألة جدية
  • مقاربة Thunderbit القائمة على المتصفح — أي العمل داخل جلستك المصادَق عليها — أقرب إلى «تصفّح يدوي بسرعة الآلة» منها إلى روبوت بلا واجهة يعمل من مركز بيانات، وهذا هو الوضع الأكثر قابلية للدفاع عنه بعد الواجهات المرخّصة

نصائح وأخطاء شائعة

بعض الدروس المكتسبة بشق الأنفس من بناء أدوات الاستخراج ومتابعة آلاف المستخدمين وهم يجرّفون مواقع العقارات:

  • سخّن جلستك دائمًا. ادخل إلى redfin.com/ قبل أي رابط عميق. فالدخول البارد إلى الروابط العميقة هو المحرّك الأول لتحديات Cloudflare.
  • دوّر نصوص User-Agent بشكل واقعي. لا تستخدم واحدًا فقط، بل دوّر بين 5 إلى 10 نصوص حديثة من Chrome/Firefox. لكن لا تبالغ في التدوير (تغيير UA مع كل طلب يبدو مريبًا).
  • أزل التكرار حسب معرّف العقار. يتداخل ترقيم صفحات Redfin أحيانًا. استخرج /home/{id} من رابط كل إعلان وأزل التكرار قبل الإثراء.
  • تجنّب التجريف في ساعات الذروة إن أمكن. حسب تجربتي، تشهد ساعات الليل المتأخرة والصباح الباكر بتوقيت الولايات المتحدة تدقيقًا أقل من جدار الحماية.
  • إذا واجهت 429، تراجع أُسّيًا. لا تعِد المحاولة فورًا، فهكذا تتصاعد من تحديد معدل مرن إلى حظر IP صارم.
  • للمشاريع واسعة النطاق (أكثر من 1000 صفحة)، خصّص ميزانية لبروكسيات سكنية. فعناوين مراكز البيانات (AWS، GCP، Azure، OVH) مدرجة في القوائم السوداء لنظام سمعة ASN لدى Cloudflare. وستواجه الخطأ 1020 على الفور تقريبًا.

اختيار الطريقة المناسبة لتجريف Redfin

إذًا، أي مقاربة ينبغي أن تختار؟ يعتمد ذلك على من أنت وما تحتاجه.

تحليل HTML (BeautifulSoup + Selenium): الأفضل للمطورين الذين يريدون تحكمًا كاملًا، ولا يمانعون صيانة محددات CSS، ولا يزعجهم إعادة البناء عندما يغيّر Redfin هيكل DOM. توقّع أن تعود إلى كودك كل 6 إلى 12 شهرًا.

واجهة Stingray المخفية: الأفضل للمطورين الذين يحتاجون JSON نظيفًا ومنظّمًا، ويستطيعون التعامل مع الهندسة العكسية لنقاط نهاية غير موثّقة. صيانتها أقل من تحليل HTML، لكن نقاط النهاية قد تتغير دون إشعار. وتذكّر أن /stingray/ ممنوع صراحةً في ملف robots.txt.

Thunderbit (بلا أكواد): الأفضل لغير المطورين، وللمشاريع السريعة، وللفرق التي تحتاج بيانات Redfin بشكل مستمر دون موارد تطوير. فالذكاء الاصطناعي يتكيّف مع تغيّرات التخطيط، وتجريف الصفحات الفرعية يثري البيانات بنقرة واحدة، والتصدير إلى Google Sheets أو Airtable أو Notion مدمج أصلًا. وإذا كنت فريقًا عقاريًا يحتاج قاعدة بيانات عقارية حيّة، لا ملف CSV لمرة واحدة، فهذا هو المسار الأقل مقاومة.

وأيًّا كان المسار الذي تسلكه: افهم دفاعات Redfin ضد الروبوتات قبل أن تبدأ، واعرف ما الحقول التي تحتاجها، واختر صيغة تصدير تناسب سير عمل فريقك، وابقَ على الجانب الصحيح من الإرشادات القانونية.

مستعد لتجربة المسار بلا أكواد؟ الخطة المجانية من Thunderbit تتيح لك تجربة تجريف Redfin ورؤية النتائج خلال دقائق. أما بالنسبة لمقاربات Python، فالمقتطفات البرمجية أعلاه نقطة انطلاق عملية، ولا ينقصها سوى البروكسيات والصبر.

جرّب Thunderbit للحصول على بيانات Redfin محدَّثة باستمرار

الأسئلة الشائعة

هل لدى Redfin واجهة برمجية عامة؟

لا. لا يقدّم Redfin واجهة برمجية عامة رسمية. أما واجهة Stingray المخفية (/stingray/api/home/details/*) فتعيد JSON منظّمًا وتستخدمها واجهة Redfin الأمامية نفسها، لكنها غير رسمية وغير موثّقة وقابلة للتغيير دون إشعار وممنوعة صراحةً في ملف robots.txt لدى Redfin. وتوفّر مغلّفات مفتوحة المصدر مثل reteps/redfin على PyPI وصولًا عبر Python، لكن استخدمها وأنت مدرك للمخاطر.

هل يمكنني تجريف Redfin دون Python؟

نعم. Thunderbit هو إضافة Chrome مدعومة بالذكاء الاصطناعي ترث جلسة متصفحك لمقاومة أنظمة مكافحة الروبوتات: ثبّتها، وانتقل إلى Redfin، وانقر على «AI Suggest Fields»، ثم صدّر إلى Excel أو Google Sheets أو Airtable أو Notion. وتوجد أيضًا أدوات تجريف أخرى بلا أكواد ومزوّدو مجموعات بيانات جاهزة في السوق إذا أردت استكشاف بدائل.

كم مرة يغيّر Redfin تخطيط موقعه؟

يُظهر سجل مشكلات GitHub لدى المجتمع أن محددات CSS تنكسر كل 6 إلى 12 شهرًا تقريبًا. وقد أطلق Redfin جيلين من DOM البطاقات: القديم (homecardV2Price وhomeAddressV2) والحالي (bp-Homecard__Price--value وbp-Homecard__Address). وأدوات التجريف الناضجة تجرّب الاثنين بالتتابع.

أما الأدوات القائمة على الذكاء الاصطناعي مثل Thunderbit فـتتكيّف تلقائيًا لأنها تكتشف الحقول عبر المحتوى لا عبر محددات CSS.

ما أفضل نوع بروكسي لتجريف Redfin؟

البروكسيات السكنية الأمريكية للتجريف واسع النطاق، إذ تشير قياسات المجتمع إلى معدل نجاح يقارب 80%. أما بروكسيات مراكز البيانات فتصطدم بخطأ Cloudflare 1020 على الفور تقريبًا؛ فنطاقات AWS وGCP وAzure وOVH مدرجة في القوائم السوداء. وتحقق البروكسيات الجوّالة أعلى معدل نجاح، لكن تكلفتها أعلى بـ 5 إلى 10 أضعاف.

وللتجريف الشخصي محدود النطاق (أقل من 100 صفحة)، قد تكفي الترويسات السليمة + انتحال curl_cffi + تأخيرات من 2 إلى 5 ثوانٍ دون أي بروكسيات على الإطلاق.

هل يمكنني تجريف بيانات العقارات المباعة أو خارج السوق من Redfin؟

نعم. تتوفر بيانات العقارات المباعة وتقدير Redfin للعقارات خارج السوق (بمتوسط خطأ 7.52%) في صفحات التفاصيل باستخدام المقاربات نفسها. لكن الحقول تختلف عن الإعلانات النشطة: فصفحات خارج السوق تعرض سعر البيع وتاريخه وتاريخ العقار ونقطة نهاية تقدير المالك، لكنها تفتقر إلى سعر الطلب الحالي وأيام العرض في السوق ومعلومات البيوت المفتوحة. ونقطة نهاية Stingray API الخاصة بتقديرات خارج السوق هي api/home/details/owner-estimate بدلًا من api/home/details/avm.

جرّب Thunderbit لاستخراج بيانات Redfin Get Started Free

اقرأ المزيد

Shuai Guan
Shuai Guan
الرئيس التنفيذي في Thunderbit | خبير في أتمتة البيانات بالذكاء الاصطناعي Shuai Guan هو الرئيس التنفيذي لشركة Thunderbit وخريج كلية الهندسة بجامعة ميشيغان. وبالاستناد إلى ما يقرب من عشر سنوات من الخبرة في مجالي التقنية وبنية SaaS، يتخصص في تحويل نماذج الذكاء الاصطناعي المعقدة إلى أدوات عملية لاستخراج البيانات بدون الحاجة إلى البرمجة. في هذه المدونة، يشارك رؤى صريحة ومجرّبة ميدانيًا حول استخراج البيانات من الويب واستراتيجيات الأتمتة، لمساعدتك على بناء سير عمل أذكى يعتمد على البيانات. وعندما لا يكون منشغلاً بتحسين تدفقات العمل الخاصة بالبيانات، يوجّه نفس دقته واهتمامه بالتفاصيل إلى شغفه بالتصوير الفوتوغرافي.
جدول المحتويات
Thunderbit · وكيل بيانات الويب بالذكاء الاصطناعي

استخرج البيانات من أي صفحة في بنقرة واحدة

يثق به أكثر من 250,000 مستخدم
تتوفر خطة مجانية
من صفحة ويب إلى جدول بيانات
صف ما تحتاجه — يتولى وكيل Thunderbit الذكي استخراجه وتصديره إلى Excel أو Google Sheets أو Airtable أو Notion. ابدأ مجانًا.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week