BeautifulSoup findAll爬取沃尔玛页面价格返回零结果问题
问题原因
- 价格数据为客户端动态渲染内容:你发起请求拿到的静态HTML源码中不存在对应类名的div节点,这类价格节点是页面加载完成后,由JavaScript调用后端接口获取价格数据后动态生成的,BeautifulSoup仅能解析静态HTML内容,自然无法匹配到目标节点。
- 类名稳定性极低:你使用的带
css-前缀的类名是前端CSS Modules方案编译生成的,平台代码迭代时会随机调整这类类名,依赖这类类名做提取逻辑的兼容性极差。
可行解决方案
方案1:提取静态页内嵌的初始化数据(性能最优,推荐)
沃尔玛页面会把首次加载的商品全量数据预置到页面的<script>标签的全局JSON变量中,不需要依赖动态渲染,直接从静态源码中提取即可,示例代码如下:
from urllib.request import Request, urlopen import re import json header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:77.0) Gecko/20100101 Firefox/77.0'} url = "https://www.walmart.ca/search?q=lettuce" req = Request(url = url, headers = header) client = urlopen(req) pageHtml = client.read().decode('utf-8') client.close() # 正则匹配页面内嵌的初始化数据 data_match = re.search(r'window\.__INITIAL_STATE__ = (.*?);<', pageHtml) if data_match: raw_data = data_match.group(1) data = json.loads(raw_data) # 提取商品列表数据,路径可根据实际数据结构调整 products = data['search']['searchResult']['itemStacks'][0]['items'] for product in products: print(f"商品名:{product['name']},价格:{product['price']['currentPrice']}")
方案2:使用支持JS渲染的爬取工具
如果需要模拟真实浏览器行为获取动态渲染后的节点,可以使用Selenium、Playwright等工具,等页面资源加载完成后再提取对应节点即可。
内容的提问来源于stack exchange,提问作者skushu
相关产品推荐
相关产品推荐

