Python使用BeautifulSoup提取网页JS生成的特定值方法
OLX动态页面内容提取可行方案
requests 发起的请求只会拿到服务端返回的初始静态HTML,不会执行页面内嵌的JavaScript代码,自然无法获取JS动态渲染生成的目标值,针对这个场景有三类可落地的实现方案,按实现成本从低到高排序如下:
方案1:逆向页面初始数据/接口(优先推荐,性能最高)
OLX这类站点不会把核心商品数据完全放在前端计算,绝大多数场景下:
- 商品全量字段会直接挂载在页面的全局JS变量中(常见命名如
window.__INITIAL_STATE__、window.__NEXT_DATA__),直接嵌在静态返回的HTML里,根本不需要执行JS就能拿到 - 少部分动态字段会在页面加载时通过XHR/fetch接口异步拉取
操作步骤:
- 打开浏览器开发者工具,切到Network面板,刷新页面后搜索目标值3143,就能定位到数据所在的位置
- 如果数据嵌在script标签的全局变量里,直接用正则提取JSON内容反序列化即可,示例代码:
import re import json import requests from bs4 import BeautifulSoup target_url = 'https://www.olx.bg/d/ad/podemnitsi-haspeli-tovarni-i-kuhnenski-asansori-motor-reduktori-CID1012-ID8pWNq.html' # 必须加正常浏览器的UA,否则会被OLX反爬拦截 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' } resp = requests.get(target_url, headers=headers) soup = BeautifulSoup(resp.text, 'html.parser') # 匹配存初始数据的script标签 data_script = soup.find('script', string=re.compile(r'window\.__INITIAL_STATE__')) if data_script: # 提取JSON串并解析 json_content = re.search(r'window\.__INITIAL_STATE__\s*=\s*({.*?});', data_script.string, re.S).group(1) full_data = json.loads(json_content) # 顺着数据结构逐层查找即可拿到目标值3143
这种方案的请求速度和你原来的requests脚本几乎一致,资源消耗极低。
方案2:用无头浏览器渲染页面(适配性最强,无需逆向)
如果找不到嵌入的静态数据、也没定位到对应接口,直接用可以执行JS的无头浏览器工具,等页面渲染完成后再提取内容即可,优先选playwright,配置简单、反爬检测命中率低:
- 先安装依赖:
pip install playwright playwright install chromium
- 核心实现代码:
from playwright.sync_api import sync_playwright from bs4 import BeautifulSoup target_url = 'https://www.olx.bg/d/ad/podemnitsi-haspeli-tovarni-i-kuhnenski-asansori-motor-reduktori-CID1012-ID8pWNq.html' with sync_playwright() as p: # 启动无界面Chromium浏览器 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/126.0.0.0 Safari/537.36') # 等待页面网络空闲,所有JS执行完成再拿内容 page.goto(target_url, wait_until='networkidle') rendered_html = page.content() browser.close() # 这时候拿到的就是渲染完成的完整HTML,和你在浏览器里看到的内容一致 soup = BeautifulSoup(rendered_html, 'html.parser') # 直接用你之前写的选择器逻辑提取目标值3143即可
如果觉得playwright依赖太重,也可以换requests-html这类轻量封装的库,不过稳定性不如playwright。
方案3:本地执行JS逻辑(性能优先场景可选)
如果目标值是前端通过固定算法计算生成、既不嵌在初始数据里也没有独立接口,可以把对应计算逻辑的JS代码抠出来,用PyExecJS这类库在本地Python环境里执行拿到结果。但这种方案维护成本很高,页面前端代码一改版就会失效,非极端性能要求场景不推荐使用。
注意:OLX有基础反爬机制,无论用哪种方案,都不要高频发起请求,否则会触发验证码或者IP封禁,测试阶段建议加随机延时。
内容的提问来源于stack exchange,提问作者pewocis495
相关产品推荐
相关产品推荐

