news 2026/6/12 7:16:54

Python 爬虫项目:静态网页数据提取入门

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫项目:静态网页数据提取入门

前言

在互联网数据体量持续增长的当下,网页数据采集已成为数据分析、市场调研、内容聚合等领域的基础技术手段。静态网页作为互联网最基础的页面形态,具备代码结构固定、渲染逻辑简单、访问门槛低等特点,是学习网络爬虫技术的首选场景。静态网页指页面内容由服务端直接生成 HTML 代码并返回至客户端,页面展示内容不会随用户操作、前端脚本动态变更,浏览器接收到完整 HTML 源码后即可直接完成页面渲染,这也让数据提取工作无需处理异步加载、动态渲染等复杂问题。

本文围绕 Python 实现静态网页数据提取展开全面讲解,从环境准备、基础网络请求、网页源码解读,到数据初步筛选、异常处理、基础实战案例逐层推进,搭建完整的静态爬虫知识体系。为方便读者快速获取所需工具与官方文档,本文涉及的核心库官方地址如下: Python 官方下载地址、requests 库官方文档、pip 官方使用文档、HTTP 状态码标准参考文档。

对于零基础学习者而言,掌握静态网页爬虫不仅能够理解网络请求的底层逻辑,更能为后续学习动态网页爬取、分布式爬虫、反爬应对等高阶内容筑牢根基。全文结合理论解析、代码实操、原理讲解与问题总结,兼顾理论深度与工程实用性,读者跟随内容逐步实操,即可独立完成常规静态网页的内容抓取工作。

一、爬虫基础认知与静态网页原理

1.1 网络爬虫的定义与应用场景

网络爬虫又被称作网络蜘蛛、网络机器人,是一种按照既定规则,自动抓取互联网网页数据的程序。其核心工作逻辑为模拟客户端向目标服务器发送网络请求,接收服务器返回的页面数据,再按照需求对数据进行解析、提取、存储等一系列操作。

从应用领域划分,爬虫技术目前已广泛落地于多个行业。在电商行业,爬虫可抓取商品价格、销量、评价数据,用于竞品分析与价格监控;在资讯行业,可批量采集新闻、文章内容,完成内容聚合平台的数据更新;在科研领域,能够大规模抓取公开文献、行业报告,支撑数据统计与学术研究;在运营领域,可采集社交平台、论坛的公开舆情信息,实现舆情监测。

需要明确的是,爬虫技术的使用必须严格遵守《网络安全法》《著作权法》以及目标网站的robots.txt协议,禁止未经授权抓取涉密数据、用户隐私数据、付费版权内容,同时需控制请求频率,避免对目标服务器造成过载压力,做到合法合规使用技术。

1.2 静态网页与动态网页核心区分

开展爬虫学习前,必须清晰区分静态网页与动态网页,二者的数据加载逻辑不同,对应的爬取方案也存在本质差异,下表为两类网页的核心特征对比:

表格

对比维度静态网页动态网页
数据加载方式服务端拼接完整 HTML 代码,一次性返回全部内容初始仅返回框架代码,通过 JavaScript 异步请求接口加载数据
页面后缀常见.html.htm常见.php.jsp.asp,也存在伪静态.html
源码特征网页可见内容全部包含在 HTML 源码中可见内容不存在于初始 HTML 源码,需抓接口获取
爬取难度低,直接解析源码即可提取数据高,需分析接口、处理 JS 渲染、签名校验等
典型站点企业官网、静态文档站、老式资讯页面主流电商平台、短视频平台、交互式论坛

静态网页的核心优势在于数据与 HTML 源码绑定,当客户端发起访问请求后,Web 服务器会直接将编写完成的 HTML 文件发送给浏览器,页面上所有文字、图片地址、链接等信息,均完整存在于响应源码内。爬虫程序只需获取到完整源码,就能通过字符串匹配、标签筛选等方式提取目标数据,这也是静态爬虫入门的核心切入点。

1.3 静态爬虫完整工作流程

一套标准的静态网页爬虫,整体分为六大核心环节,各环节环环相扣,缺一不可,具体流程如下:

  1. 目标分析:确定需要爬取的网站、页面地址、目标数据,查看页面结构,判断是否为纯静态网页,同时查阅网站robots.txt协议,确认爬取权限。
  2. 环境准备:安装 Python 解释器、第三方请求库,配置运行环境,保证代码可以正常执行网络请求。
  3. 发送网络请求:模拟浏览器向目标 URL 发送 HTTP 请求,携带请求头、请求参数等信息,获取服务器返回的响应数据。
  4. 响应校验:判断请求是否成功,通过 HTTP 状态码、响应内容长度等信息排查访问失败、页面跳转、封禁 IP 等问题。
  5. 数据提取:对返回的 HTML 源码进行解析,根据 HTML 标签、属性、文本内容筛选出所需数据。
  6. 数据存储与收尾:将提取到的文本、链接、地址等数据保存至文件、数据库,同时添加异常捕获、请求延时,优化爬虫稳定性。

