如何使用 Beautiful Soup 正确提取网页中的所有分类链接

16次阅读

如何使用 Beautiful Soup 正确提取网页中的所有分类链接

本文详解为何 `find_all(class_=”side_categories”)` 返回单个 `

` 而非预期的链接列表,并提供两种可靠方法(css 选择器与嵌套 `find`/`find_all`)精准定位并提取图书网站的所有分类 url。

当你调用 soup.find_all(class_=”side_categories”) 时,Beautiful Soup 确实返回了一个 ResultSet(本质是类列表对象),但它只包含一个匹配的

元素——因为整个页面中该 class 仅出现一次。这个

是分类导航的容器,而非你要的每个分类链接本身。因此你看到的是一个包裹了完整嵌套 html 的单元素列表,而非可直接遍历的 标签集合。

要获取所有分类链接(即 标签),需进一步在该容器内查找目标元素。以下是两种推荐做法:

✅ 方法一:使用 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’)。

通过以上任一方法,你将获得真正的可迭代链接列表,轻松完成后续数据采集任务。核心原则是:先定位容器,再聚焦目标;避免对容器本身调用 find_all,而应在容器内查找子元素。

text=ZqhQzanResources