一、什么是HTML网页结构
在爬虫中,我们主要通过 HTML 获取网页数据,因其定义了网页的核心结构和信息。以下是 HTML 的基础概念及与爬虫相关的核心知识:
1、网页三大技术要素
- HTML:定义网页的结构和内容(如标题、段落、列表等),是爬虫的主要处理对象。
- CSS:定义网页的样式(如颜色、布局、字体),爬虫通常无需关注。
- JavaScript:定义网页的交互逻辑(如按钮点击、动态加载),复杂爬虫可能需要处理。
2、HTML 的基本结构
一个简单的 HTML 文档结构如下:
<!DOCTYPE html> <!-- 声明文档类型为HTML -->
<html> <!-- 根元素,包含所有其他元素 -->
<body> <!-- 主体元素,包含网页可见内容 -->
<h1>这是一级标题</h1> <!-- 标题元素(h1-h6,字号递减) -->
<p>这是一个段落。</p> <!-- 段落元素 -->
</body>
</html>
核心概念
标签:用
<>
包围的关键词(如<html>
、<body>
),分为:- 起始标签:
<标签名>
(如<h1>
),表示元素开始。 - 闭合标签:
</标签名>
(如</h1>
),表示元素结束。
- 起始标签:
元素:起始标签 + 内容 + 闭合标签的整体(如
<p>内容</p>
)。层级关系:
- 子元素:嵌套在其他元素内部的元素(如
是
的子元素)。
- 子元素:嵌套在其他元素内部的元素(如
- 兄弟元素:同一层级的元素(如
和
是兄弟元素)。
3、查看网页的 HTML 源码
要分析目标网页的结构,可通过以下方式查看 HTML:
查看网页源码:右键网页→“查看网页源代码”,获取完整 HTML 文本。
开发者工具:右键网页→“检查”(或按 F12),进入 “Elements” 面板:
- 可实时查看鼠标点击元素对应的 HTML 标签。
- 便于定位目标数据在 HTML 中的位置(爬虫解析的关键)。
4、爬虫为何关注 HTML?
HTML 直接包含网页的文本、链接、图片路径等核心数据,例如:
- 电影名称可能在
<h3 class="title">
标签内; - 商品价格可能在
<span class="price">
标签内。
二、HTML有哪些常用标签
HTML 标签定义了网页的信息结构,是爬虫提取数据的核心依据。以下是爬虫中常见的 HTML 标签及其功能,帮助快速定位目标数据:
1、文本与标题标签
1.1. 标题标签(<h1>
-<h6>
)
功能:定义不同层级的标题,
层级最高(通常为页面主标题),
层级最低。示例:
html<h1>豆瓣电影Top250</h1> <!-- 一级标题 --> <h2>剧情片</h2> <!-- 二级标题 -->
1.2. 段落标签(<p>
)
功能:定义文本段落,不同
<p>
标签默认换行。示例:
html<p>这是电影简介内容...</p> <p>导演:张艺谋</p>
1.3. 换行与文本格式化标签
<br>
:强制换行(单标签,无闭合标签)。html<p>第一行<br>第二行</p>
<b>
:加粗文本;<i>
:斜体文本;<u>
:下划线文本。html<b>重点内容</b>、<i>强调内容</i>
2、媒体与链接标签
2.1. 图片标签(<img>
)
功能:插入图片(单标签,无闭合标签)。
核心属性:
src
:图片路径(必填,可为 URL 或本地路径);alt
:图片加载失败时的替代文本;width
/height
:图片宽高。
示例:
html<img src="movie.jpg" alt="电影海报" width="300">
2.2. 链接标签(<a>
)
功能:定义超链接,实现页面跳转。
核心属性:
href
:目标 URL(必填,如https://movie.douban.com
);target
:打开方式(_self
默认当前窗口,_blank
新窗口)。
示例:
html<a href="https://movie.douban.com/top250" target="_blank">豆瓣Top250</a>
3、容器标签(<div>
与<span>
)
功能:用于分组或包裹其他元素,便于统一样式或结构管理。
区别:
<div>
:块级元素,独占一行(如页面分区);<span>
:内联元素,同行显示(如段落内部分文本)。
示例:
html<div class="movie-info"> <!-- 块级容器,包含电影信息 --> <span class="title">肖申克的救赎</span> <!-- 内联容器,包裹标题 --> <span class="rating">9.7</span> <!-- 内联容器,包裹评分 --> </div>
4、列表标签
4.1. 有序列表(<ol>
+<li>
)
功能:定义有顺序的列表(如排名),
为列表容器,
为列表项。示例:
html<ol> <li>第一名:肖申克的救赎</li> <li>第二名:霸王别姬</li> </ol>
4.2. 无序列表(<ul>
+<li>
)
功能:定义无顺序的列表(如标签、类别),列表项前通常为符号(圆点、方块等)。
示例:
html<ul> <li>剧情</li> <li>犯罪</li> </ul>
5、表格标签(<table>
系列)
功能:定义表格,常用于展示结构化数据(如统计信息)。
核心标签:
<table>
:表格容器;<thead>
:表格头部(通常为表头行);<tbody>
:表格主体(数据行);<tr>
:表格行;<td>
:单元格数据。
示例:
html<table border="1"> <!-- border属性添加边框 --> <thead> <tr><td>排名</td><td>电影名</td></tr> <!-- 表头行 --> </thead> <tbody> <tr><td>1</td><td>肖申克的救赎</td></tr> <!-- 数据行 --> </tbody> </table>
6、通用属性:class
功能:为元素定义类名,用于分组或区分同类元素(所有标签均可使用)。
示例:
html<p class="intro">电影简介...</p> <p class="review">用户评论...</p>
爬虫关注点:通过类名快速定位特定类型的元素(如提取所有
class="review"
的评论内容)。
三、练习HTML常见标签
1、准备工作:选择编辑器与创建 HTML 文件
- 编辑器选择:推荐使用 WebStorm 或 VS Code(支持代码高亮、自动缩进),也可使用记事本(需手动保存为
.html
后缀)。 - 新建文件:创建名为
practice.html
的文件,所有代码将写入此文件。
2、基础结构:HTML 文档的 “骨架”
所有 HTML 内容需包裹在固定的基础结构中,确保浏览器正确识别:
<!DOCTYPE html> <!-- 声明文档类型为HTML -->
<html> <!-- 根元素,包含所有其他元素 -->
<head> <!-- 文档头部:存放网页元信息(非可见内容) -->
<title>HTML实战练习</title> <!-- 浏览器选项卡标题 -->
</head>
<body> <!-- 文档主体:存放网页可见内容(标签、文本、图片等) -->
<!-- 以下将写入各类标签 -->
</body>
</html>
- 效果验证:保存文件后,双击或拖入浏览器,可看到浏览器选项卡显示 “HTML 实战练习”,页面主体为空白(待添加内容)。
- 缩进规则:子元素缩进比父元素多 2-4 个空格(如
head
和body
缩进于html
,title
缩进于head
),层级更清晰。
3、实战 1:文本与标题标签
3.1. 标题标签(<h1>
-<h6>
)
在body
中添加不同层级的标题:
<body>
<h1>一级标题(最大)</h1>
<h2>二级标题</h2>
<h3>三级标题</h3>
<h6>六级标题(最小)</h6>
<h7>七级标题(无效,显示为普通文本)</h7> <!-- 无此标签 -->
</body>
- 效果:刷新浏览器,标题字号随层级递减,
h7
无特殊样式(视为普通文本,建议删除)。
3.2. 段落与换行标签(<p>
、<br>
)
添加文本段落并控制换行:
<body>
<!-- 标题标签省略,接下文 -->
<p>这是第一个段落。即使在代码里换行,网页也不会换行,只会显示为空格。</p>
<p>这是第二个段落(自动换行)。</p>
<p>这是第三个段落<br>用BR标签强制换行(单标签,无闭合)。</p>
</body>
- 效果:
p
标签自动分隔段落,br
标签实现段落内强制换行。
3.3. 文本格式化标签(<b>
、<i>
、<u>
)
对文本进行加粗、斜体、下划线处理:
<body>
<!-- 前文标签省略,接下文 -->
<p>这是<b>加粗文本</b>,这是<i>斜体文本</i>,这是<u>下划线文本</u>。</p>
</body>
- 效果:对应文本分别呈现加粗、斜体、下划线样式。
4、实战 2:媒体与链接标签
4.1. 图片标签(<img>
)
插入图片并控制尺寸(需指定src
属性,单标签):
<body>
<!-- 前文标签省略,接下文 -->
<!-- src为图片URL或本地路径,width/height控制尺寸(单位:像素px) -->
<img src="https://picsum.photos/200/300" alt="示例图片" width="200" height="150">
</body>
- 参数说明:
src
:图片来源(示例使用免费图片链接,本地图片需写路径如./images/pic.jpg
);alt
:图片加载失败时显示的替代文本;width/height
:可选,控制图片大小。
- 效果:刷新后显示指定尺寸的图片。
4.2. 链接标签(<a>
)
添加超链接,控制跳转方式:
<body>
<!-- 前文标签省略,接下文 -->
<!-- 1. 当前窗口跳转(默认) -->
<a href="https://www.baidu.com">百度(当前窗口打开)</a>
<br>
<!-- 2. 新窗口跳转(target="_blank") -->
<a href="https://www.douban.com" target="_blank">豆瓣(新窗口打开)</a>
</body>
- 注意:
href
必须为完整 URL(含http/https
),否则无法正常跳转。 - 效果:点击链接,分别在当前窗口 / 新窗口打开目标网页。
5、实战 3:容器标签(<div>
与<span>
)
容器用于分组元素,配合简单 CSS 可直观区分(仅演示功能,不深入 CSS):
<body>
<!-- 前文标签省略,接下文 -->
<!-- 1. div:块级元素,独占一行 -->
<div style="background-color: lightcoral; padding: 10px;">
<p>这是div容器内的文本(独占一行)</p>
<img src="https://picsum.photos/100/100" alt="小图">
</div>
<br> <!-- 换行分隔 -->
<!-- 2. span:内联元素,同行显示 -->
<p>
<span style="background-color: lightblue; padding: 5px;">这是第一个span</span>
<span style="background-color: lightgreen; padding: 5px;">这是第二个span(同行)</span>
</p>
</body>
- 效果:
div
区域背景为浅红色,独占一行;两个span
背景分别为浅蓝色、浅绿色,在同一行显示。
6、实战 4:列表标签(有序列表、无序列表)
6.1. 有序列表(<ol>
+<li>
)
定义有顺序的列表(如排名):
<body>
<!-- 前文标签省略,接下文 -->
<h3>电影排名(有序列表)</h3>
<ol>
<li>肖申克的救赎</li>
<li>霸王别姬</li>
<li>阿甘正传</li>
</ol>
</body>
- 效果:列表项前自动添加数字(1、2、3)。
6.2. 无序列表(<ul>
+<li>
)
定义无顺序的列表(如标签):
<body>
<!-- 前文标签省略,接下文 -->
<h3>电影类型(无序列表)</h3>
<ul>
<li>剧情</li>
<li>犯罪</li>
<li>爱情</li>
</ul>
</body>
- 效果:列表项前显示圆点(默认样式),无顺序标识。
7、实战 5:表格标签(<table>
系列)
创建结构化表格,包含表头、表体和边框:
<body>
<!-- 前文标签省略,接下文 -->
<h3>学生信息表</h3>
<!-- border="1" 添加边框,1为边框宽度(单位:像素) -->
<table border="1">
<thead> <!-- 表格头部(表头) -->
<tr> <!-- 表头行 -->
<td>学号</td> <!-- 表头单元格 -->
<td>姓名</td>
<td>班级</td>
</tr>
</thead>
<tbody> <!-- 表格主体(数据) -->
<tr> <!-- 数据行1 -->
<td>2023001</td>
<td>小明</td>
<td>一班</td>
</tr>
<tr> <!-- 数据行2 -->
<td>2023002</td>
<td>小红</td>
<td>二班</td>
</tr>
<tr> <!-- 数据行3(单元格数量可不同) -->
<td>2023003</td>
<td>小刚</td>
</tr>
</tbody>
</table>
</body>
- 效果:表格带边框,表头与数据清晰区分,第三行仅 2 个单元格(允许行数与列数不统一)。
8、实战 6:通用属性class
为元素添加类名(后续结合 CSS/JavaScript 有用,此处仅演示定义):
<body>
<!-- 给表格添加class="student-table" -->
<table border="1" class="student-table">
<!-- 表格内容省略,同上文 -->
</table>
</body>
9、关键总结
- 效果更新:每次修改 HTML 后,需刷新浏览器才能看到最新效果。
- 标签规则:大部分标签需成对(起始 + 闭合),单标签(
<br>
、<img>
)无需闭合。 - 爬虫关联:实战中的标签(如
<h3>
电影名、<table>
数据、<a>
链接)正是爬虫后续要提取的核心目标,理解结构即可,无需记忆所有细节。
四、如何解析HTML内容
在获取网页 HTML 内容后,需要必要从中精准提取目标数据。Beautiful Soup 是 Python 中强大的 HTML 解析库,能高效处理复杂的 HTML 结构,轻松实现数据提取。以下是其使用方法及实战案例:
1、安装与引入 Beautiful Soup
1.1. 安装库
Beautiful Soup 是第三方库,需先安装:
Windows:在终端输入
shpip install bs4
macOS/Linux:通常使用
shpip3 install bs4
验证安装: 若终端显示Successfully installed bs4
,或Requirements already satisfied
(已安装),则安装成功。
1.2. 引入库
在 Python 代码中引入 Beautiful Soup 类:
from bs4 import BeautifulSoup
2、解析 HTML:创建 Beautiful Soup 的基本用法
2.1. 创建 Beautiful Soup 对象
假设已通过 requests 库获取网页 HTML 内容(字符串格式),存储在content
变量中,解析步骤如下:
# 假设content是通过requests.get().text获取的HTML字符串
soup = BeautifulSoup(content, "html.parser") # 第二个参数指定解析器(解析HTML用html.parser)
soup
是解析后的的 HTML 对象,将复杂的 HTML 转换为树形结构,便于查找和提取数据。
2.2. 查找元素的核心方法
(1)获取单个元素:find()
返回第一个符合条件的第一个元素,例如:
# 获取第一个<p>标签
first_p = soup.find("p")
# 获取第一个<img>标签
first_img = soup.find("img")
(2)获取多个元素:find_all()
返回所有符合条件的元素(可迭代对象),例如:
# 获取所有<h3>标签
all_h3 = soup.find_all("h3")
# 获取所有<a>标签
all_links = soup.find_all("a")
(3)按属性筛选元素
通过attrs
参数指定标签的属性(如class
、id
等),精准定位元素:
# 示例:获取所有class为"price_color"的<p>标签(假设价格信息在这类标签中)
price_tags = soup.find_all("p", attrs={"class": "price_color"})
2.3. 提取元素内容
通过元素的string
属性获取标签内的文本:
# 遍历价格标签,提取文本(例如价格)
for tag in price_tags:
price_text = tag.string # 获取文本内容(如"£51.77")
pure_price = price_text[1:] # 去除货币符号,仅保留数字(如"51.77")
print(pure_price)
3、实战案例:提取书名(多层级元素)
若目标数据嵌套在多层标签中(如书名在→
标签内),需分层提取:
步骤分析
- 找到所有
标签(假设书名的父元素是
); - 在每个
中找到
标签(书名所在标签); - 提取``标签内的文本。
代码实现
# 1. 获取所有<h3>标签
all_h3 = soup.find_all("h3")
# 2. 遍历每个<h3>,提取其中的<a>标签文本
book_titles = []
for h3 in all_h3:
# 在当前<h3>中找第一个<a>标签(使用find(),因每个<h3>通常只有一个<a>)
a_tag = h3.find("a")
# 提取文本并添加到列表
if a_tag:
title = a_tag.string
book_titles.append(title)
# 打印所有书名
for title in book_titles:
print(title)
4、关键技巧
- 利用浏览器开发者工具:通过 “检查” 功能定位目标数据的标签及属性(如
class
值),为find_all()
提供筛选条件。 - 灵活处理嵌套结构:若数据在多层标签中,需逐层查找(如先找父标签,再在父标签内找子标签)。
- 字符串处理:提取的文本可能包含多余符号(如货币符号、空格),可通过切片、
strip()
等方法清洗。