整个流程逻辑简单清晰,入门阶段的核心学习重点集中在网络请求发送基础数据提取两大模块。

二、运行环境搭建与依赖库安装

2.1 Python 环境配置

Python 是目前爬虫领域使用最广泛的编程语言,其语法简洁、第三方库生态完善,极大降低了爬虫开发的门槛。首先需要完成 Python 解释器的安装,推荐使用 3.8 及以上版本,高版本 Python 对网络请求库、解析库的兼容性更佳。

安装步骤简述:进入前文提供的 Python 官方下载地址,根据自身操作系统(Windows、macOS、Linux)选择对应安装包,Windows 系统安装时建议勾选 “Add Python to PATH” 自动配置环境变量,安装完成后打开系统命令行工具(CMD、PowerShell、终端),输入以下命令验证安装是否成功:

bash

运行

python --version

若命令行输出对应的 Python 版本号,则代表环境配置完成。

2.2 核心依赖库介绍与安装

原生 Python 内置了urllib模块用于网络请求,但该模块语法繁琐、功能单一,在实际项目中极少使用。行业内主流使用requests 库实现 HTTP 请求,该库封装了复杂的网络请求逻辑,语法人性化,支持 GET、POST 等多种请求方式,同时兼容请求头、代理、超时设置等常用功能。

2.2.1 pip 包管理工具

pip是 Python 官方的第三方库管理工具,Python3.4 及以上版本默认自带pip,无需额外安装。在命令行输入以下命令验证pip可用性:

bash

运行

pip --version

若输出版本信息即可正常使用,若提示命令不存在,可手动配置环境变量或使用python -m pip替代pip指令。

2.2.2 requests 库安装

在命令行中执行以下安装命令,完成 requests 库的在线安装:

bash

运行

pip install requests

网络不佳的用户可以使用国内镜像源加速安装,以清华镜像源为例,命令如下:

bash

运行

pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple

安装完成后,可进入 Python 交互环境,执行import requests,若无报错则说明库安装成功。

2.3 辅助工具介绍

2.3.1 浏览器开发者工具

主流浏览器(Chrome、Edge、Firefox)均内置开发者工具,是爬虫开发的核心辅助工具,主要作用为:查看网页 HTML 源码、定位数据对应的 HTML 标签、查看网络请求信息、分析请求头与响应内容。 调用方式:打开目标网页后按下F12快捷键,或右键页面选择 “检查”,即可调出工具面板。其中Elements面板用于查看完整 HTML 结构,Network面板用于监控所有网络请求。

2.3.2 文本编辑器 / IDE

代码编写工具推荐使用 VS Code、PyCharm,两类工具均提供语法高亮、代码提示、断点调试等功能,适合 Python 代码开发。入门阶段也可使用系统自带记事本编写简单代码,但不建议长期使用。

三、HTTP 协议与网络请求基础

3.1 HTTP 协议核心概念

爬虫本质是基于HTTP/HTTPS 协议的客户端程序。HTTP 即超文本传输协议,是互联网应用最广泛的应用层协议,规定了客户端与服务端之间数据传输的格式与规则。HTTPS 是 HTTP 的加密版本,基于 SSL/TLS 协议对传输数据进行加密,目前绝大多数正规网站均使用 HTTPS 协议。

一次完整的 HTTP 交互分为两部分:客户端请求服务端响应。客户端(爬虫 / 浏览器)按照协议规则发送请求报文,服务端接收到请求后处理业务逻辑,并返回响应报文,整个交互过程基于 “请求 - 响应” 模型完成。

3.2 常见 HTTP 请求方式

HTTP 协议定义了多种请求方法,静态网页爬取中最常用的为GET 请求,其次为 POST 请求,其余请求方法在入门阶段极少使用,两种核心请求方式的区别如下:

表格

请求方式适用场景参数传递形式静态爬虫使用频率
GET单纯获取页面数据、查询内容参数拼接在 URL 地址后方,公开可见极高(静态网页主流)
POST提交表单、上传数据、登录验证参数放置在请求体中,相对隐蔽较低(静态页面基本不用)

GET 请求是静态网页爬取的核心,当我们在浏览器地址栏输入网址访问页面、点击普通链接跳转页面时,浏览器发送的都是 GET 请求。

