Day 28:【99天精通Python】HTML解析库 BeautifulSoup - 像喝汤一样提取网页数据

Day 28:【99天精通Python】HTML解析库 BeautifulSoup - 像喝汤一样提取网页数据

前言

欢迎来到第28天!

在昨天的课程中,我们学会了用requests库把网页源代码(HTML)下载下来。但是,打印出来的response.text是一大坨密密麻麻的 HTML 标签,看得人头皮发麻。

比如你想提取网页中所有的"新闻标题",如果用正则表达式去匹配<h3>(.*?)</h3>,不仅写起来麻烦,而且一旦网页结构稍微变一下(比如标签里多了个 class),正则就失效了。

今天介绍的BeautifulSoup(美味的汤),就是一个专门用来"解析" HTML 的库。它能把乱七八糟的 HTML 代码变成一个复杂的树形结构,你只需要告诉它:“给我找所有的<h3>标签”,或者"给我找id='content'的那个div",它就能乖乖把数据端到你面前。

本节内容:

  • 安装 BeautifulSoup4
  • 解析 HTML 结构
  • 核心方法find()find_all()
  • CSS 选择器select()
  • 提取文本与属性
  • 实战练习:爬取豆瓣电影Top250(简易版)

一、安装与准备

BeautifulSoup 是第三方库,通常配合lxml解析器使用(速度快,容错能力强)。

pipinstallbeautifulsoup4 lxml

1.1 初始化 Soup 对象

我们先用一段简单的 HTML 字符串来演示。

frombs4importBeautifulSoup html_doc=""" <html> <head><title>这是网页标题</title></head> <body> <p class="title"><b>故事是从这里开始的</b></p> <p class="story"> 曾经有三个小伙伴: <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> 和 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; 他们生活在井底。 </p> </body> </html> """# 创建 BeautifulSoup 对象# 第二个参数指定解析器 'lxml'soup=BeautifulSoup(html_doc,'lxml')# 格式化输出看看结构print(soup.prettify())

二、遍历文档树:指哪打哪

2.1 直接访问标签

可以直接通过.来访问标签,这会返回第一个匹配到的标签。

print(soup.title)# <title>这是网页标题</title>print(soup.title.string)# 这是网页标题print(soup.a)# <a ...>Elsie</a> (只返回第一个a标签)print(soup.p)# <p class="title">...</p>

三、搜索文档树:find 与 find_all (重点)

这是最常用的两个方法。

3.1 find_all():查找所有匹配项

返回一个列表

# 1. 查找所有 <a> 标签links=soup.find_all('a')forlinkinlinks:print(link)# 2. 查找所有 class="sister" 的标签# 注意:class 是 Python 关键字,所以参数名要写成 class_sisters=soup.find_all(class_='sister')# 3. 查找 id="link1" 的标签link1=soup.find_all(id='link1')

3.2 find():查找第一个匹配项

返回单个标签对象(如果找不到返回None)。

# 查找第一个 <b> 标签b_tag=soup.find('b')print(b_tag.string)# 故事是从这里开始的

3.3 混合搜索

# 查找 id=link2 的 a 标签target=soup.find('a',id='link2')print(target)

四、CSS 选择器:select (推荐)

如果你熟悉前端开发(CSS/jQuery),你会爱死select()方法。它允许你用 CSS 选择器语法来查找元素。

选择器语法示例
标签选择器tagsoup.select('a')
类选择器.classsoup.select('.sister')
ID选择器#idsoup.select('#link1')
层级选择器parent childsoup.select('p a')(p标签下的所有a)
属性选择器[attr]soup.select('a[href^="http"]')
# select 返回的是列表tags=soup.select('p.story > a')# p标签(class=story)下的直接子标签aprint(tags)# select_one 返回的是单个对象 (等同于 find)tag=soup.select_one('#link3')print(tag.string)

五、提取数据:拿走肉,留下汤

找到标签后,我们的目标通常是里面的文字链接

5.1 获取文本get_text()

