You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用BeautifulSoup爬取O'Reilly书籍页面描述时,CSS选择器返回空列表的问题排查

解决O'Reilly商城书籍描述爬取返回空列表的问题

我来帮你分析下你遇到的这个问题——用BeautifulSoup爬取O'Reilly指定书籍页面的描述时,各种CSS选择器都返回空列表,大概率是以下几个原因导致的:

1. 页面内容是动态加载的

你用requests.get()获取的是服务器返回的静态HTML,但很多电商网站会用JavaScript动态渲染页面内容(比如书籍描述、评论这类模块)。浏览器审查元素看到的是渲染后的DOM结构,而静态HTML里根本没有你要找的div.description这类元素,所以BeautifulSoup自然查不到。

你可以先把返回的页面内容保存下来验证:

with open('oreilly_page.html', 'w', encoding='utf-8') as f:
    f.write(req.text)

打开这个HTML文件,搜索"description"相关内容,如果找不到目标段落,就说明是动态加载的问题。

2. 请求被网站反爬机制拦截

O'Reilly的商城可能会检测请求的来源,如果你的请求没有带浏览器的User-Agent头,服务器可能返回一个简化版页面或者反爬页面,导致你获取的内容不完整。

解决方法是给请求添加模拟浏览器的请求头:

import requests
from bs4 import BeautifulSoup

link = 'http://shop.oreilly.com/product/0636920028154.do'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}
req = requests.get(link, headers=headers)
bs = BeautifulSoup(req.text, 'html.parser')
# 再尝试用你的选择器查询

3. CSS选择器对应静态HTML的结构和渲染后不一致

浏览器审查元素看到的DOM是经过JavaScript修改后的结构,而静态HTML的原始结构可能完全不同。比如你看到的div.description:nth-child(2)在静态HTML里可能是另一种嵌套关系,或者标签名、class/id不一样。

这种情况下,你需要打开刚才保存的静态HTML文件,手动查找书籍描述所在的标签,重新编写正确的CSS选择器。

针对动态加载的解决方案

如果确认是动态加载导致的,你需要用可以模拟浏览器渲染的工具,比如Selenium或者Playwright,这里给你一个Selenium的示例:

from selenium import webdriver
from bs4 import BeautifulSoup
import time

link = 'http://shop.oreilly.com/product/0636920028154.do'
# 初始化Chrome浏览器
driver = webdriver.Chrome()
driver.get(link)
time.sleep(2)  # 等待页面动态内容加载完成
# 获取渲染后的页面源码
soup = BeautifulSoup(driver.page_source, 'html.parser')
# 尝试查询目标元素
description = soup.select_one('div.description:nth-child(2) > span:nth-child(2)')
if description:
    print(description.get_text(strip=True))
# 关闭浏览器
driver.quit()

内容的提问来源于stack exchange,提问作者Stephan Psaras

火山引擎 最新活动