3.3 HTTP 请求头与核心参数

请求头(Request Headers)是请求报文的重要组成部分,用于向服务端传递客户端的基础信息,包括浏览器类型、操作系统、语言、Cookie 等。很多网站会校验请求头信息,若爬虫程序不携带合法请求头,会被服务器识别为非法程序,直接拒绝访问,返回 403 禁止访问错误。

请求头中User-Agent是最关键的参数,该字段用于标识客户端身份,浏览器、爬虫程序、移动端设备都会携带专属的 User-Agent 信息。爬虫入门阶段,必须模拟浏览器的 User-Agent,伪装成正常客户端发起请求。

获取浏览器 User-Agent 的方法:打开浏览器开发者工具,切换至 Network 面板,刷新页面,点击第一条请求记录,在 Request Headers 列表中找到User-Agent字段,复制其对应值即可。

3.4 HTTP 响应状态码

服务端返回的响应报文中会包含状态码,用于标识本次请求的执行结果,状态码分为五大类别,静态爬虫中高频出现的状态码及含义如下:

  1. 2xx 成功类:200 OK,请求成功,服务器正常返回页面数据,是爬虫最希望得到的响应结果。
  2. 3xx 重定向类:301 永久重定向、302 临时重定向,页面地址发生跳转,爬虫会自动跟随跳转获取新页面内容。
  3. 4xx 客户端错误:404 Not Found(页面不存在)、403 Forbidden(禁止访问,多为反爬拦截)、400 Bad Request(请求格式错误)。
  4. 5xx 服务端错误:500 服务器内部错误、502 网关错误,代表目标网站服务器出现故障,非爬虫代码问题。

在代码中判断状态码,是排查爬虫访问异常的首要步骤。

四、requests 库实现基础网络请求

4.1 发送简单 GET 请求

使用 requests 库发送 GET 请求是静态爬虫的第一步,本节从最简代码开始,逐步叠加功能,讲解每一段代码的作用与底层原理。

4.1.1 基础 GET 请求代码示例

python

运行

# 导入第三方请求库 import requests # 定义目标网页URL url = "https://www.example.com" # 发送GET请求,获取响应对象 response = requests.get(url) # 打印HTTP状态码 print("请求状态码:", response.status_code) # 打印网页原始源码(字节流格式) print("字节流源码:", response.content) # 打印解码后的网页文本(字符串格式) print("网页文本源码:", response.text)
4.1.2 代码逐行原理解析
  1. import requests:导入已安装的 requests 第三方库,只有导入库后,程序才能调用库中封装的网络请求相关方法,这是 Python 调用外部库的标准语法。
  2. url = "https://www.example.com":定义字符串变量存储目标网页的统一资源定位符,也就是网页地址。URL 是客户端定位互联网资源的唯一标识,爬虫必须依靠 URL 确定访问目标。
  3. response = requests.get(url):调用 requests 库的get()方法向指定 URL 发送 GET 请求,该方法会自动完成网络连接、报文封装、数据接收等操作,最终返回一个Response 响应对象。这个对象并非单纯的字符串,而是封装了状态码、源码、请求头、响应头、编码格式等一系列数据的复合对象。
  4. response.status_code:读取响应对象的status_code属性,获取本次请求的 HTTP 状态码,用于判断请求是否成功。
  5. response.content:该属性返回bytes 字节流数据,是服务器原始返回的数据,未经过字符编码转换。网页、图片、文件等所有网络资源,在网络传输中均以字节流形式传递,这是网络传输的底层格式。字节流适合下载图片、视频、附件等非文本类资源。
  6. response.text:该属性返回字符串文本数据,requests 库会自动根据网页默认编码,将字节流解码为人类可阅读的字符串。解析 HTML 网页源码、提取文本数据时,优先使用该属性。
4.1.3 编码问题说明

部分网页会出现response.text输出乱码的情况,根本原因是 requests 自动识别的编码格式与网页实际编码格式不匹配。中文网页常用编码为utf-8gbk,出现乱码时需要手动指定编码格式,优化代码如下:

python

运行

import requests url = "https://www.example.com" response = requests.get(url) # 手动设置编码格式,解决中文乱码 response.encoding = "utf-8" html = response.text print(html)

原理补充:网络传输的字节流没有字符概念,不同编码规则会将字节解析为不同文字。response.encoding属性用于强制指定解码规则,匹配网页真实编码后,即可消除乱码。

4.2 携带请求头的 GET 请求(伪装浏览器)

绝大多数网站会拦截无 User-Agent 的请求,上一节的基础代码在爬取常规网站时,大概率会触发 403 禁止访问错误。解决方案就是自定义请求头,模拟真实浏览器