p=soup.select_one('.story')# get_text() 会自动去除标签,只提取文字print(p.get_text())# 输出:曾经有三个小伙伴:Elsie, Lacie 和 Tillie; 他们生活在井底。# 或者用 .string 属性 (如果标签内还有子标签,.string 可能是 None)print(soup.title.string)

5.2 获取属性get('attr')

link=soup.select_one('#link1')# 像字典一样取值url=link.get('href')# 或者 link['href']print(url)# http://example.com/elsie

六、实战练习:爬取豆瓣电影 Top250

这是一个经典的爬虫练习。我们要提取每部电影的标题评分引言

注意:豆瓣有反爬机制,必须带User-Agent

importrequestsfrombs4importBeautifulSoupdefscrape_douban():url="https://movie.douban.com/top250"headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"}try:response=requests.get(url,headers=headers)ifresponse.status_code!=200:print("请求失败")returnsoup=BeautifulSoup(response.text,'lxml')# 1. 找到所有电影的条目 (每个电影都在一个 class="item" 的 div 里)items=soup.select('.item')print(f"本页共找到{len(items)}部电影:\n")foriteminitems:# 2. 提取标题 (span class="title")title=item.select_one('.title').get_text()# 3. 提取评分 (span class="rating_num")rating=item.select_one('.rating_num').get_text()# 4. 提取引言 (span class="inq"),有的电影可能没有引言,要做防错处理quote_tag=item.select_one('.inq')quote=quote_tag.get_text()ifquote_tagelse"无"print(f"《{title}》 评分:{rating}| 简评:{quote}")exceptExceptionase:print(f"发生错误:{e}")# 运行 (请勿频繁请求,以免被封IP)# scrape_douban()

七、常见问题

Q1:findselect哪个好?

  • find/find_all:Python 风格,参数直观,适合简单的查找。
  • select/select_one:CSS 风格,适合复杂的层级查找(比如找div下的ul下的第3个li)。
    建议:掌握select,因为它和前端逻辑一致,通用性更强。

Q2:.text.string的区别?

  • .string: 只有当标签内只有纯文本(没有子标签)时才返回文本,否则返回None
  • .text/get_text(): 无论有多少子标签,都会把里面所有的文本拼起来返回。通常用这个。

Q3:为什么解析结果和浏览器F12看到的不一样?

浏览器 F12 看到的是 JS 执行后渲染的最终结果。而requests拿到的只是服务器返回的原始 HTML。如果网页内容是 JS 动态加载的(比如 AJAX),BeautifulSoup 就抓不到了(需要用到 Selenium 或分析 API,后续课程会讲)。


八、小结

爬虫流程

Requests: 获取HTML

BeautifulSoup: 解析HTML

Find/Select: 定位标签

Extract: 提取数据

soup = BeautifulSoup(html, 'lxml')

find('tag') / find_all('tag')

select('.class') / select('#id')

tag.get_text() -> 文本

tag['href'] -> 属性

关键要点

  1. BeautifulSoup是 HTML 解析神器,配合requests使用。
  2. soup.select()支持 CSS 选择器,非常强大。
  3. 提取三要素:找节点、取文本、取属性。

九、课后作业

  1. 博客标题爬取:找一个你喜欢的技术博客网站(如 CSDN 首页或某个专栏),爬取首页所有的文章标题和链接。
  2. 古诗词抓取:在一个古诗词网站(如古诗文网),搜索"李白",抓取搜索结果中前 5 首诗的题目和作者。
  3. 图片批量下载器升级:结合 Day 27 的知识,先用 BeautifulSoup 解析网页找到所有<img>标签的src,然后用requests批量下载图片。

下节预告

Day 29:数据持久化 - CSV与Excel- 爬下来的数据光打印在屏幕上没用,我们要把它们存进 Excel 表格里,方便后续分析和汇报!


系列导航

  • 上一篇:Day 27 - HTTP协议与Requests库
  • 下一篇:Day 29 - 数据持久化CSV与Excel(待更新)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1150786.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务分布式SpringBoot+Vue+Springcloud人脸识别的微信小程序的学生选课签到定位考勤系统

