Les plateformes de livraison de nourriture protègent leurs données de tarification grâce aux CAPTCHA et à la détection de robots. Les services de comparaison de prix, les études de marché et les outils d'analyse des restaurants ont besoin d'un accès automatisé pour comparer les prix des menus, les frais de livraison et les promotions sur DoorDash, Uber Eats, Grubhub et d'autres plateformes.
CAPTCHA sur les plateformes de livraison
| Plateforme | Type de CAPTCHA | Déclencheur | Données protégées |
|---|---|---|---|
| PorteDash | reCAPTCHA v3 + Cloudflare | Détection de robots | Menus, prix, frais |
| Uber mange | Cloudflare Turnstile | Accès automatisé | Listes de restaurants, prix |
| Grubhub | reCAPTCHA v2 | Limitation du débit | Éléments de menu, promotions |
| Camarades de poste | Cloudflare Challenge | Détection de grattage | Frais de livraison, ETA |
| Mange juste | reCAPTCHA v2 | Recherches répétées | Données sur les restaurants |
| Instacart | reCAPTCHA v3 | Détection de robots | Prix des produits d'épicerie |
Comparateur de prix multiplateforme
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')}")
Recommandations de proxy
| Plateforme | Meilleur proxy | Pourquoi |
|---|---|---|
| PorteDash | Mobile (4G) | Détection intensive de robots, mobile attendu |
| Uber mange | Mobile (4G) | Plateforme axée sur le mobile |
| Grubhub | Résidentiel | Protections standards |
| Instacart | Résidentiel | Détection modérée des robots |
| Mange juste | Résidentiel tournant | Cloudflare standard |
Les applications de diffusion sont avant tout mobiles : les proxys mobiles avec des agents utilisateurs mobiles produisent les meilleurs résultats.
Points de données à suivre
| Métrique | Valeur commerciale |
|---|---|
| Prix des articles du menu | Analyse de la parité des prix et des majorations |
| Frais de livraison | Comparaison des frais de plateforme |
| Montants minimum de commande | Analyse des barrières d'accès |
| Estimations des délais de livraison | Comparaison des niveaux de service |
| Promotions/discounts | Intelligence marketing |
| Disponibilité des restaurants | Analyse de couverture |
Dépannage
| Problème | Parce que | Corriger |
|---|---|---|
| Résultats de restaurants vides | Emplacement non desservi ou page CAPTCHA | Définir l'adresse de livraison correcte zip |
| Prix des menus différents de ceux de l'application | Écart de prix entre le Web et les applications | Utilisez l'UA mobile pour obtenir des tarifs équivalents à ceux d'une application |
| Boucle de défi Cloudflare | Inadéquation des empreintes digitales | Utiliser un proxy mobile + UA mobile |
| Restaurant trouvé sur une plateforme mais pas sur une autre | Couverture différente | Marquer comme "non disponible" en comparaison |
| Frais de livraison incorrects | Tarification en fonction de l'emplacement | Faites correspondre la géolocalisation du proxy à l'emplacement cible |
FAQ
Pourquoi les prix sont-ils différents selon les plateformes de livraison ?
Les restaurants fixent des prix différents par plateforme pour tenir compte des différents taux de commission (15 à 30 %). Les frais de livraison et les frais de service varient également selon la plateforme.
Dois-je utiliser un mobile ou un ordinateur pour supprimer les applications de livraison ?
Mobile : ce sont des plates-formes axées sur le mobile. Un proxy mobile avec l'agent utilisateur iPhone/Android produit le trafic le plus authentique.
À quelle fréquence dois-je comparer les prix ?
Hebdomadaire pour une analyse générale du marché. Quotidiennement pendant les périodes promotionnelles ou les sprints de recherche compétitifs.
Guides connexes
- Surveillance des stocks de détail
- Proxy mobiles pour CAPTCHA
- Rotation des procurations résidentielles
Comparez les prix de livraison de nourriture à grande échelle -récupérez votre clé CaptchaAIet automatisez l'analyse multiplateforme.