4.2.1 携带请求头代码示例

python

运行

import requests # 目标URL url = "https://www.example.com" # 自定义请求头字典 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" } # 发送GET请求,传入请求头参数 response = requests.get(url, headers=headers) # 校验请求结果 if response.status_code == 200: response.encoding = "utf-8" print("网页源码获取成功") print(response.text) else: print(f"请求失败,状态码:{response.status_code}")
4.2.2 代码原理解析
  1. headers = {}:请求头以 Python 字典格式定义,字典的键对应请求头字段名,值对应字段内容。字典是 Python 中存储键值对数据的标准结构,与 HTTP 请求头的键值对格式完全契合,因此 requests 库采用字典接收请求头参数。
  2. headers中的User-Agent字段:复制自真实浏览器的请求头信息,作用是向服务器声明 “当前客户端为 Chrome 浏览器”,绕过基础的客户端校验规则。除 User-Agent 外,还可根据网站要求添加RefererAccept等字段,进一步完善伪装效果。
  3. requests.get(url, headers=headers)get()方法支持多个可选参数,headers为其中之一,作用是将自定义请求头附加到请求报文中,一并发送至服务器。
  4. 状态码判断逻辑:增加分支判断,仅当状态码为 200(请求成功)时,才解析并输出网页源码,否则打印错误状态码。该逻辑是工程化代码的基础,能够有效区分正常请求与异常请求,提升代码健壮性。

4.3 增加超时参数,防止程序卡死

网络环境存在不确定性,可能出现目标服务器无响应、网络中断等问题。若不设置超时时间,requests.get()方法会一直阻塞等待响应,导致爬虫程序卡死。因此在正式代码中,必须添加timeout超时参数。

4.3.1 超时设置代码示例

python

运行

import requests url = "https://www.example.com" 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" } try: # timeout单位为秒,超过设定时间未响应则抛出异常 response = requests.get(url, headers=headers, timeout=10) response.encoding = "utf-8" print("源码长度:", len(response.text)) except requests.exceptions.Timeout: print("请求超时,服务器无响应") except Exception as e: print(f"请求出现未知异常:{e}")
4.3.2 原理解析
  1. timeout=10:设置请求超时时间为 10 秒,含义是从客户端发起请求开始计时,若 10 秒内未接收到服务器完整响应,requests 库会主动终止请求,并抛出Timeout超时异常。行业内静态爬虫超时时间通常设置为 5~15 秒。
  2. try...except异常捕获结构:Python 标准的异常处理语法,将可能出现错误的网络请求代码放入try代码块中。当代码抛出指定异常时,执行对应except代码块的逻辑,程序不会直接崩溃,而是输出错误提示并继续运行。
  3. 细分异常类型:代码中单独捕获Timeout超时异常,同时设置通用异常捕获,区分不同错误类型,便于开发者定位问题。网络爬虫常见异常包含超时、连接失败、SSL 证书错误、网络中断等。

五、HTML 网页结构详解(数据提取基础)

成功获取网页源码后,下一步就是理解 HTML 结构,这是从源码中精准提取数据的核心前提。HTML 全称超文本标记语言,是构建网页的标准标记语言,所有静态网页的视觉内容、文本、链接,都由 HTML 标签组合而成。

5.1 HTML 基础标签规则

HTML 由标签组成,绝大多数标签为成对出现的双标签,格式为<标签名>内容</标签名>;少数为单标签,格式为<标签名 />。标签可以互相嵌套,形成层级化的树状结构,这也是后续解析库定位元素的核心依据。

基础语法规则:

  1. 标签名称不区分大小写,但行业规范中统一使用小写标签。
  2. 标签内部可以添加属性,格式为属性名="属性值",属性用于对标签进行补充描述,是定位元素的重要依据。
  3. 整个 HTML 页面由根标签<html>包裹,内部分为<head>头部区域与<body>主体区域,页面可见内容全部位于<body>标签内部。

5.2 静态网页高频标签介绍

结合爬虫数据提取场景,整理网页中出现频率最高的标签、属性及对应作用,如下表所示:

表格

标签名称标签类型主要作用爬虫提取场景
<title>双标签定义网页标题,显示在浏览器标签栏提取网页标题
<a>双标签超链接标签,实现页面跳转提取网址、链接文本
<p>双标签段落标签,包裹正文文本提取文章段落、描述文本
<div>双标签块级容器标签,用于布局分组定位数据区块,批量提取内容
<span>双标签行内容器标签,包裹小段文本提取局部关键词、数字
<h1>~<h6>双标签标题标签,六级标题层级提取文章标题、栏目名称
<img>单标签图片标签,展示图片提取图片地址链接
<ul>/<li>组合标签无序列表,列表项组合提取列表类数据(榜单、目录)

