Yemek dağıtım platformları, fiyatlandırma verilerini CAPTCHA'lar ve bot tespitiyle korur. Fiyat karşılaştırma hizmetleri, pazar araştırmacıları ve restoran analiz araçları, DoorDash, Uber Eats, Grubhub ve diğer platformlarda menü fiyatlarını, teslimat ücretlerini ve promosyonları karşılaştırmak için otomatik erişime ihtiyaç duyar.
Dağıtım Platformlarındaki CAPTCHA'lar
| platformu | CAPTCHA Türü | Tetikleyici | Korunan Veriler |
|---|---|---|---|
| Kapı Göstergesi | reCAPTCHA v3 + Bulut parlaması | Bot tespiti | Menüler, fiyatlar, ücretler |
| Uber'in Yemekleri | Cloudflare Turnstile | Otomatik erişim | Restoran listeleri, fiyatlar |
| Grubhub | reCAPTCHA v2 | Hız sınırlaması | Menü öğeleri, promosyonlar |
| Posta arkadaşları | Cloudflare doğrulama akışı | Kazıma tespiti | Teslimat ücretleri, ETA'lar |
| Sadece Ye | reCAPTCHA v2 | Tekrarlanan aramalar | Restoran verileri |
| Instacart | reCAPTCHA v3 | Bot tespiti | Bakkal fiyatları |
Çoklu Platform Fiyat Karşılaştırıcısı
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')}")
Vekil Önerileri
| platformu | En İyi Vekil | neden |
|---|---|---|
| Kapı Göstergesi | Mobil (4G) | Ağır bot tespiti, mobil cihaz bekleniyor |
| Uber'in Yemekleri | Mobil (4G) | Mobil öncelikli platform |
| Grubhub | Konut | Standart koruma |
| Instacart | Konut | Orta düzeyde bot tespiti |
| Sadece Ye | Dönen konut | Standart Cloudflare |
Teslimat uygulamaları mobil önceliklidir; mobil Kullanıcı Aracılarına sahip kendi sunucu altyapınız'ler en iyi sonuçları üretir.
İzlenecek Veri Noktaları
| Metrik | İş Değeri |
|---|---|
| Menü öğesi fiyatları | Fiyat paritesi ve fiyat farkı analizi |
| Teslimat ücretleri | Platform ücreti karşılaştırması |
| Minimum sipariş tutarları | Erişim engeli analizi |
| Teslimat süresi tahminleri | Hizmet düzeyi karşılaştırması |
| Promosyonlar/discounts | Pazarlama zekası |
| Restoran müsaitliği | Kapsam analizi |
Sorun giderme
| Sorun | Sebep | Düzeltme |
|---|---|---|
| Boş restoran sonuçları | Konum sunulmuyor veya CAPTCHA sayfası | Doğru teslimat adresi zip'ini ayarlayın |
| Menü fiyatları uygulamadan farklı | Web ve uygulama fiyatlandırma tutarsızlığı | Uygulamaya eşdeğer fiyatlandırma almak için mobil UA'yı kullanın |
| Cloudflare meydan okuma döngüsü | test profil yapılandırması uyuşmazlığı | Kendi sunucu altyapınız + mobil UA kullanın |
| Restoran bir platformda bulundu ancak diğerinde bulunamadı | Farklı kapsam | Karşılaştırmada "mevcut değil" olarak işaretleyin |
| Yanlış teslimat ücretleri | Konuma bağlı fiyatlandırma | Proxy coğrafi konumunu hedef konumla eşleştirin |
SSS
Fiyatlar dağıtım platformlarında neden farklı?
Restoranlar, değişen komisyon oranlarını (%15-30) hesaba katmak için platform başına farklı fiyatlar belirliyor. Teslimat ücretleri ve hizmet ücretleri de platforma göre değişir.
Teslimat uygulamalarını kazımak için mobil mi yoksa masaüstü mü kullanmalıyım?
Mobil – bunlar önce mobil platformlardır. iPhone/Android Kullanıcı Aracısı içeren bir kendi sunucu altyapınız, en özgün görünümlü trafiği üretir.
Fiyatları ne sıklıkla karşılaştırmalıyım?
Genel piyasa analizi için haftalık. Promosyon dönemlerinde veya rekabetçi araştırma sprintlerinde günlük olarak.
İlgili Kılavuzlar
Gıda teslimatı fiyatlarını geniş ölçekte karşılaştırın —CaptchaAI anahtarınızı alınve platformlar arası analizi otomatikleştirin.