news 2026/6/16 4:48:49

Python 爬虫项目:网页解析之 BeautifulSoup 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫项目:网页解析之 BeautifulSoup 实战

前言

完成网络请求后,拿到完整网页源码只是第一步,从繁杂的 HTML 文本中精准提取目标数据,是爬虫核心环节之一。BeautifulSoup是 Python 生态中经典的 HTML/XML 解析库,语法简洁、上手简单,依托 CSS 选择器、标签层级查找、属性筛选等能力,可快速定位页面元素、提取文本、链接、图片地址等内容,非常适合新手入门网页解析。

结合前文requests请求能力,请求 + 解析构成静态爬虫标准工作流。本章从零讲解 BeautifulSoup 安装、对象结构、核心查询语法、实战筛选规则,搭配大量可运行案例,覆盖标签查找、属性提取、文本获取、节点遍历等常用场景,同时总结解析易错点与优化技巧。

参考文档链接:

  1. BeautifulSoup 官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/
  2. lxml 解析器说明:https://lxml.de/
  3. 在线 HTML 调试工具:https://html-online.com/editor/

一、环境安装与解析器选择

1.1 库安装

BeautifulSoup 不属于 Python 内置库,需通过 pip 安装,同时推荐搭配lxml解析器(速度快、容错性强,工业级首选)。

shell

# 安装 BeautifulSoup4 pip install beautifulsoup4 # 安装 lxml 解析器(必装,推荐) pip install lxml

备选解析器:html.parser(Python 内置,无需额外安装,兼容性好但速度偏弱)。

1.2 基础导入与初始化

解析流程固定:请求获取网页源码 → 传入 BeautifulSoup 构建解析对象 → 调用方法查询元素。 基础语法:

python

运行

from bs4 import BeautifulSoup import requests # 1. 发起请求获取网页 url = "https://httpbin.org/html" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0.0.0 Safari/537.36"} resp = requests.get(url, headers=headers, timeout=5) resp.encoding = "utf-8" html = resp.text # 2. 构建 BeautifulSoup 解析对象 # 参数1:网页源码字符串;参数2:指定解析器 soup = BeautifulSoup(html, "lxml") # 格式化输出完整网页(自动补全标签、排版) print(soup.prettify())
关键说明
  1. prettify():格式化 HTML 代码,自动换行、缩进,方便查看页面结构;
  2. 解析器优先级:lxml> 内置html.parser,正式项目统一使用 lxml;
  3. 若网页存在残缺、不规范标签,lxml 会自动容错修复。

二、BeautifulSoup 四大核心对象

解析后页面会被拆解为四类对象,理解对象类型是灵活解析的基础。

2.1 Tag 标签对象

HTML 中的标签(<div><a><p><img>等)对应 Tag 对象,可获取标签名、属性、内部文本

python

运行

# 获取第一个 <h1> 标签 h1_tag = soup.h1 # 标签名称 print("标签名:", h1_tag.name) # 标签所有属性(字典格式) print("标签属性:", h1_tag.attrs)

2.2 NavigableString 字符串对象

标签内部的文本内容,属于 NavigableString 对象,直接取值即可拿到纯文本。

python

运行

# 获取标签内文本 text = soup.h1.string print("标签文本:", text)

2.3 BeautifulSoup 文档对象

整个网页文档本身就是 BeautifulSoup 对象,可视作根节点,所有查找操作都基于该对象发起。

2.4 Comment 注释对象

HTML 注释内容<!-- 注释 -->会被识别为 Comment 对象,解析时注意区分,避免误提取注释文本。

三、基础节点查找(简易用法)

通过soup.标签名可快速获取页面第一个匹配标签,适合结构简单、唯一标签的场景。

3.1 直接通过标签名查找

python

运行

# 获取页面第一个 a 标签 a_tag = soup.a print("a标签完整内容:", a_tag) # 获取a标签文本 print("a标签文本:", a_tag.string) # 获取a标签 href 属性 print("链接地址:", a_tag.get("href")) # 嵌套标签查找:逐层定位 body = soup.body p = body.p print("p标签文本:", p.string)

3.2 属性获取两种写法

  1. 标签.get("属性名"):推荐写法,属性不存在返回None,不会报错;
  2. 标签["属性名"]:字典取值写法,属性不存在直接抛异常。

python

运行

tag = soup.a print(tag.get("href")) print(tag["href"])

四、重点:find 与 find_all 精准查找