5.3 标签属性详解(定位元素核心)

标签属性是区分同类标签的关键,同一个页面中会存在大量重复的<div><a>标签,单纯依靠标签名无法精准找到目标数据,必须借助属性筛选。爬虫开发中最常用的三大属性:

  1. id 属性:理论上在整个 HTML 页面中唯一,格式<div id="content">,定位精度最高,优先使用。
  2. class 属性:用于给标签归类,多个标签可以共用同一个 class,格式<div class="list-item">,批量提取同类元素的首选属性。
  3. href 属性:专属<a>标签,存储链接地址,是提取 URL 的核心属性。
  4. src 属性:专属<img>标签,存储图片地址。

示例 HTML 代码片段:

html

预览

<div class="article-list"> <div class="item"> <h2 class="title">Python静态爬虫入门教程</h2> <p class="desc">本文讲解静态网页数据提取基础</p> <a href="https://www.example.com/detail">查看详情</a> </div> </div>

从这段代码可以看出,标签层层嵌套,class属性对不同区块进行分类,href存储跳转链接,完整呈现了静态网页的数据组织形式。爬虫提取数据的本质,就是根据标签名、属性、层级关系,在这段结构化文本中筛选目标内容。

六、原生字符串方法实现简易数据提取

在不使用专业 HTML 解析库的前提下,可以利用 Python 内置的字符串方法,对网页源码进行截取、匹配、分割,实现基础的数据提取。该方式能够帮助开发者理解 “从源码中捞取数据” 的底层逻辑,也是理解解析库原理的铺垫。

6.1 核心字符串方法介绍

Python 字符串内置大量处理方法,静态数据提取常用方法如下:

  1. find():查找子字符串的索引位置,找到返回起始下标,未找到返回 - 1。
  2. split():按照指定分隔符切割字符串,返回字符串列表。
  3. strip():去除字符串首尾的空格、换行符、制表符等空白字符。
  4. 字符串切片[起始下标:结束下标]:根据索引截取指定范围的字符串。

6.2 实战案例:提取网页标题

网页标题存放在<title></title>标签之间,使用字符串截取的方式提取标题,代码及原理如下:

6.2.1 代码示例

python

运行

import requests url = "https://www.example.com" 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" } try: response = requests.get(url, headers=headers, timeout=10) response.encoding = "utf-8" html = response.text # 定义前后标记字符串 start_tag = "<title>" end_tag = "</title>" # 查找起始标签的索引 start_index = html.find(start_tag) # 标题内容起始位置 = 起始标签索引 + 标签长度 content_start = start_index + len(start_tag) # 查找结束标签的索引 end_index = html.find(end_tag, content_start) # 切片截取标题内容 title = html[content_start:end_index] # 去除首尾空白字符 title = title.strip() print("网页标题:", title) except Exception as e: print("请求或解析出错:", e)
6.2.2 代码原理解析
  1. 先通过 requests 库获取完整的网页 HTML 字符串html,整个源码是一个超长的单行 / 多行字符串。
  2. 确定目标数据的左右边界标记,也就是包裹标题的<title>开始标签和</title>结束标签,这是字符串截取的核心思路。
  3. html.find(start_tag):从整个字符串中查找<title>第一次出现的位置,返回该字符的下标索引。字符串在计算机中以字符数组形式存储,每一个字符都有唯一的数字下标。
  4. content_start = start_index + len(start_tag)find()返回的是开始标签第一个字符的下标,想要获取标签内部的内容,需要跳过整个开始标签,因此加上标签字符串的长度。
  5. html.find(end_tag, content_start):第二个参数代表查找的起始位置,从标题内容开始的位置向后查找结束标签,避免匹配到页面其他位置的同名结束标签。
  6. 字符串切片html[content_start:end_index]:截取两个下标之间的所有字符,即为标题原始内容。最后使用strip()清理多余的换行、空格,得到干净的标题文本。

6.3 实战案例:批量提取超链接

网页中大量链接均由<a>标签包裹,结合find()循环匹配与字符串分割,可批量提取所有链接地址与链接文本。该案例能够体现字符串提取方式的局限性,也侧面引出专业解析库的必要性。

6.3.1 代码示例

python

运行

