项目二 动态网页数据采集

用 urllib 与 requests 抓取“新闻动态”“浪潮云说”页面:请求参数、请求头、编码、异常处理。

采集第3-4周urllib · requests · HTTP10 段代码

本项目学习目标

  • 能用 urllib.request 发 GET 请求并读取网页
  • 能用 requests 设置 params、headers、timeout、编码
  • 能处理 403/404/超时/编码乱码等常见问题
  • 能把网页内容保存成本地文件

本项目任务导览

01

动态网页数据采集

使用 Urllib 模块采集"新闻动态"、使用 Requests 库采集"浪潮云说",掌握 Python 中最常用的两类 HTTP 数据采集方式。

  • 项目导言与学习目标
  • 任务 2-1 使用 Urllib 模块采集"新闻动态"
  • 任务 2-2 使用 Requests 库采集"浪潮云说"
  • 知识拓展与实例案例(3 例)
项目导言与学习目标

动态网页数据采集是数据链路的起点。

本项目将通过两个任务,分别使用 Python 标准库 Urllib 与第三方库 Requests 完成网页数据的采集,实现从网页中获取新闻动态与指定平台数据的完整过程,为后续的数据解析与处理做准备。

掌握 Urllib 模块中 request、error、parse 子模块的常用方法; 掌握 Requests 库的安装与请求方法; 掌握 Response 响应对象与常用状态码; 熟悉 Requests 的高级使用(会话、上传、超时、异常、代理)。

能够使用 Urllib 完成网页数据采集; 能够使用 Requests 完成网页数据采集; 能够处理采集过程中的异常与状态码。

03

任务 2-1 使用 Urllib 模块采集"新闻动态"

Urllib 是 Python 标准库,无需安装即可使用,包含 request、error、parse 等子模块。

一、request 模块

request 模块用于构造和发起 HTTP 请求,是 Urllib 采集数据的核心。

用于打开一个 URL,向服务器发送请求并返回响应对象。

参数说明
url请求的 URL 地址
data请求数据,默认为 None。设置该参数后请求方式变为 POST
timeout请求超时时间,单位为秒
方法说明
read()读取响应内容(字节)
readline()读取一行响应内容
readlines()按行读取所有响应内容
getcode()获取响应状态码
geturl()获取请求的 URL
decode()对响应内容进行解码
getheaders()获取响应头信息

用于构造一个完整的请求对象,可携带请求头、请求方法等信息。

参数说明
url请求的 URL 地址
data请求数据,默认为 None
headers请求头信息,常用 User-Agent、accept、Accept-Encoding、Accept-Language 等
origin_req_host请求方的主机 IP 或主机名
unverifiable请求是否无法验证,默认为 False
method请求方法,如 GET / POST / HEAD / PUT / DELETE

用于将 URL 指向的文件(如网页、图片、视频等)直接下载保存到本地文件。

PYTHON
# 将网页文件下载保存到本地
urlretrieve(url, filename)

二、error 模块

用于处理请求过程中出现的异常。

异常类说明
URLErrorURLError 的基类,由网络问题(无法连接、网络不可达等)引起。
HTTPErrorURLError 的子类,服务器返回错误状态码时抛出,具有 code(状态码)、reason(原因)、headers(响应头)等属性。

三、parse 模块

用于 URL 的解析、拼接与编码处理。

方法说明
urlparse()解析 URL,返回 6 部分:scheme(协议)、netloc(域名)、path(路径)、params(参数)、query(查询)、fragment(片段)
urljoin()拼接 URL:以第一个参数为基础,与第二个参数进行拼接
quote()将中文等特殊字符编码为 URL 安全格式(编码)
unquote()对 URL 编码内容进行解码
PYTHON
# urlparse 解析示例:http://www.example.com/path?a=1#frag
# 结果:scheme=http, netloc=www.example.com, path=/path, query=a=1, fragment=frag

四、任务实施(共 7 步)

  • 打开新闻动态网页,使用浏览器开发者工具查看网页结构;
  • 在 PyCharm 中新建 Python 项目与文件;
  • 导入 urllib.request 模块,编写代码请求网页;
  • 设置 Request 请求头(User-Agent 等)模拟浏览器;
  • 调用 urlopen() 获取响应,使用 read().decode() 解码页面内容;
  • 将获取到的页面数据保存到本地文件;
  • 运行程序,查看采集结果并验证数据完整性。
04

任务 2-2 使用 Requests 库采集"浪潮云说"

Requests 是优雅、简单的 Python HTTP 请求库,比 Urllib 更易用。

一、Requests 简介及安装