find()find_all()是项目中使用频率最高的方法,支持按标签、属性、文本多条件筛选,可匹配单个 / 多个元素。

4.1 find ():查找第一个匹配元素

语法:soup.find(name=None, attrs={}, text=None)

  • 只返回第一个符合条件的 Tag,无匹配返回None
4.1.1 按标签名查找

python

运行

# 查找第一个 p 标签 p = soup.find("p") print(p.text)
4.1.2 按标签 + 属性查找

支持单属性、多属性筛选,适配带 class、id 的标签。

python

运行

# 查找 class 为 "title" 的 div 标签 div = soup.find("div", class_="title") # 注意:class 是 Python 关键字,语法改为 class_ # 多属性联合筛选 tag = soup.find("a", attrs={"href": "/index.html", "target": "_blank"})
4.1.3 按文本内容查找

根据标签内的文字匹配节点:

python

运行

# 查找文本包含 "Hello" 的标签 tag = soup.find(text="Hello World") print(tag)

4.2 find_all ():查找所有匹配元素

语法同 find (),返回列表,包含全部符合条件的标签,无匹配返回空列表。

4.2.1 基础用法:批量获取同类型标签

python

运行

# 获取页面所有 a 标签 a_list = soup.find_all("a") print(f"共找到 {len(a_list)} 个链接") # 遍历提取所有链接与文本 for a in a_list: link = a.get("href") text = a.get_text(strip=True) # strip=True 去除首尾空格、换行 print(f"文本:{text} 链接:{link}")
4.2.2 多标签同时查找

传入列表,一次性匹配多种标签:

python

运行

# 同时查找所有 p 标签和 h2 标签 tags = soup.find_all(["p", "h2"]) for t in tags: print(t.text.strip())
4.2.3 限制返回数量

通过limit参数控制返回标签个数:

python

运行

# 只取前 2 个 a 标签 a_list = soup.find_all("a", limit=2) print(a_list)

4.3 文本提取:text /get_text ()

两种方式均可提取标签内所有文本,嵌套标签也会合并内容:

  1. 标签.string:仅标签内纯文本,嵌套子标签时返回 None;
  2. 标签.text/标签.get_text():提取当前标签 + 所有子标签的全部文本;
  3. strip=True:自动清除换行、空格、制表符,数据清洗必备。

python

运行

tag = soup.find("div") # 清除空白字符后提取文本 content = tag.get_text(strip=True) print(content)

五、CSS 选择器 select(推荐主流用法)

select()方法依托 CSS 选择器语法定位元素,语法直观、和前端通用,复杂页面优先使用 select,是目前行业主流解析方案。

语法:soup.select("CSS选择器")

  • 永远返回列表,匹配不到则返回空列表

5.1 常用选择器规则与实战

5.1.1 标签选择器

直接写标签名,匹配所有对应标签:

python

运行

# 选择所有 p 标签 res = soup.select("p") for item in res: print(item.text.strip())
5.1.2 class 类选择器

语法:.类名

python

运行

# 选择 class="news" 的所有标签 news_list = soup.select(".news")
5.1.3 id 选择器

语法:#id名

python

运行

# 选择 id="main" 的标签 main_tag = soup.select("#main") print(main_tag[0].text.strip())
5.1.4 属性选择器

语法:标签[属性=值],精准匹配带指定属性的标签,常用于提取链接、图片:

python

运行

# 选择所有 href 属性为指定值的 a 标签 a_tags = soup.select('a[href="/about"]') # 提取所有图片地址 img_tags = soup.select("img") for img in img_tags: img_url = img.get("src") print("图片链接:", img_url)
5.1.5 层级选择器(父子 / 后代)
  • 空格分隔:后代选择器(所有下级节点)
  • >分隔:直接子节点(仅一级子标签)

python

运行

# 查找 div 内部所有 a 标签(后代) res = soup.select("div a") # 查找 div 直接子级 a 标签 res = soup.select("div > a")

5.2 select_one ():匹配单个元素

等价于select()[0],专门用于只取第一个匹配项,避免列表取值:

python

运行

# 获取第一个 class="title" 的标签 title = soup.select_one(".title") print(title.text.strip())

六、节点遍历(兄弟 / 父子节点)

部分页面结构无唯一 class/id,需通过节点关系遍历查找,适用于规整列表结构。

6.1 子节点与父节点

python

运行

tag = soup.select_one(".list") # 所有直接子节点 children = tag.children for child in children: if child.name: # 过滤空行、文本节点 print(child) # 获取父节点 parent = tag.parent print(parent.name)

