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
相关产品推荐
相关产品推荐