Requests 是一个简单易用的第三方 HTTP 库,基于 urllib3 开发,API 设计人性化,是当前 Python 网页数据采集最常用的库之一。

  • 打开 cmd 命令窗口;
  • 执行 pip install requests 命令(或下载 wheel 文件安装);
  • 等待依赖包自动下载安装完成;
  • 进入 Python 交互式命令行,通过 import requests 验证安装。

二、HTTP 请求类型

请求类型说明
GET请求指定的页面信息,返回响应实体
POST向指定资源提交数据进行处理(如表单提交)
HEAD类似 GET,但只返回响应头,不返回响应体
PUT向指定资源位置上传最新内容
PATCH对资源进行局部修改
DELETE请求服务器删除指定资源

三、请求方法

get(url, params=None, **kwargs) —— 发送 GET 请求,返回 Response 对象。

参数说明
url请求的 URL
paramsURL 中的查询参数(字典),会自动拼接到 URL 末尾
**kwargs其他可选参数,见下表
参数说明
data请求体数据(表单),POST 时常用
jsonJSON 格式的请求体数据
headers请求头(字典)
cookies请求携带的 Cookie
auth认证信息(如 HTTPBasicAuth)
files文件上传参数(字典)
timeout请求超时时间(秒或元组)
proxies代理设置(字典)
allow_redirects是否允许自动重定向,默认 True
stream是否流式获取响应内容,默认 False
verify是否验证 SSL 证书,默认 True
cert本地 SSL 证书路径

四、Response 对象常用属性

属性说明
status_code响应状态码(如 200、404)
text响应内容(字符串形式,自动解码)
content响应内容(字节形式)
encoding响应内容的编码方式
apparent_encoding从内容中推测出的编码方式
cookies响应中的 Cookie
url最终请求的 URL
headers响应头信息
PYTHON
# 使用示例
response = requests.get(url)
# 获取文本内容,若乱码可指定编码
response.encoding = response.apparent_encoding
print(response.text)

五、常用状态码

状态码含义
200请求成功
301永久重定向(资源已被永久移动到新 URL)
400客户端请求有语法错误,服务器无法理解
401请求未经授权(需要认证)
403服务器拒绝执行请求(无权限访问)
404请求的资源不存在
500服务器内部错误
503服务器暂时不可用(过载或维护)

六、高级使用

Session 对象可在多次请求之间保持 Cookie 等状态,适合需要登录后采集的场景。

通过 files 参数以字典形式上传文件: files = {'file': open('a.txt','rb')}

通过 timeout 参数设置等待时间,避免请求长时间挂起: timeout=(连接超时, 读取超时)

通过 verify 参数控制 SSL 证书验证;自定义证书可传 cert 参数。

通过 proxies 参数设置代理: proxies = {'http': 'http://ip:port'}

异常类说明
ConnectionError连接错误(网络问题、连接被拒绝)
HTTPErrorHTTP 错误响应
URLRequired缺少有效 URL
TooManyRedirects重定向次数过多
ConnectTimeout连接服务器超时
Timeout请求超时
PYTHON
# 异常处理示例
import requests
try:
    r = requests.get(url, timeout=10)
    r.raise_for_status()
    print(r.text)
except requests.exceptions.Timeout:
    print("请求超时")
except requests.exceptions.ConnectionError:
    print("连接错误")
except requests.exceptions.HTTPError:
    print("HTTP 错误")

七、任务实施(共 7 步)

  • 分析"浪潮云说"页面结构,确定数据所在位置;
  • 安装 Requests 库并验证;
  • 使用 get() 方法请求目标页面;
  • 设置请求头(User-Agent)模拟浏览器访问;
  • 处理响应内容(指定编码、解析文本);
  • 将采集的数据保存到本地文件;
  • 运行验证,检查数据完整性。
05

知识拓展与实例案例

课堂讲解用:3 个可运行实例 + 知识拓展卡片。

知识拓展

实例 1:urllib 伪装浏览器爬取网页并保存

目标:用 urllib 请求百度首页,设置 User-Agent 伪装浏览器,把 HTML 保存到本地文件。

PYTHON
# urllib_demo.py
import urllib.request

