无需无头浏览器,如何用Python执行JS查询提取Highcharts数据?
提取Highcharts数据的替代方案(无需Selenium/PhantomJS)
一、修正requests_html的用法(解决AttributeError)
你之前的代码错误在于直接调用session.html,HTMLSession实例本身没有html属性,正确流程是先发起请求获取响应对象,再调用响应的render()方法执行脚本。
正确代码示例:
from requests_html import HTMLSession # 初始化会话(如果需要登录,先通过session.post完成登录) session = HTMLSession() # 请求目标页面 response = session.get('https://www.highcharts.com/demo/line-basic') # 渲染页面并执行脚本提取数据 values = response.render(script=''' let values = []; Highcharts.charts[0].series[0].data.forEach(d => values.push(d.y)); return values; ''') print(values)
二、最优方案:直接抓取数据源(无需执行JS)
Highcharts的数据通常要么嵌入在页面的JavaScript变量中,要么通过后端API接口返回,这两种方式都不需要执行JS,效率远高于无头浏览器。
1. 从页面源码提取嵌入数据
打开目标页面的源码,搜索series、data等关键词,找到存储图表数据的代码块,用正则表达式提取:
import re import json from requests_html import HTMLSession session = HTMLSession() # 若需登录,先执行session.post登录逻辑 response = session.get('https://www.highcharts.com/demo/line-basic') # 匹配series中的data数组 pattern = re.compile(r'series:\s*\[\s*\{\s*name:\s*\'[^\']+\'\s*,\s*data:\s*(\[[^\]]+\])') match_result = pattern.search(response.text) if match_result: data = json.loads(match_result.group(1)) print(data) # 输出:[7.0, 6.9, 9.5, 14.5, 18.4, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
2. 直接调用后端API
如果图表数据是通过AJAX请求获取的,打开浏览器开发者工具的网络面板,筛选XHR/Fetch请求,找到返回图表数据的API接口,直接用requests请求该接口(需带上登录后的会话Cookie)。
三、轻量无头浏览器:Pyppeteer
如果上述方法都不可行,可以用Pyppeteer(基于Chrome DevTools协议,比Selenium轻量):
import asyncio from pyppeteer import launch async def extract_highcharts_data(): # 启动无头浏览器 browser = await launch(headless=True, args=['--no-sandbox']) page = await browser.newPage() # 处理登录(示例逻辑,需替换为目标网站的登录步骤) # await page.goto('https://目标网站登录页') # await page.type('#username-input', '你的用户名') # await page.type('#password-input', '你的密码') # await page.click('#submit-login') # await page.waitForNavigation() # 访问目标页面 await page.goto('https://www.highcharts.com/demo/line-basic') # 执行脚本提取数据 values = await page.evaluate(''' let values = []; Highcharts.charts[0].series[0].data.forEach(d => values.push(d.y)); return values; ''') print(values) await browser.close() # 运行异步函数 asyncio.get_event_loop().run_until_complete(extract_highcharts_data())
内容的提问来源于stack exchange,提问作者MaxFrost
相关产品推荐
相关产品推荐

