某速体育网站中canvas数据获取

数据使用canvas渲染出来的。

针对*速体育这种用 Canvas 渲染数字的反爬方案,我给你提供 4 种从易到难的逆向方法,其中Hook Canvas API 是通用杀招,不需要分析接口加密,100% 能拿到和页面显示完全一致的数据。
核心原理
所有 Canvas 绘制的文字,最终都必须通过浏览器标准 API
CanvasRenderingContext2D.prototype.fillText(text, x, y) 来渲染。无论网站怎么加密数据、混淆 JS,只要它要显示文字,就绕不开这个 API。我们只需要拦截这个函数,就能直接拿到绘制的内容。方法一:Hook Canvas API(最推荐,通用所有 Canvas 反爬)
步骤 1:注入 Hook 代码(Chrome 浏览器直接用)
- 打开开发者工具(F12)→ 切换到 Sources 面板 → 点击左侧 Snippets(代码片段)
- 新建一个片段,粘贴下面的代码,按
Ctrl+Enter运行
javascript
// 保存原始的fillText方法
const originalFillText = CanvasRenderingContext2D.prototype.fillText;
// 重写fillText方法,拦截所有绘制的文字
CanvasRenderingContext2D.prototype.fillText = function(text, x, y) {
// 将绘制的文字存到Canvas元素的自定义属性上
this.canvas.dataset.renderedText = text;
// 调用原始方法,保证页面正常显示
return originalFillText.call(this, text, x, y);
};
console.log('✅ Canvas文字拦截Hook已生效');
步骤 2:一键提取所有赔率数据
运行 Hook 代码后,刷新页面(或切换标签页让 Canvas 重新渲染),然后在 Console 面板执行这行代码:
javascript
// 专门针对雷速体育的赔率提取
const oddsData = Array.from(document.querySelectorAll('span[class*="exponent"] canvas'))
.map(canvas => ({
赔率数值: canvas.dataset.renderedText,
时间节点: canvas.closest('tr').querySelector('td:first-child')?.textContent?.trim(),
涨跌: canvas.parentElement.classList.contains('exponent-up') ? '涨' : '跌'
}))
.filter(item => item.赔率数值); // 过滤空Canvas
console.table(oddsData);
你会直接得到一个格式化的表格,包含所有时间点的赔率数据。
自动化集成(Python+Playwright)
如果需要写爬虫批量获取,直接把 Hook 代码注入到页面初始化阶段即可,不需要 OCR,速度极快:
python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
# 页面加载前注入Hook,一劳永逸
page.add_init_script("""
const originalFillText = CanvasRenderingContext2D.prototype.fillText;
CanvasRenderingContext2D.prototype.fillText = function(text, x, y) {
this.canvas.dataset.renderedText = text;
return originalFillText.call(this, text, x, y);
};
""")
# 打开目标比赛页面
page.goto("https://www.leisu.com/match/你的比赛ID")
page.wait_for_selector("canvas")
# 提取数据
data = page.evaluate("""
() => Array.from(document.querySelectorAll('span[class*="exponent"] canvas'))
.map(c => ({
value: c.dataset.renderedText,
time: c.closest('tr').cells[0].textContent.trim()
}))
""")
print(data)
browser.close()
方法二:抓包获取原始接口数据(最稳定,适合大规模爬虫)
这是最根本的方法,直接获取网站后端返回的原始赔率数据,不需要解析前端。
具体步骤
- 打开 Network 面板 → 勾选 Preserve log(保留日志)→ 过滤 Fetch/XHR
- 刷新页面,观察请求 URL,雷速体育的赔率接口通常是:
https://api.leisu.com/api/odds/detail/比赛IDhttps://api.leisu.com/api/match/odds/history/比赛ID
- 查看响应内容,你会发现 JSON 里直接有
odds、exponent、change等字段,对应页面上的所有赔率和涨跌数据
注意事项
- 请求需要携带正确的
User-Agent、Referer和Cookie - 部分接口可能有签名参数(如
sign、timestamp),如果遇到加密,优先用上面的 Hook 方法 - 接口有频率限制,建议添加 1-2 秒的随机延迟
方法三:OCR 识别(快速验证,最简单)
如果只是临时需要少量数据,可以用 OCR 直接识别 Canvas 图片,准确率接近 100%(因为是标准数字字体)。
Python 示例代码
python
from selenium import webdriver
from PIL import Image
import pytesseract
import io
driver = webdriver.Chrome()
driver.get("https://www.leisu.com/match/你的比赛ID")
# 识别所有Canvas
for canvas in driver.find_elements("tag name", "canvas"):
# 直接截取Canvas元素的截图
img = Image.open(io.BytesIO(canvas.screenshot_as_png))
# 只识别数字和小数点,提高准确率
text = pytesseract.image_to_string(
img,
config="--psm 8 --oem 3 -c tessedit_char_whitelist=0123456789."
)
print(text.strip())
方法四:逆向 JS 代码(最彻底,难度最高)
如果需要深度定制爬虫,可以逆向网站的混淆 JS,找到数据处理的完整流程:
- 全局搜索
fillText或canvas,找到绘图函数的位置 - 在绘图函数处打上断点,刷新页面触发断点
- 向上追溯调用栈,找到传入的文字参数的来源
- 继续追溯到接口请求和解密函数,写出对应的 Python 解密代码
针对*速体育的提示
- 混淆代码主要在
feilin010.xxx.js和fp_min.js中 - 可以用
js-beautify先解混淆,再搜索关键词odds、exponent
注意事项
- 法律风险:本方法仅供学习研究使用,爬取数据请遵守《网络安全法》和网站的 robots 协议,不要用于商业用途
- 反爬规避:雷速体育有 IP 封禁和行为检测,不要高频请求,建议使用代理池
- 稳定性对比:
方法 难度 速度 稳定性 通用性 Hook Canvas 低 极快 极高 所有 Canvas 网站 接口抓包 中 极快 高 有公开接口的网站 OCR 识别 极低 慢 中 所有可视化内容 JS 逆向 高 极快 极高 特定网站

浙公网安备 33010602011771号