You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

抓取动态彩票结果表格遇问题:解析结果不一致

问题分析与解决方案

问题背景

尝试抓取https://star49s.com/results/teatime的下午茶时段彩票开奖结果,使用requests+BeautifulSoup时出现以下异常:

  • 有时能正常获取最新结果
  • 有时会跳过部分行
  • 偶尔重新运行脚本出现重复条目

当前代码:

import requests
from bs4 import BeautifulSoup

url = "https://star49s.com/results/teatime"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")

results = []
for row in soup.select("div.results-row"):
    numbers = [num.get_text(strip=True) for num in row.select("span.ball")]
    date = row.select_one("span.date").get_text(strip=True) if row.select_one("span.date") else None
    if numbers:
        results.append({"date": date, "numbers": numbers})

print(results)

核心原因排查

  1. 动态内容渲染:页面可能通过JavaScript异步加载结果(比如滚动加载、AJAX拉取数据),requests只能获取初始HTML,无法执行JS,导致部分行未被抓取到。
  2. 服务器缓存/动态内容:服务器可能返回缓存内容或根据请求头动态调整响应,导致多次请求结果不一致。
  3. 选择器精度不足:div.results-row可能不是最精准的选择器,页面中可能存在隐藏的重复行或未完全加载的行被选中。

解决方案

方案1:优先尝试无浏览器的优化(推荐先验证)

如果页面数据是通过AJAX加载的,直接调用API比解析HTML更可靠:

  • 打开浏览器开发者工具(F12),切换到Network标签,刷新页面,筛选XHR/Fetch请求,查找返回开奖结果的API接口(通常是JSON格式)。
  • 找到后,直接用requests调用该API,解析JSON数据,无需处理HTML。

如果必须解析HTML,优化现有代码:

import requests
from bs4 import BeautifulSoup
from datetime import datetime

# 模拟浏览器请求头,避免被识别为爬虫
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

url = "https://star49s.com/results/teatime"
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()  # 抛出请求错误,避免静默失败
soup = BeautifulSoup(response.text, "html.parser")

results = []
# 用更精准的选择器,结合父容器缩小范围
for row in soup.select("div.results-container div.results-row"):
    date_elem = row.select_one("span.date")
    numbers_elems = row.select("span.ball")
    # 确保日期和号码都存在才添加,过滤不完整条目
    if date_elem and numbers_elems:
        date = date_elem.get_text(strip=True)
        numbers = [num.get_text(strip=True) for num in numbers_elems]
        results.append({"date": date, "numbers": numbers})

# 基于日期去重,避免重复条目
unique_results = {}
for item in results:
    unique_results[item["date"]] = item
results = list(unique_results.values())

# 按日期倒序排序,确保最新结果在前
results.sort(key=lambda x: datetime.strptime(x["date"], "%d/%m/%Y"), reverse=True)

print(results)

优化点说明:

  • 添加浏览器请求头,避免被服务器拦截或返回差异化内容
  • 增加请求错误处理,及时发现请求失败问题
  • 用更精准的选择器,减少误选隐藏或未加载的行
  • 增加数据校验,只保留完整的条目
  • 基于日期去重,解决重复条目问题
  • 按日期排序,保证结果顺序符合预期

方案2:使用无头浏览器(当方案1无效时)

如果页面确实是完全动态渲染(比如结果由JS生成,无API接口),则需要使用Selenium或Playwright执行JS:

Playwright示例(轻量高效,推荐)

from playwright.sync_api import sync_playwright
from datetime import datetime

results = []
with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
    # 等待网络空闲,确保所有动态内容加载完成
    page.goto("https://star49s.com/results/teatime", wait_until="networkidle")
    
    # 滚动到页面底部,触发可能的滚动加载逻辑
    page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
    page.wait_for_timeout(1000)  # 等待加载完成
    
    rows = page.query_selector_all("div.results-row")
    for row in rows:
        date = row.query_selector("span.date")
        numbers = row.query_selector_all("span.ball")
        if date and numbers:
            date_text = date.text_content().strip()
            numbers_list = [num.text_content().strip() for num in numbers]
            results.append({"date": date_text, "numbers": numbers_list})
    
    browser.close()

# 去重+排序,保证数据唯一性和顺序
unique_results = {}
for item in results:
    unique_results[item["date"]] = item
results = list(unique_results.values())
results.sort(key=lambda x: datetime.strptime(x["date"], "%d/%m/%Y"), reverse=True)

print(results)

确保数据可靠的额外措施

  • 持久化存储:将抓取到的结果存储到本地文件(如JSON、CSV)或数据库,每次抓取后对比已有数据,只新增未存在的条目。
  • 重试机制:对请求失败或数据不完整的情况,添加重试逻辑(比如使用tenacity库)。
  • 定时监控:如果需要定期抓取,设置定时任务,并添加告警(如数据连续多次异常时通知)。

内容的提问来源于stack exchange,提问作者Zuryab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 11:27:21