目录摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 该系统基于微服务分布式架构&#xff0c;结合SpringBoot、Vue和SpringCloud技术栈&#xff0c;实现了一套集成人脸识别、微信小程序交互、学生选课及签到定位考勤功…

Java Web 车辆管理系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着城市化进程的加快和私家车保有量的持续增长&#xff0c;车辆管理成为城市治理的重要课题。传统车辆管理方式依赖人工登记和纸质档案&#xff0c;存在效率低下、数据易丢失、查询困难等问题。信息化技术的普及为车辆管理提供了新的解决方案&#xff0c;通过构建智能化的…

一文说清Vitis使用教程在Alveo上的应用要点

从零到实战&#xff1a;如何用Vitis在Alveo上高效实现FPGA硬件加速 你是否曾为AI推理延迟过高而焦虑&#xff1f; 是否在处理TB级数据库查询时&#xff0c;眼睁睁看着CPU跑满却束手无策&#xff1f; 又或者&#xff0c;在做实时视频转码时&#xff0c;发现GPU编码器灵活性不…

Day 29:【99天精通Python】数据持久化 - CSV与Excel - 办公自动化的第一步

Day 29&#xff1a;【99天精通Python】数据持久化 - CSV与Excel - 办公自动化的第一步 前言 欢迎来到第29天&#xff01; 在昨天的爬虫练习中&#xff0c;我们成功从网页上抓取了数据。但这些数据如果只打印在终端里&#xff0c;关掉窗口就没了&#xff0c;实在太可惜。 在职场…

零基础掌握HardFault异常处理机制的基本原理

破解HardFault之谜&#xff1a;从崩溃现场还原程序“死亡瞬间”你有没有遇到过这样的场景&#xff1f;代码烧进去&#xff0c;设备上电后一切正常&#xff0c;突然毫无征兆地卡死——没有日志、无法复现、JTAG一连才发现&#xff1a;程序停在了while(1)里&#xff0c;而调用栈清…

微服务分布式SpringBoot+Vue+Springcloud仁康医院预约挂号系统

目录 微服务分布式医院预约挂号系统摘要 开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 微服务分布式医院预约挂号系统摘要 该系统基于SpringBoot、Vue和SpringCloud技术栈构建&#xff0c;采用微服务架构实现高并发、高可用…

企业级桂林旅游景点导游平台管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】

摘要 随着旅游业的快速发展&#xff0c;信息化管理成为提升旅游服务质量和效率的重要手段。桂林作为国际知名的旅游城市&#xff0c;拥有丰富的自然和人文景观&#xff0c;但传统的旅游管理模式难以满足现代游客的个性化需求。企业级桂林旅游景点导游平台管理系统的开发&#x…

从零实现内核崩溃分析:WinDbg解析DMP蓝屏文件完整指南

从崩溃中读懂真相&#xff1a;手把手教你用 WinDbg 深度解析蓝屏 DMP 文件你有没有遇到过这样的场景&#xff1f;服务器毫无征兆地重启&#xff0c;只留下一个神秘的MEMORY.DMP文件&#xff1b;或者刚装完新驱动&#xff0c;系统瞬间蓝屏&#xff0c;错误码一闪而过——想查问题…

HID协议入门指南:常见术语与框架介绍

HID协议从零到实战&#xff1a;嵌入式开发者的深度指南 你有没有遇到过这样的场景&#xff1f; 插上一个自制的USB键盘&#xff0c;电脑却无法识别按键&#xff1b;或者做了一个BLE游戏手柄&#xff0c;安卓手机连上了却不会震动。问题可能不在硬件电路&#xff0c;而在于——…

L298N典型应用电路搭建手把手教程

手把手教你用L298N驱动直流电机&#xff1a;从零搭建稳定控制电路你有没有遇到过这样的情况&#xff1f;写好了Arduino程序&#xff0c;信心满满地给小车通电&#xff0c;结果电机纹丝不动——或者只转一个方向&#xff0c;还“嗡嗡”发热。别急&#xff0c;问题很可能出在电机…

