Trường Hợp Sử Dụng

So sánh giá giao đồ ăn bằng cách giải CAPTCHA

Các nền tảng giao đồ ăn bảo vệ dữ liệu về giá của họ bằng CAPTCHA và tính năng phát hiện bot. Các dịch vụ so sánh giá, nhà nghiên cứu thị trường và công cụ phân tích nhà hàng cần quyền truy cập tự động để so sánh giá thực đơn, phí giao hàng và chương trình khuyến mãi trên DoorDash, Uber Eats, Grubhub và các nền tảng khác.


CAPTCHA trên nền tảng phân phối

Nền tảng Loại CAPTCHA Trình kích hoạt Dữ liệu được bảo vệ
CửaDash reCAPTCHA v3 + Cloudflare Phát hiện bot Thực đơn, giá cả, phí
Đồ ăn Uber Cloudflare Turnstile Truy cập tự động Danh sách nhà hàng, giá cả
Grubhub reCAPTCHA v2 Giới hạn tỷ lệ Thực đơn, khuyến mãi
Bạn cùng phòng Cloudflare Challenge Phát hiện cạo Phí giao hàng, ETA
chỉ cần ăn reCAPTCHA v2 Tìm kiếm lặp lại Dữ liệu nhà hàng
giỏ hàng tức thời reCAPTCHA v3 Phát hiện bot Giá tạp hóa

Công cụ so sánh giá đa nền tảng

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')}")

Đề xuất ủy quyền

Nền tảng Proxy tốt nhất tại sao
CửaDash Di động (4G) Phát hiện bot nặng, mong đợi trên thiết bị di động
Đồ ăn Uber Di động (4G) Nền tảng di động đầu tiên
Grubhub Khu dân cư Bảo vệ tiêu chuẩn
giỏ hàng tức thì Khu dân cư Phát hiện bot vừa phải
chỉ cần ăn Khu dân cư xoay vòng Đám mây tiêu chuẩn

Ứng dụng phân phối ưu tiên thiết bị di động - đa dạng nguồn yêu cầu có Tác nhân người dùng di động mang lại kết quả tốt nhất.


Điểm dữ liệu để theo dõi

Số liệu Giá trị doanh nghiệp
Giá các món trong thực đơn Phân tích ngang giá và chênh lệch giá
Phí giao hàng So sánh phí nền tảng
Số lượng đặt hàng tối thiểu Phân tích rào cản truy cập
Ước tính thời gian giao hàng So sánh mức độ dịch vụ
Khuyến mãi/discounts Thông tin tiếp thị
Tình trạng sẵn có của nhà hàng Phân tích phạm vi bảo hiểm

Khắc phục sự cố

Vấn đề Nguyên nhân Cách xử lý
Kết quả nhà hàng trống Vị trí không được cung cấp hoặc trang CAPTCHA Đặt mã zip địa chỉ giao hàng chính xác
Giá thực đơn khác với ứng dụng Sự khác biệt về giá trên web và ứng dụng Sử dụng UA di động để nhận được mức giá tương đương với ứng dụng
Vòng lặp thử thách Cloudflare Dấu vân tay không khớp Sử dụng đa dạng nguồn yêu cầu + UA di động
Nhà hàng được tìm thấy trên một nền tảng nhưng không tìm thấy trên nền tảng khác Phạm vi bảo hiểm khác nhau Đánh dấu là "không có sẵn" khi so sánh
Phí giao hàng không chính xác Định giá phụ thuộc vào vị trí Khớp địa lý proxy với vị trí mục tiêu

Câu hỏi thường gặp

Tại sao giá khác nhau giữa các nền tảng giao hàng?

Các nhà hàng đặt các mức giá khác nhau cho mỗi nền tảng để tính tỷ lệ hoa hồng khác nhau (15-30%). Phí giao hàng và phí dịch vụ cũng khác nhau tùy theo nền tảng.

Tôi nên sử dụng thiết bị di động hay máy tính để bàn để thu thập các ứng dụng phân phối?

Di động - đây là những nền tảng ưu tiên thiết bị di động. đa dạng nguồn yêu cầu với Tác nhân người dùng iPhone/Android tạo ra lưu lượng truy cập trông chân thực nhất.

Tôi nên so sánh giá bao lâu một lần?

Hàng tuần để phân tích thị trường chung. Hàng ngày trong thời gian khuyến mại hoặc chạy nước rút nghiên cứu cạnh tranh.


Hướng dẫn liên quan

  • Giám sát hàng tồn kho bán lẻ
  • đa dạng nguồn yêu cầu cho CAPTCHA
  • Ủy quyền dân cư luân phiên

So sánh giá giao đồ ăn trên quy mô lớn —lấy khóa CaptchaAI của bạnvà tự động hóa phân tích đa nền tảng.

Os comentários estão desativados para este artigo.