url = "https://www.baidu.com"
# 构造请求并添加请求头
req = urllib.request.Request(url)
req.add_header("User-Agent",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/120.0 Safari/537.36")

# 发起请求,获取响应对象
resp = urllib.request.urlopen(req, timeout=10)
html = resp.read().decode("utf-8")

# 保存到本地
with open("baidu.html", "w", encoding="utf-8") as f:
    f.write(html)
print("抓取成功,HTML 长度:", len(html))
print("状态码:", resp.status)
PYTHON
抓取成功,HTML 长度: 182413
状态码: 200
代码白话解释
import urllib.request把 Python 自带的"网络请求"工具包导入进来,后面才能用它访问网页。urllib 是标准库,不需要安装。
req = urllib.request.Request(url)把"要访问的网址"包装成一个"请求对象" req,相当于写好一张访问申请单。
req.add_header("User-Agent", ...)给申请单加上"浏览器身份说明"。很多网站只允许浏览器访问,不加这行容易被拒绝(返回 403)。
resp = urllib.request.urlopen(req, timeout=10)真正把申请单发出去,把网站的"回复"存进 resp。timeout=10 表示最多等 10 秒,防止网络卡住时程序一直等。
html = resp.read().decode("utf-8")把回复的原始字节翻译成文字(按 utf-8 编码解码),得到网页源代码。
with open("baidu.html", "w") as f: f.write(html)打开(或创建)baidu.html 文件,把网页源代码写进去保存。"with ... as" 会自动关闭文件,是推荐写法。

实例 2:Requests 携带参数请求接口并解析 JSON

目标:向天气接口发送 GET 请求,携带查询参数,把返回的 JSON 解析为 Python 字典并提取数据。

PYTHON
# requests_json.py
import requests

# 参数通过 params 传入,自动完成 URL 编码
params = {"city": "济南", "key": "your_api_key"}
resp = requests.get("https://api.example.com/weather", params=params,
                    timeout=10)
resp.raise_for_status()          # 状态码非 200 时抛出异常
data = resp.json()               # JSON 字符串 → 字典

print("城市:", data["city"])
print("温度:", data["temperature"], "℃")
print("天气:", data["weather"])
PYTHON
城市: 济南
温度: 23
天气: 多云
代码白话解释
import requests导入第三方库 requests。它不是 Python 自带的,需要先 pip install requests 安装。
params = {"city": "济南", "key": "..."}把要传给服务器的参数装进字典:城市和密钥。Requests 会把它们自动拼到网址后面(如 ?city=济南&key=...)。
resp = requests.get(url, params=params, timeout=10)向 url 发起 GET 请求,附带参数,返回的响应对象存进 resp。timeout=10 限时 10 秒。
resp.raise_for_status()检查状态码:如果是 200 就什么也不做;如果不是 200(比如 404),主动抛出异常,方便我们发现问题。
data = resp.json()把服务器返回的 JSON 字符串({"city": "济南", ...})解析成 Python 字典,之后就能用 data["城市"] 取数。
print("温度:", data["temperature"])从字典里按"键"取出温度值并打印。这就是"半结构化数据 → Python 数据结构"的落地。

实例 3:Requests 下载图片并处理异常

目标:下载一张网络图片到本地,演示异常捕获(连接错误、HTTP 错误、超时)的完整写法。

PYTHON
# requests_download.py
import requests

img_url = "https://www.example.com/images/logo.png"

try:
    resp = requests.get(img_url, timeout=10)
    resp.raise_for_status()
    with open("logo.png", "wb") as f:
        f.write(resp.content)    # 二进制内容用 resp.content
    print("图片下载成功,大小:", len(resp.content), "字节")
except requests.exceptions.ConnectionError:
    print("连接错误,请检查网络")
except requests.exceptions.Timeout:
    print("请求超时")
except requests.exceptions.HTTPError:
    print("HTTP 错误:", resp.status_code)
PYTHON
图片下载成功,大小: 24831 字节
代码白话解释
img_url = "https://..."定义要下载的图片地址。实际项目中,这个地址往往来自上一步解析出来的 @href 或 img 的 src。
try:开启"尝试"区域:把可能出错的代码放进来,出错时程序不会直接崩溃,而是跳到 except。
resp = requests.get(img_url, timeout=10)请求图片地址。图片也是数据,网络请求和请求网页一样。
resp.raise_for_status()检查状态码,非 200 主动抛异常,进入对应的 except 分支。
with open("logo.png", "wb") as f: f.write(resp.content)"wb" 表示"以二进制写入"模式打开文件(图片必须用二进制);resp.content 是图片的原始字节内容,写进文件即下载完成。
except requests.exceptions.ConnectionError:捕获"连不上服务器"类错误:网络断了、域名解析失败等,打印提示而不是崩溃。
except requests.exceptions.Timeout:捕获"超时"错误:10 秒没响应就进来,避免程序无限等待。
except requests.exceptions.HTTPError:捕获"HTTP 状态码错误":比如 404 文件不存在,打印具体状态码方便排查。