微服务分布式SpringBoot+Vue+Springcloud受灾区救援物资管理系统优惠

目录微服务分布式救援物资管理系统概述核心功能模块技术优势优惠方案社会价值开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;微服务分布式救援物资管理系统概述 基于SpringBootVueSpringCloud的受灾区救援物资管理系统采用分布…

Vlm-Transformer_demo

import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import random# 1. 准备数据&#xff08;字符级语料&#xff09; # 简单语料&#xff08;自己构造&#xff0c;无需下载&#xff09; #训练样本数: 89 | 词汇表字符: [ , a…

微服务分布式SpringBoot+Vue+Springcloud四川自驾游攻略管理系统

目录微服务分布式SpringBootVueSpringCloud四川自驾游攻略管理系统摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;微服务分布式SpringBootVueSpringCloud四川自驾游攻略管理系统摘要 该系统基于微服务分布式架构&#xff…

微服务分布式SpringBoot+Vue+Springcloud微信小程序的宠物美容预约系统设计与实现

目录摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 随着宠物经济的快速发展&#xff0c;宠物美容服务的需求日益增长。传统的线下预约方式存在效率低、信息不对称等问题。基于此&#xff0c;设计并实现了一套基于微服…

USB转串口驱动安装步骤通俗解释

电脑没串口&#xff1f;一文搞懂USB转串口驱动安装与芯片选型 你有没有遇到过这种情况&#xff1a;手握一块开发板&#xff0c;连上USB线准备调试&#xff0c;打开设备管理器却发现“未知设备”或者根本找不到COM口&#xff1f;明明线插好了&#xff0c;灯也亮了&#xff0c;就…

Java SpringBoot+Vue3+MyBatis 网站系统源码|前后端分离+MySQL数据库

摘要 随着互联网技术的快速发展&#xff0c;现代Web应用对高性能、模块化和可扩展性的需求日益增长。传统的单体架构在应对复杂业务逻辑和高并发场景时逐渐显现出局限性&#xff0c;前后端分离架构因其灵活性、开发效率高和易于维护等特点成为主流解决方案。基于此背景&#xf…

易连说-如何寻找具备 Drummond Group AS2 国际认证的EDI 产品?

在数字化供应链重构的浪潮中&#xff0c;电子数据交换&#xff08;EDI&#xff09;已从“可选配置”升级为企业对接全球贸易伙伴的“必备能力”。作为 EDI 数据传输的主流协议——AS2 协议凭借安全加密、可靠传输的特性&#xff0c;成为企业间数据交换的核心选择&#xff0c;选…

AD画PCB中HDMI高速通道设计项目应用详解

如何在Altium Designer中搞定HDMI高速通道设计&#xff1f;一文讲透实战要点你有没有遇到过这样的情况&#xff1a;板子打回来了&#xff0c;HDMI接口连上去却黑屏、闪屏&#xff0c;甚至压根不识别显示器&#xff1f;明明原理图画得没错&#xff0c;元器件也焊上了&#xff0c…

小白指南:USB接口各引脚功能详解入门篇

从零开始搞懂USB&#xff1a;别再被那几根线难住了&#xff01;你有没有试过自己焊一条USB线&#xff0c;结果接上电脑没反应&#xff0c;甚至烧了接口&#xff1f;或者想给开发板单独供电&#xff0c;却不知道哪根线是电源、哪根是地&#xff1f;又或者好奇为什么有些安卓手机…

大数据分布式事务:CAP定理视角下的解决方案对比

大数据分布式事务&#xff1a;CAP定理视角下的解决方案对比关键词&#xff1a;大数据、分布式事务、CAP定理、解决方案对比摘要&#xff1a;本文主要从CAP定理的视角出发&#xff0c;深入探讨大数据分布式事务的多种解决方案。首先介绍了大数据分布式事务的背景知识和CAP定理的…