
本文详解为何 `find_all(class_="side_categories")` 返回单个 `
当你调用 soup.find_all(class_="side_categories") 时,Beautiful Soup 确实返回了一个 ResultSet(本质是类列表对象),但它只包含一个匹配的 要获取所有分类链接(即 标签),需进一步在该容器内查找目标元素。以下是两种推荐做法: 通过以上任一方法,你将获得真正的可迭代链接列表,轻松完成后续数据采集任务。核心原则是:先定位容器,再聚焦目标;避免对容器本身调用 find_all,而应在容器内查找子元素。✅ 方法一:使用 CSS 选择器(推荐,简洁高效)
from bs4 import BeautifulSoup
import requests
url = "http://books.toscrape.com/"
page = requests.get(url)
soup = BeautifulSoup(page.text, "html.parser")
# 直接定位所有位于 .side_categories 内的 标签(层级更精确)
for link in soup.select('.side_categories li a'):
href = link.get('href')
if href: # 防止 None 值
full_url = url.rstrip('/') + '/' + href.lstrip('/')
print(full_url)
✅ 方法二:链式查找(语义清晰,易理解)
# 先找到容器,再在其内部查找所有 标签
side_nav = soup.find(class_='side_categories')
if side_nav:
for link in side_nav.find_all('a'):
href = link.get('href')
if href:
full_url = url.rstrip('/') + '/' + href.lstrip('/')
print(full_url)
⚠️ 注意事项:find() 返回单个 Tag 对象(或 None),而 find_all() 返回 ResultSet(可迭代);使用 select() 或 find_all() 时,务必确认选择器路径是否准确(如 .side_categories li a 表示“class 为 side_categories 的元素下的所有 li 中的 a”);处理 href 时建议做空值检查(link.get('href') 可能为 None),并规范化 URL 拼接(避免双斜杠 //);若需提取分类名称(如 “Travel”, “Mystery”),可用 link.get_text(strip=True) 替代 link.get('href')。










