使用BeautifulSoup+lxml XPath解析Sephora/Ulta无输出,Selenium正常
问题原因及解决方案
核心原因
Sephora和Ulta这类电商网站的商品价格等数据是通过JavaScript动态渲染生成的:
- 用
requests/ureq直接获取的是服务器返回的静态HTML源码,里面根本没有你XPath定位的那个动态生成的ID节点(比如1b7a3ab3-2765-4ee2-8367-c8a0e7230fa4),自然拿不到数据。 - Selenium是模拟真实浏览器加载页面,会自动执行页面中的JavaScript,渲染出完整的DOM结构,所以能找到对应的节点。
另外你的BeautifulSoup代码存在冗余:同时用了requests.get和ureq请求页面,重复获取资源;而且把soup转成字符串再用et.HTML解析,完全没必要,直接用lxml处理响应内容更高效,但这不是核心问题。
可行解决方案
1. 优化浏览器自动化方案(你当前的Selenium方式)
把固定的time.sleep换成WebDriverWait显式等待,避免不必要的等待时间,同时提升稳定性:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By lst=[] urls=df['product_url'] for url in urls[:599]: driver.get(url) try: # 等待元素可见,最多等5秒 prize = WebDriverWait(driver, 5).until( EC.visibility_of_element_located((By.XPATH, '//*[@id="1b7a3ab3-2765-4ee2-8367-c8a0e7230fa4"]/span')) ).text except Exception as e: prize = None print(f"获取{url}价格失败: {e}") lst.append([prize])
2. 直接调用API接口(推荐)
打开浏览器开发者工具(F12),切换到「网络」标签,刷新商品页面,筛选XHR/fetch请求,找到返回商品价格数据的接口。比如:
- Sephora的商品数据通常来自
/api/v3/products/{skuId}这类接口,请求时需要带上必要的请求头(比如User-Agent、Authorization等)。 - Ulta的商品详情接口一般包含在商品页面的初始化请求里,或者单独的商品数据接口。
直接用requests调用这些接口,能快速拿到结构化数据,比爬页面效率高很多。
3. 模拟JS渲染(备选)
如果不想用浏览器自动化,可以用Pyppeteer(无头浏览器)或Splash(渲染服务)来执行页面JS,获取渲染后的HTML再解析,但配置和维护成本比前两种方案高。
内容的提问来源于stack exchange,提问作者THASNI HAKEEM
相关产品推荐
相关产品推荐

