تحمي منصات توصيل الطعام بيانات التسعير الخاصة بها من خلال اختبارات CAPTCHA واكتشاف الروبوتات. تحتاج خدمات مقارنة الأسعار وباحثو السوق وأدوات تحليلات المطاعم إلى الوصول الآلي لمقارنة أسعار القائمة ورسوم التوصيل والعروض الترويجية عبر DoorDash وUber Eats وGrubhub والمنصات الأخرى.
CAPTCHAs على منصات التسليم
| منصة | نوع التحقق | المحفّز | البيانات المحمية |
|---|---|---|---|
| DoorDash | reCAPTCHA v3 + كلاود فلير | كشف البوت | القوائم والأسعار والرسوم |
| اوبر إيتس | Cloudflare Turnstile | الوصول الآلي | قوائم المطاعم والأسعار |
| جروبوب | reCAPTCHA v2 | الحد من المعدل | عناصر القائمة، والترقيات |
| زملاء البريد | Cloudflare Challenge | كشف الخدش | رسوم التسليم، ETAs |
| فقط أكل | reCAPTCHA v2 | عمليات البحث المتكررة | بيانات المطعم |
| إنستاكارت | reCAPTCHA v3 | كشف البوت | أسعار البقالة |
مقارنة الأسعار متعددة المنصات
import requests
import time
import re
from bs4 import BeautifulSoup
import json
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"
def solve_captcha(method, sitekey, pageurl, **kwargs):
data = {
"key": CAPTCHAAI_KEY, "method": method,
"googlekey": sitekey, "pageurl": pageurl, "json": 1,
}
data.update(kwargs)
resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data=data)
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
"key": CAPTCHAAI_KEY, "action": "get",
"id": task_id, "json": 1,
})
r = result.json()
if r["request"] != "CAPCHA_NOT_READY":
return r["request"]
raise TimeoutError("Timeout")
class FoodDeliveryComparator:
def __init__(self, proxy=None):
self.session = requests.Session()
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) "
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 "
"Mobile/15E148 Safari/604.1",
"Accept-Language": "en-US,en;q=0.9",
})
def search_restaurants(self, platform_url, location, cuisine=None):
"""Search restaurants on a delivery platform."""
params = {"address": location}
if cuisine:
params["cuisine"] = cuisine
url = f"{platform_url}/search"
resp = self.session.get(url, params=params, timeout=30)
if self._has_captcha(resp.text):
resp = self._solve_and_retry(resp.text, url)
return self._parse_restaurants(resp.text)
def get_menu(self, restaurant_url):
"""Get menu with prices from a specific restaurant."""
resp = self.session.get(restaurant_url, timeout=30)
if self._has_captcha(resp.text):
resp = self._solve_and_retry(resp.text, restaurant_url)
return self._parse_menu(resp.text)
def compare_restaurant_across_platforms(self, restaurant_name, platforms, location):
"""Compare same restaurant's pricing across delivery platforms."""
results = []
for platform in platforms:
try:
restaurants = self.search_restaurants(
platform["url"], location,
)
# Find matching restaurant
match = None
for r in restaurants:
if restaurant_name.lower() in r["name"].lower():
match = r
break
if match and match.get("url"):
menu = self.get_menu(match["url"])
results.append({
"platform": platform["name"],
"restaurant": match["name"],
"delivery_fee": match.get("delivery_fee", ""),
"delivery_time": match.get("delivery_time", ""),
"menu_items": len(menu),
"sample_prices": menu[:5],
})
else:
results.append({
"platform": platform["name"],
"restaurant": restaurant_name,
"status": "not found",
})
except Exception as e:
results.append({
"platform": platform["name"],
"error": str(e),
})
time.sleep(5)
return results
def track_delivery_fees(self, platforms, location, output_file):
"""Track delivery fees across platforms for analysis."""
all_data = []
for platform in platforms:
try:
restaurants = self.search_restaurants(
platform["url"], location,
)
for r in restaurants[:20]: # Top 20 per platform
all_data.append({
"platform": platform["name"],
"restaurant": r["name"],
"delivery_fee": r.get("delivery_fee", ""),
"delivery_time": r.get("delivery_time", ""),
"rating": r.get("rating", ""),
})
time.sleep(5)
except Exception as e:
print(f"Error on {platform['name']}: {e}")
with open(output_file, "w") as f:
json.dump(all_data, f, indent=2)
return all_data
def _has_captcha(self, html):
return any(tag in html.lower() for tag in [
'data-sitekey', 'g-recaptcha', 'cf-turnstile',
'challenge-platform',
])
def _solve_and_retry(self, html, url):
match = re.search(r'data-sitekey="([^"]+)"', html)
if not match:
return self.session.get(url)
sitekey = match.group(1)
if 'cf-turnstile' in html:
token = solve_captcha("turnstile", sitekey, url)
return self.session.post(url, data={"cf-turnstile-response": token})
token = solve_captcha("userrecaptcha", sitekey, url)
return self.session.post(url, data={"g-recaptcha-response": token})
def _parse_restaurants(self, html):
soup = BeautifulSoup(html, "html.parser")
restaurants = []
for card in soup.select(".restaurant-card, .store-card, .merchant"):
name_el = card.select_one(".name, .store-name, h3")
if name_el:
restaurants.append({
"name": name_el.get_text(strip=True),
"url": self._link(card),
"delivery_fee": self._text(card, ".delivery-fee, .fee"),
"delivery_time": self._text(card, ".delivery-time, .eta"),
"rating": self._text(card, ".rating, .stars"),
})
return restaurants
def _parse_menu(self, html):
soup = BeautifulSoup(html, "html.parser")
items = []
for item in soup.select(".menu-item, .item-card"):
items.append({
"name": self._text(item, ".item-name, .name"),
"price": self._text(item, ".price, .item-price"),
"description": self._text(item, ".description, .item-desc"),
})
return items
def _text(self, el, selector):
found = el.select_one(selector)
return found.get_text(strip=True) if found else ""
def _link(self, card):
a = card.select_one("a")
return a.get("href", "") if a else ""
# Usage
comparator = FoodDeliveryComparator(
proxy="http://user:pass@mobile.proxy.com:5000"
)
# Compare platforms
platforms = [
{"name": "Platform A", "url": "https://delivery-a.example.com"},
{"name": "Platform B", "url": "https://delivery-b.example.com"},
{"name": "Platform C", "url": "https://delivery-c.example.com"},
]
comparison = comparator.compare_restaurant_across_platforms(
restaurant_name="Pizza Palace",
platforms=platforms,
location="10001",
)
for result in comparison:
print(f"{result.get('platform')}: Fee={result.get('delivery_fee')} "
f"ETA={result.get('delivery_time')}")
توصيات الوكيل
| منصة | أفضل وكيل | لماذا |
|---|---|---|
| DoorDash | الجوال (4G) | اكتشاف الروبوتات الثقيلة، ويتوقع المحمول |
| اوبر إيتس | الجوال (4G) | منصة المحمول الأول |
| جروبوب | سكني | الحماية القياسية |
| إنستاكارت | سكني | كشف بوت معتدل |
| فقط أكل | السكنية الدوارة | كلاود فلير القياسية |
تعتبر تطبيقات التسليم هي الأولى على الأجهزة المحمولة، حيث تنتج وكلاء الأجهزة المحمولة مع وكلاء المستخدم على الأجهزة المحمولة أفضل النتائج.
نقاط البيانات لتتبعها
| متري | قيمة الأعمال |
|---|---|
| أسعار عناصر القائمة | تحليل تكافؤ الأسعار والعلامات |
| رسوم التوصيل | مقارنة رسوم المنصة |
| الحد الأدنى لكميات الطلب | تحليل حاجز الوصول |
| تقديرات وقت التسليم | مقارنة مستوى الخدمة |
| الترقيات/discounts | الاستخبارات التسويقية |
| توافر المطعم | تحليل التغطية |
استكشاف الأخطاء وإصلاحها
| المشكلة | السبب | الإجراء |
|---|---|---|
| نتائج مطعم فارغة | لم يتم تقديم الموقع أو صفحة CAPTCHA | قم بتعيين الرمز البريدي لعنوان التسليم الصحيح |
| أسعار القائمة تختلف عن التطبيق | التناقض في أسعار الويب مقابل التطبيقات | استخدم UA المحمول للحصول على أسعار مكافئة للتطبيق |
| حلقة التحدي Cloudflare | عدم تطابق بصمات الأصابع | استخدم وكيل المحمول + UA المحمول |
| تم العثور على مطعم على منصة واحدة ولكن ليس على منصة أخرى | تغطية مختلفة | وضع علامة "غير متوفر" في المقارنة |
| رسوم التوصيل غير صحيحة | التسعير يعتمد على الموقع | مطابقة الموقع الجغرافي للوكيل مع الموقع المستهدف |
الأسئلة الشائعة
لماذا تختلف الأسعار عبر منصات التسليم؟
تحدد المطاعم أسعارًا مختلفة لكل منصة لمراعاة معدلات العمولة المتفاوتة (15-30%). تختلف رسوم التوصيل ورسوم الخدمة أيضًا حسب النظام الأساسي.
هل يجب علي استخدام الهاتف المحمول أو سطح المكتب لحذف تطبيقات التوصيل؟
الهاتف المحمول - هذه هي المنصات المحمولة أولاً، حيث ينتج وكيل الهاتف المحمول مع وكيل المستخدم iPhone/Android حركة المرور الأكثر أصالة.
كم مرة يجب أن أقارن الأسعار؟
أسبوعي للتحليل العام للسوق. يوميًا خلال الفترات الترويجية أو سباقات البحث التنافسية.
أدلة ذات صلة
- قارن أسعار توصيل الطعام على نطاق واسع -احصل على مفتاح CaptchaAI الخاص بكوأتمتة التحليل عبر الأنظمة الأساسية.*