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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 13:12:28