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

BeautifulSoup按id查找元素返回None无法提取标的价格问题

问题根本原因

代码返回None是因为requests拿到的初始HTML响应里,根本不存在id="bid"的span节点:

  • XTB的实时行情价格不是写在首次返回的静态HTML里的,页面在浏览器加载时,会先返回基础页面骨架,等JS运行后再调用异步接口拉取价格数据,动态渲染到页面对应位置。requests只能拿到初始的静态代码,不会执行页面内的JavaScript,自然找不到动态生成的价格元素。
  • 这类金融行情站点都有基础反爬校验,不带正常请求头的裸requests请求大概率会被识别为爬虫,返回验证页或者错误页,和浏览器正常打开看到的内容完全不一样。
可行解决方案

二选一即可:

  • 直接抓异步数据接口:打开浏览器开发者工具,切到「网络」面板,筛选Fetch/XHR类型的请求,刷新页面后找到返回bid/ask实时价格的接口,直接用requests请求这个接口拿结构化JSON数据就行,这种方式效率最高,也不需要解析HTML。注意请求时要带上和浏览器一致的User-Agent等请求头,避免被拦截。
  • 用支持JS渲染的爬虫工具:如果一定要从渲染后的页面提取元素,可以换用playwright、selenium这类能模拟浏览器运行、自动执行页面JS的工具,等页面完全加载、价格渲染完成后,再定位目标元素提取内容。

基于playwright的参考实现:

from playwright.sync_api import sync_playwright

def get_price(instrument):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        page.goto(f"https://www.xtb.com/pl/oferta/dostepne-rynki/indeksy/{instrument}")
        # 等待价格元素加载完成再提取内容
        bid_elem = page.wait_for_selector("#bid")
        print(f"{instrument} 买入价:{bid_elem.inner_text()}")
        browser.close()

if __name__ == "__main__":
    get_price("us100")

爬取站点数据请遵守目标站点相关规则及当地法律法规,不要发起高频请求影响站点正常服务。

内容的提问来源于stack exchange,提问作者Darek Kaczyński

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:21:25