十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python进阶教程:22_BeautifulSoup 网页解析 零基础超详细教程

Python进阶教程:22_BeautifulSoup 网页解析 零基础超详细教程 BeautifulSoup 是 Python 爬虫领域最经典的HTML/XML 解析库核心作用是从网页源码中精准提取你想要的数据。 通俗理解如果把网页比作一本杂乱的书requests负责把书下载下来BeautifulSoup 就是帮你快速翻书、定位指定内容的智能工具 —— 不用逐行找、不用写复杂的正则表达式通过标签名、属性、CSS 选择器就能快速抠出数据是新手入门爬虫的必学工具。本文从环境搭建、基础语法到完整实战全程配可运行代码 逐行解释 避坑指南零基础也能一步步上手。⚠️ 合规提示本文仅用于技术学习请遵守目标网站的robots协议不要恶意爬取、批量请求他人网站。一、前置说明1. BeautifulSoup 的定位它只能解析已经拿到的网页源码本身不能下载网页。爬虫的标准流程是用requests等库发送请求下载网页的 HTML 源码把源码交给 BeautifulSoup 解析提取目标数据补充BeautifulSoup 只能处理静态 HTML浏览器右键 “查看网页源码” 能看到的内容如果是 JavaScript 动态渲染的内容比如需要滚动、点击才加载的数据直接拿源码是看不到的需要配合 Selenium 或者抓接口。2. 安装BeautifulSoup 是第三方库需要手动安装。注意库名是beautifulsoup4末尾的 4 是版本号pip install beautifulsoup43. 关于解析器BeautifulSoup 本身只提供解析逻辑需要搭配解析器使用新手记住两种即可解析器说明推荐度html.parserPython 内置无需额外安装足够应对绝大多数场景⭐⭐⭐⭐⭐新手首选lxml第三方解析器解析速度更快需要单独安装pip install lxml⭐⭐⭐⭐本文所有例子都用内置的html.parser不用额外装东西。二、快速入门第一个解析示例我们先不用联网用一段手写的 HTML 字符串演示直观感受 BeautifulSoup 的用法。完整入门代码# 1. 导入库从 bs4 包里导入 BeautifulSoup 类 from bs4 import BeautifulSoup # 2. 准备一段HTML源码模拟我们下载到的网页内容 html_doc html head title测试网页标题/title /head body h1 classmain-title欢迎来到测试网站/h1 p classintro这是一个用于测试BeautifulSoup的示例网页。/p ul classnews-list lia hrefnews/1.html classnews-link第一条新闻/a/li lia hrefnews/2.html classnews-link第二条新闻/a/li lia hrefnews/3.html classnews-link第三条新闻/a/li /ul div idfooter p版权所有 © 2024/p /div /body /html # 3. 创建BeautifulSoup解析对象 # 第一个参数HTML源码字符串 # 第二个参数解析器这里用内置的html.parser soup BeautifulSoup(html_doc, html.parser) # 4. 提取数据获取网页标题 title soup.title.string print(网页标题, title) # 5. 提取所有新闻链接的文本和地址 links soup.find_all(a, class_news-link) print(\n所有新闻) for link in links: # .text 获取标签内的文字.get(href) 获取href属性的值 print(f标题{link.text}链接{link.get(href)})运行结果网页标题 测试网页标题 所有新闻 标题第一条新闻链接news/1.html 标题第二条新闻链接news/2.html 标题第三条新闻链接news/3.html逐行解释核心步骤BeautifulSoup(html_doc, html.parser)把字符串格式的 HTML变成结构化的「解析对象」之后所有提取操作都通过这个对象完成soup.title直接找到页面里第一个title标签.string获取标签里的文本内容soup.find_all(a, class_news-link)找到所有classnews-link的a标签返回列表.get(href)安全获取标签的href属性值三、核心解析方法重点必学BeautifulSoup 提供了多种提取数据的方法新手优先掌握最常用的 3 类标签直接选择、find()/find_all()、CSS 选择器select()。1. 直接通过标签名选择最简单的写法soup.标签名直接找到页面中第一个匹配的标签。示例from bs4 import BeautifulSoup soup BeautifulSoup(html_doc, html.parser) # 获取第一个h1标签 h1 soup.h1 print(h1) # h1 classmain-title欢迎来到测试网站/h1 # 获取第一个a标签 first_a soup.a print(first_a) # a hrefnews/1.html classnews-link第一条新闻/a⚠️ 注意这种方式只能拿到第一个匹配的标签适合页面里只有一个该标签的场景比如 title要找多个必须用后面的find_all()。2. find () 和 find_all ()最核心最常用这是 BeautifulSoup 最核心的两个方法90% 的提取场景都用它们。方法作用返回值find()找第一个符合条件的标签单个标签对象找不到返回 Nonefind_all()找所有符合条件的标签标签对象组成的列表找不到返回空列表通用语法soup.find(name标签名, attrs{属性名: 属性值}, text文本内容) soup.find_all(name标签名, attrs{属性名: 属性值}, text文本内容)用法 1只按标签名查找# 找到所有的li标签 all_li soup.find_all(li) print(f找到{len(all_li)}个li标签) # 找到第一个p标签 first_p soup.find(p) print(第一个p标签内容, first_p.text)用法 2按属性查找最常用通过标签的class、id、href等属性精准定位有两种写法写法 A通过attrs字典传属性通用写法# 找到id为footer的div标签 footer soup.find(div, attrs{id: footer}) print(footer.text.strip()) # 版权所有 © 2024 # 找到所有class为news-link的a标签 links soup.find_all(a, attrs{class: news-link})写法 B关键字参数简写更常用# 按id查找 footer soup.find(div, idfooter) # 按class查找注意class后面要加下划线_ # 因为class是Python的关键字直接写会语法报错 links soup.find_all(a, class_news-link)⚠️ 新手头号坑class是 Python 关键字作为参数必须写成class_加下划线否则直接语法报错用法 3按文本内容查找通过text参数匹配标签里的文字# 找到文本为第二条新闻的a标签 target soup.find(a, text第二条新闻) print(target.get(href)) # news/2.html注意text是完全匹配必须和标签里的文字一模一样才行模糊匹配需要配合正则表达式。3. 获取标签的文本和属性找到标签对象后我们最常用两个操作拿文字、拿属性值。① 获取文本内容写法作用推荐度.text获取标签内所有文本包括子标签里的文字自动拼接⭐⭐⭐⭐⭐最常用.get_text()和.text 效果一致还可以加参数控制分隔符⭐⭐⭐⭐.string仅当标签内只有纯文本、没有子标签时才能拿到否则返回 None⭐⭐示例div soup.find(div, idfooter) print(div.text) # 版权所有 © 2024 print(div.get_text(stripTrue)) # 自动去掉首尾空白② 获取属性值表格写法作用推荐度.get(属性名)属性存在返回值不存在返回 None不会报错⭐⭐⭐⭐⭐安全首选[属性名]属性不存在直接报错⭐⭐示例a_tag soup.find(a) print(a_tag.get(href)) # news/1.html print(a_tag.get(class)) # [news-link] print(a_tag.get(xxx)) # None属性不存在不报错4. CSS 选择器select () 方法如果你懂前端 CSS 选择器用select()会非常顺手语法和 CSS 完全一致返回匹配的所有元素列表。常用选择器对应写法选择器类型示例作用标签选择器soup.select(a)找到所有 a 标签class 选择器soup.select(.news-link)找到所有 class 为 news-link 的元素id 选择器soup.select(#footer)找到 id 为 footer 的元素后代选择器soup.select(ul li a)找到 ul 里面的 li 里面的 a子选择器soup.select(ul li)找到 ul 的直接子元素 li示例# 找到所有新闻链接 links soup.select(ul.news-list a.news-link) for link in links: print(link.text, link.get(href)) # 找到id为footer的div里的p标签 footer_p soup.select(#footer p) print(footer_p[0].text)补充select()永远返回列表哪怕只有一个结果也要用[0]取出来如果只要第一个可以用select_one()返回单个元素。四、进阶标签层级导航有时候我们先找到一个父标签再在它内部找子标签这就是「相对查找」可以避免页面其他同名标签的干扰。在标签内部继续查找标签对象本身也支持find()、find_all()、select()等所有方法只在当前标签的内部查找# 先找到整个ul父标签 ul_tag soup.find(ul, class_news-list) # 只在ul内部找a标签不会找到页面其他地方的a links ul_tag.find_all(a)其他层级属性了解即可.parent获取当前标签的父标签.children获取所有直接子标签迭代器.next_sibling/.previous_sibling下一个 / 上一个同级兄弟标签五、完整实战requests BeautifulSoup 爬取练习网站我们用专门的爬虫练习网站https://quotes.toscrape.com/做完整实战这个网站没有反爬、结构清晰专门供新手练习。需求爬取第一页的所有名言、作者、标签。完整代码 逐行解释# 1. 导入需要的库 import requests from bs4 import BeautifulSoup # 2. 目标网址 url https://quotes.toscrape.com/ # 3. 发送GET请求获取网页响应 # 加User-Agent模拟浏览器避免被拦截 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 } response requests.get(url, headersheaders) # 4. 设置编码防止中文乱码 response.encoding utf-8 # 5. 把响应的HTML文本交给BeautifulSoup解析 soup BeautifulSoup(response.text, html.parser) # 6. 定位所有名言条目每个名言都在class为quote的div里 quote_items soup.find_all(div, class_quote) print(f共找到{len(quote_items)}条名言\n) # 7. 遍历每条提取详细信息 for index, item in enumerate(quote_items, 1): # 提取名言内容在class为text的span里 text item.find(span, class_text).text.strip(“”) # 提取作者在class为author的small标签里 author item.find(small, class_author).text # 提取标签所有class为tag的a标签 tags [tag.text for tag in item.find_all(a, class_tag)] # 打印结果 print(f【第{index}条】) print(f名言{text}) print(f作者{author}) print(f标签{, .join(tags)}) print(-*50)运行效果共找到10条名言 【第1条】 名言The world as we have created it is a process of our thinking. 作者Albert Einstein 标签change, deep-thoughts, thinking, world -------------------------------------------------- ...关键步骤说明加请求头User-Agent模拟浏览器防止网站识别为爬虫直接拒绝编码设置response.encoding utf-8避免中文乱码如果不确定编码可以用response.apparent_encoding自动识别先找父容器再找子元素先定位每个名言的大盒子div.quote再在里面分别提取文字、作者、标签结构清晰不容易错六、新手高频易错点 避坑指南1.class忘加下划线❌ 错误soup.find(a, classnews-link)✅ 正确soup.find(a, class_news-link)原因class是 Python 关键字不能直接当参数名。2.find_all()结果直接.text报错find_all()返回的是列表不是单个标签对象不能直接.text必须遍历或者用下标取单个元素。 ❌ 错误soup.find_all(a).text✅ 正确links soup.find_all(a) for link in links: print(link.text)3. 找不到元素先看源码对不对如果定位语法没错但就是找不到元素先打印soup.prettify()看看拿到的源码是不是和浏览器里的一样如果源码里根本没有这个内容 → 是 JS 动态渲染的BeautifulSoup 搞不定需要用 Selenium 或者抓接口如果源码里有 → 检查标签名、属性名有没有写错注意大小写、拼写4. 属性值有多个 class 时的匹配问题如果一个标签有多个 class比如div classitem active用class_item是可以匹配到的BeautifulSoup 会匹配单个 class。5. 网页乱码拿到的内容中文全是乱码基本都是编码没设置对# 手动指定编码 response.encoding utf-8 # 或者自动识别编码 response.encoding response.apparent_encoding七、调试小技巧print(soup.prettify())可以把解析后的 HTML 格式化输出结构清晰调试的时候用来检查拿到的源码对不对、元素结构是什么样的非常好用。八、核心总结定位BeautifulSoup 是解析工具负责从 HTML 源码里提取数据配合 requests 下载网页使用核心方法找单个find()找所有find_all()CSS 选择器select()/select_one()取值文本.text/.get_text()属性.get(属性名)避坑class_加下划线、find_all 返回列表要遍历、动态页面用不了
返回列表