6.2 兄弟节点(同级标签)

python

运行

# 下一个兄弟节点 next_sib = tag.next_sibling # 上一个兄弟节点 prev_sib = tag.previous_sibling # 所有后面的兄弟节点 all_next = tag.next_siblings

七、综合实战 1:列表页数据提取

模拟资讯列表页,完成请求 → 解析 → 批量提取标题、链接、简介全流程,整合前面所有知识点。

python

运行

import requests from bs4 import BeautifulSoup # 基础配置 url = "https://httpbin.org/html" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0.0.0 Safari/537.36" } # 1. 发起请求 resp = requests.get(url, headers=headers, timeout=6) resp.encoding = "utf-8" # 2. 构建解析对象 soup = BeautifulSoup(resp.text, "lxml") # 3. CSS选择器批量提取列表数据 news_items = soup.select("body > p") print("===== 列表数据提取结果 =====") for idx, item in enumerate(news_items, 1): text = item.get_text(strip=True) print(f"第{idx}条:{text}")

八、综合实战 2:图片链接批量抓取

实战场景:爬取页面所有图片地址,是爬虫高频需求。

python

运行

import requests from bs4 import BeautifulSoup url = "https://httpbin.org/images" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0.0.0 Safari/537.36"} resp = requests.get(url, headers=headers, timeout=8) soup = BeautifulSoup(resp.text, "lxml") # 选中所有 img 标签 img_list = soup.select("img") print("页面所有图片链接:") for img in img_list: src = img.get("src") if src: # 拼接完整绝对链接(相对地址补全域名) full_url = url.rstrip("/") + "/" + src.lstrip("/") print(full_url)

九、常见问题与避坑指南

9.1 找不到目标标签

  1. 检查页面是否为JS 动态渲染:BeautifulSoup 只能解析静态 HTML,动态内容无法获取,后续需使用 Selenium/Playwright;
  2. 核对选择器语法:class、id、标签名大小写严格区分;
  3. 查看源码:浏览器开发者工具 Elements 面板为准,不要只看预览界面。

9.2 文本出现大量换行、空格

解决方案:提取文本时统一使用get_text(strip=True)清除空白字符。

9.3 class 筛选失效

HTML 中 class 存在多个值时,完整匹配或模糊匹配:

html

预览

<div class="box item"></div>

python

运行

# 匹配包含 box 的标签 soup.select(".box")

9.4 相对链接无法访问

页面中src="/1.jpg"href="/index"属于相对路径,必须手动拼接主域名转为绝对链接。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/16 4:47:51

Python列表删除原理与生产级安全实践

1. 项目概述&#xff1a;Python列表删元素&#xff0c;远不止del、remove、pop三板斧“How to Remove an Item from a List in Python”——这个标题看似平平无奇&#xff0c;是每个刚学Python的人在第二天就会遇到的问题。但如果你真把它当成“查文档三秒解决”的入门题&#…

作者头像 李华
网站建设 2026/6/16 4:46:55

压电材料也怕冷!大禹电子教你为风速风向仪挑选“耐寒”搭档

在超声波风速风向仪的实际应用中&#xff0c;环境温度是影响换能器测量信号强度的重要因素之一。近期也有客户问&#xff1a;“风速风向仪的换能器工作温度&#xff0c;会不会影响测量信号?”这个问题很实际&#xff0c;尤其是在极端环境下使用的朋友。今天大禹电子就来聊聊这…

作者头像 李华
网站建设 2026/6/16 4:45:13

AgentGPT与AutoGPT选型指南:自主代理落地的工程决策逻辑

1. 这不是“选哪个更好”&#xff0c;而是“你手里的锤子该敲哪颗钉子”最近在几个技术社群里&#xff0c;几乎每天都能看到类似提问&#xff1a;“AgentGPT和AutoGPT哪个好&#xff1f;”——语气里带着一种急切的、想立刻抄起工具开工的务实感。但说实话&#xff0c;我第一次…

作者头像 李华
网站建设 2026/6/16 4:44:41

反激多路输出开关电源仿真:从模型构建到交叉调整率优化实战

1. 项目概述&#xff1a;从“黑盒”到“白盒”的电源设计思维转变在硬件开发的江湖里&#xff0c;开关电源设计&#xff0c;尤其是反激式多路输出电源&#xff0c;一直是个让人又爱又恨的领域。爱的是它结构简单、成本低廉&#xff0c;恨的是调试过程如同“开盲盒”&#xff0c…

作者头像 李华