import requests url = "https://www.example.com" 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" } def extract_links(html_str): link_list = [] # 循环查找所有<a>标签 a_start = html_str.find("<a") while a_start != -1: # 从<a>位置向后查找href属性起始位置 href_start = html_str.find('href="', a_start) if href_start == -1: break # 链接地址起始位置 url_start = href_start + len('href="') # 查找链接结束的双引号 url_end = html_str.find('"', url_start) # 截取链接地址 link_url = html_str[url_start:url_end] # 查找链接文本结束位置(</a>标签) a_end = html_str.find("</a>", url_end) # 截取链接文本 link_text = html_str[url_end + 1:a_end].strip() # 存入列表 link_list.append({"链接地址": link_url, "链接文本": link_text}) # 从下一个位置继续查找下一个<a>标签 a_start = html_str.find("<a", a_end) return link_list try: res = requests.get(url, headers=headers, timeout=10) res.encoding = "utf-8" html_content = res.text links = extract_links(html_content) # 遍历输出结果 for item in links: print(item) except Exception as e: print("执行异常:", e)
6.3.2 原理与局限性分析
  1. 原理逻辑:延续 “标记截取” 思路,通过while循环反复查找<a>标签,逐个提取href属性内的链接地址与标签内部的文本内容,将结果以字典形式存入列表,实现批量提取。
  2. 明显局限性:
    • 容错率极低:若网页 HTML 格式发生微小变化(如标签内增加空格、属性顺序调换、使用单引号替代双引号),代码会直接提取失败。
    • 代码冗余复杂:面对多层嵌套、复杂结构的 HTML 页面,需要编写大量循环与判断逻辑,开发效率极低。
    • 无法精准定位:不能根据classid等属性筛选指定范围内的链接,只能全局匹配所有<a>标签。

正是由于原生字符串方法存在以上缺陷,行业内才诞生了 BeautifulSoup、lxml 等专业 HTML/XML 解析库,这类库会将 HTML 文本转换为树形结构,基于节点、标签、属性进行智能匹配,大幅降低数据提取难度。原生字符串方法仅适合理解底层逻辑,正式项目中不推荐使用。

七、爬虫基础优化与合规性规范

7.1 请求延时设置,规避访问限制

高频、不间断的请求会给目标服务器造成压力,同时极易触发网站反爬机制,导致 IP 被临时封禁。在循环爬取多个页面的场景中,必须添加请求延时,模拟人类正常浏览网页的行为节奏。

Python 内置time模块可实现延时功能,代码示例:

python

运行

import requests import time url_list = [ "https://www.example.com/1", "https://www.example.com/2", "https://www.example.com/3" ] 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" } for url in url_list: response = requests.get(url, headers=headers, timeout=10) print(f"已爬取:{url},状态码:{response.status_code}") # 延时2秒,再执行下一次请求 time.sleep(2)

原理说明:time.sleep(n)表示程序暂停运行 n 秒,单位为秒。常规静态爬虫延时设置为 1~3 秒即可,访问防护严格的网站可适当延长延时时间。

7.2 数据本地存储(文本文件)

提取到的数据若仅在控制台输出,无法长期保存,入门阶段最简易的存储方式为写入本地txt文本文件。Python 内置文件操作语法,无需额外安装库。

7.2.1 追加写入文件代码示例

python

运行

import requests url = "https://www.example.com" 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" } try: res = requests.get(url, headers=headers, timeout=10) res.encoding = "utf-8" html = res.text # 截取标题 s1 = html.find("<title>") + len("<title>") s2 = html.find("</title>", s1) title = html[s1:s2].strip() # 以追加模式打开文件,编码指定为utf-8,避免中文乱码 with open("spider_data.txt", "a", encoding="utf-8") as f: f.write(f"网页标题:{title}\n") print("数据已保存至本地文件") except Exception as e: print("出错:", e)

原理说明:open()函数用于打开本地文件,"a"代表追加写入模式,新数据会续写在文件末尾;"w"为覆盖写入模式,会清空原有内容。with语句可以自动关闭文件流,是 Python 推荐的文件操作写法。

7.3 爬虫合规性与行业准则

  1. 遵守robots.txt协议:几乎所有正规网站根目录下都存在robots.txt文件,该文件明确标注了网站允许 / 禁止爬虫访问的目录与页面,爬取前建议优先查看。
  2. 禁止抓取隐私与版权数据:用户手机号、身份证、个人相册等隐私数据,以及付费文章、影视资源、原创图文等版权内容,严禁私自抓取与传播。
  3. 控制请求频率:无论网站是否有反爬措施,都需要设置合理延时,拒绝高频轰炸式请求,维护网络服务稳定。
  4. 禁止恶意攻击:爬虫的核心用途为数据采集,不得利用爬虫技术发起 DDoS 攻击、批量注册、恶意刷量等违规行为。

八、综合实战:完整静态网页爬虫项目

