DEV Community

Taocarts
Taocarts

Posted on

Defeating Yahoo Japan Auctions Anti-Scraping: Implementing Millisecond-Level Product Monitoring with Python

Recently, I worked on a cross-border e-commerce data monitoring project that required real-time collection of product information from Yahoo Japan Auctions—including current bids, remaining time, number of bidders, and other key fields. This type of data is critical for price surveillance and bidding strategy analysis. However, Yahoo’s anti-scraping mechanisms are quite stringent.

Technical Challenges
┌─────────────────────────────────────────────────────────┐
│ 数据采集架构 │
├─────────────────────────────────────────────────────────┤
│ 调度层 → Celery Beat 定时触发(每30秒) │
│ 采集层 → Playwright + asyncio 异步并发 │
│ 解析层 → 抓包分析API接口,直接解析JSON │
│ 存储层 → MongoDB(商品数据)+ Redis(去重缓存) │
│ 代理层 → 住宅代理池动态轮换 │
└─────────────────────────────────────────────────────────┘

In actual testing, sending requests with the requests library returned HTML that contained no product price data—the page is dynamically rendered with JavaScript, so a basic scraper only gets empty values. Worse, making too many requests in a short period triggers IP bans, returning 403 errors.

Solution Architecture

We chose Playwright over Selenium mainly because it requires no manual driver configuration and offers more stable support for dynamically rendered pages.

Core Code Implementation
Simulating login and obtaining session state:
`from playwright.sync_api import sync_playwright
import json

def yahoo_login(username: str, password: str):
"""模拟登录日本雅虎,返回登录后的上下文"""
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
context = browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
)
page = context.new_page()
page.goto("https://login.yahoo.co.jp/")
page.fill('input[name="login"]', username)
page.fill('input[name="passwd"]', password)
page.click('button[type="submit"]')
page.wait_for_load_state("networkidle")

    cookies = context.cookies()
    with open("yahoo_cookies.json", "w") as f:
        json.dump(cookies, f)
    return context`
Enter fullscreen mode Exit fullscreen mode

Packet capture analysis to identify the real data API endpoints:
`import requests
import random
import time

def fetch_auction_data(item_id: str, cookies: dict):
"""通过API接口获取商品实时数据"""
url = f"https://auctions.yahoo.co.jp/api/v1/items/{item_id}"
proxies = get_proxy() # 代理池动态轮换
headers = {
"User-Agent": random.choice(UA_POOL),
"Referer": f"https://auctions.yahoo.co.jp/item/{item_id}"
}
response = requests.get(url, headers=headers, proxies=proxies, cookies=cookies)
return response.json()`
Lessons Learned

Yahoo Japan is extremely sensitive to request frequency. In practice, we found that a single IP making more than 30 requests within 60 seconds will trigger a temporary ban. Our solution is to maintain a proxy pool of no fewer than 50 residential proxies, combined with random delays (1–3 seconds) and request deduplication.

This setup has been running stably in production for three months, collecting an average of over 100,000 product data records per day. The Yahoo Japan bidding module of the Bidfans system is built on a similar data collection architecture, enabling real-time synchronization of auction listings. Whether you are running a Japan-based shopping proxy service or a Yahoo bidding assistant, reliable data collection is a fundamental infrastructure requirement.

Food for thought: What anti-scraping measures have you encountered in cross-border e-commerce data collection? Feel free to share your approaches.

Top comments (0)