结合前文所有知识点,搭建一套完整、可运行、具备异常处理、延时、数据存储的静态网页综合爬虫案例,实现 “多页面遍历、数据提取、本地存储” 全流程,整合网络请求、编码处理、字符串提取、异常捕获、延时、文件存储等所有基础知识点。

8.1 项目需求

批量爬取多个静态页面,提取每个页面的标题、页面简介,将所有数据统一保存至本地文本文件,要求:伪装浏览器请求、设置超时、异常捕获、请求延时、中文不乱码。

8.2 完整项目代码

python

运行

# 导入所需模块 import requests import time # 1. 全局配置项 # 待爬取的页面地址列表 target_urls = [ "https://www.example.com/page1", "https://www.example.com/page2", "https://www.example.com/page3" ] # 模拟浏览器请求头 request_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" } # 请求超时时间 time_out = 10 # 页面请求间隔时间 sleep_time = 2 # 2. 定义数据提取函数 def parse_html(html_content): """ 解析HTML源码,提取标题与简介 :param html_content: 网页源码字符串 :return: 标题、简介 """ # 提取标题 title_start = html_content.find("<title>") title_end = html_content.find("</title>", title_start) title = html_content[title_start + len("<title>"):title_end].strip() # 提取简介(假设简介位于<p class="intro">标签内) intro_start = html_content.find('<p class="intro">') intro_end = html_content.find("</p>", intro_start) intro = html_content[intro_start + len('<p class="intro">'):intro_end].strip() return title, intro # 3. 主爬虫逻辑 def main_spider(): print("===== 静态网页爬虫开始运行 =====") # 以追加模式打开文件,统一存储数据 with open("static_spider_result.txt", "a", encoding="utf-8") as file: for index, url in enumerate(target_urls): print(f"正在爬取第{index + 1}个页面:{url}") try: # 发送GET请求 response = requests.get( url=url, headers=request_headers, timeout=time_out ) # 判断请求状态 if response.status_code != 200: print(f"页面访问失败,状态码:{response.status_code}") # 写入错误信息 file.write(f"链接:{url} 访问失败,状态码:{response.status_code}\n") # 延时后继续下一个页面 time.sleep(sleep_time) continue # 设置编码,处理中文乱码 response.encoding = "utf-8" html_text = response.text # 调用解析函数提取数据 page_title, page_intro = parse_html(html_text) # 控制台输出结果 print(f"页面标题:{page_title}") print(f"页面简介:{page_intro}") # 数据写入本地文件 save_content = f"链接地址:{url}\n标题:{page_title}\n简介:{page_intro}\n-------------------------\n" file.write(save_content) except requests.exceptions.Timeout: print(f"页面 {url} 请求超时") file.write(f"链接:{url} 请求超时\n-------------------------\n") except Exception as e: print(f"页面 {url} 出现未知异常:{str(e)}") file.write(f"链接:{url} 异常信息:{str(e)}\n-------------------------\n") # 每个页面爬取完成后延时 time.sleep(sleep_time) print("===== 所有页面爬取完成,数据已保存 =====") # 程序入口 if __name__ == "__main__": main_spider()

8.3 项目整体原理与代码分层解析

  1. 全局配置区:将 URL 列表、请求头、超时时间、延时时间统一定义为全局变量,后期修改爬取地址、调整延时仅需修改此处,代码可维护性更强,是工程化编程的基础规范。
  2. 数据提取函数parse_html:将 HTML 解析、数据截取逻辑封装为独立函数,实现代码解耦。函数接收网页源码参数,返回提取后的标题与简介,符合 Python 函数化编程思想。
  3. 主函数main_spider:作为爬虫核心执行入口,采用for循环遍历所有目标 URL,实现多页面批量爬取。
  4. 多层异常处理:单独捕获超时异常,同时设置通用异常捕获,区分不同故障类型,保证单个页面出错不会导致整个爬虫程序终止。
  5. 文件存储逻辑:全程使用with语句操作文件,所有页面的数据统一写入同一个文本文件,格式规整,便于后续查阅。
  6. 请求延时逻辑:每完成一个页面的请求与解析,执行time.sleep()延时,模拟正常浏览行为,降低被反爬拦截的概率。

8.4 项目拓展方向

本案例为纯静态网页入门爬虫,基于现有代码可进行多维度拓展,也是后续进阶学习的方向:

  1. 适配分页爬取:分析网站分页 URL 规则,自动拼接分页地址,实现全站分页数据爬取。
  2. 替换解析方式:使用 BeautifulSoup、XPath 等专业解析方式替代原生字符串截取,提升代码稳定性。
  3. 更换存储介质:将文本文件存储替换为 CSV、Excel、轻量级数据库,适配大批量数据存储场景。
  4. 添加代理 IP:针对 IP 封禁严重的网站,增加代理池功能,切换不同 IP 发起请求。

九、常见问题排查与总结

9.1 入门阶段高频问题及解决方案

结合静态爬虫入门学习过程中学习者遇到的典型问题,整理故障现象、原因与对应解决办法,如下表:

表格

故障现象产生原因解决方案
运行代码提示ModuleNotFoundError: No module named 'requests'未安装 requests 库,或多 Python 版本环境冲突执行pip install requests重新安装,确认使用对应版本 pip
网页输出内容中文乱码自动编码识别错误手动设置response.encoding = "utf-8"gbk
请求返回 403 Forbidden服务器识别为爬虫,拒绝访问补充完整 User-Agent 请求头,模拟浏览器
程序长时间无响应、卡死网络无响应,未设置超时添加timeout参数,设置请求超时时间
部分标签内容提取为空字符串截取的标记不匹配核对 HTML 源码,修正截取的前后标签、属性

9.2 全文知识总结

本文作为 Python 静态网页数据提取的入门内容,完整覆盖了从环境搭建、网络原理、请求实现、HTML 解读、数据提取到项目实战的全流程知识,核心知识点梳理如下:

  1. 明确静态网页核心特征:页面所有可见内容均包含在初始 HTML 源码中,无需处理动态加载逻辑,是爬虫入门的最优场景。
  2. 掌握 requests 库核心用法:GET 请求发送、请求头伪装、超时设置、异常捕获,这是 Python 爬虫网络请求的通用基础。
  3. 理解 HTML 树形结构与标签、属性规则,能够借助浏览器开发者工具定位目标数据所在的标签位置。
  4. 掌握 Python 字符串截取的底层提取逻辑,理解专业解析库的设计初衷与优势。
  5. 具备基础工程化思维:代码分层、函数封装、请求延时、数据持久化、异常处理,保证爬虫程序稳定运行。
  6. 树立合规爬虫意识,遵守网络相关法规与网站规则,做到合法使用爬虫技术。

静态网页爬虫是整个 Python 爬虫体系的基石,本文所讲解的网络请求、异常处理、文件存储、代码规范等内容,同样适用于后续动态网页爬取、接口爬取、分布式爬虫等高阶场景。完成本文学习与案例实操后,读者已具备独立开发简易静态爬虫的能力,后续可继续学习专业 HTML 解析库、正则表达式、反爬应对、数据库存储等进阶内容,逐步构建完整的爬虫技术栈。

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

如何降低谷歌广告CPC?广告投放成本一个月下降50美元

去年帮一家卖办公用品的客户调整后&#xff0c;他们的平均CPC从4.2美元降到2.8美元左右&#xff0c;一个月广告费省了差不多55美元。不是靠什么神秘技巧&#xff0c;就是盯着质量得分、关键词匹配和页面体验这些地方一点点改。普通市场人员也能上手&#xff0c;下面分享具体怎么…

作者头像 李华
网站建设 2026/6/12 7:10:51

Java实现RTP视频流采集、同步播放与本地文件录制(基于JMF)

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;一套开箱即用的Java音视频处理示例&#xff0c;利用JMF框架完成RTP协议下的实时视频流捕获&#xff08;支持摄像头或网络源&#xff09;、音视频同步解码播放、以及AVI/MP4格式本地存储。包含主控制界面mainFra…

作者头像 李华
网站建设 2026/6/12 7:02:53

1MRK002122-ABR03继电器接口板

ABB 1MRK002122-ABR03 继电器接口板产品特点开头&#xff1a; ABB 1MRK002122-ABR03 是 Relion 615 系列的一款高性能数字式馈线保护与测控继电器&#xff0c;集保护、控制、测量、监视和通信功能于一体&#xff0c;专为中压配电网络设计。中间&#xff08;15条特点&#xff09…

作者头像 李华
网站建设 2026/6/12 7:02:53

如何快速下载抖音无水印视频:面向新手的完整实战指南

如何快速下载抖音无水印视频&#xff1a;面向新手的完整实战指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback suppor…

作者头像 李华
网站建设 2026/6/12 6:57:57

可视化开发新范式:Builder.io如何让前端开发效率提升300%

可视化开发新范式&#xff1a;Builder.io如何让前端开发效率提升300% 【免费下载链接】builder Visual Development for React, Vue, Svelte, Qwik, and more 项目地址: https://gitcode.com/GitHub_Trending/bu/builder 你是否曾为前端开发中的这些问题而烦恼&#xff…

作者头像 李华