Urllib
urllib 包 包含以下几个模块:
- urllib.request - 打开和读取 URL。
- urllib.error - 包含 urllib.request 抛出的异常。
- urllib.parse - 解析 URL。
- urllib.robotparser - 解析 robots.txt 文件。

urllib.request
urllib.request 定义了一些打开 URL 的函数和类,包含授权验证、重定向、浏览器 cookies 等。
urllib.request 可以模拟浏览器的一个请求发起过程。
我们可以使用 urllib.request 的 urlopen 方法来打开一个 URL,语法格式如下:
1urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
- url:url 地址。
- data:发送到服务器的其他数据对象,默认为 None。
- timeout:设置访问超时时间。
- cafile 和 capath:cafile 为 CA 证书, capath 为 CA 证书的路径,使用 HTTPS 需要用到。
- cadefault:已经被弃用。
- context:ssl.SSLContext 类型,用来指定 SSL 设置。
1import urllib.request as req
2
3url = 'https://ys.mihoyo.com/'
4# 基本使用
5
6# 类型和方法
7# 模拟浏览器向服务器发送请求
8res1 = req.urlopen(url)
9
10# HTTPResponse 类型
11print(type(res1))
12
13# read 方法 返回的是字节形式的二进制数据
14# 参数为空返回全部字节,传人数字就读取多个字节
15# decode 为解码,把二进制的数据转换为某个编码类型的数据
16context1 = res1.read().decode('utf8')
17print(context1)
18
19# 读取一行
20context2 = res1.readline()
21print(context2)
22
23# 一行一行读取直到结束
24context3 = res1.readlines()
25print(context3)
26
27# 返回请求状态吗
28print(res1.getcode())
29# 返回url
30print(res1.geturl())
31# 返回状态信息
32print(res1.getheaders())
33
34# 下载
35# 参数1url是要下载的路径,第二个参数是文件的名称filename
36urllib = req.urlretrieve()
模拟头部信息
我们抓取网页一般需要对 headers(网页头信息)进行模拟,这时候需要使用到 urllib.request.Request 类:
1class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
- url:url 地址。
- data:发送到服务器的其他数据对象,默认为 None。
- headers:HTTP 请求的头部信息,字典格式。
- origin_req_host:请求的主机地址,IP 或域名。
- unverifiable:很少用整个参数,用于设置网页是否需要验证,默认是 False。。
- method:请求方法, 如 GET、POST、DELETE、PUT 等。
1import urllib.request
2import urllib.parse
3
4url = 'https://www.runoob.com/?s=' # 菜鸟教程搜索页面
5keyword = 'Python 教程'
6key_code = urllib.parse.quote(keyword) # 对请求进行编码
7url_all = url+key_code
8header = {
9 'User-Agent':'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
10} #头部信息
11request = urllib.request.Request(url_all,headers=header)
12reponse = urllib.request.urlopen(request).read()
13
14fh = open("./urllib_test_runoob_search.html","wb") # 将文件写入到当前目录中
15fh.write(reponse)
16fh.close()
请求对象的定制
UA 介绍:User Agent 中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统
及版本、CPU 类型、浏览器及版本。浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等
urllib.parse
urllib.parse 用于解析 URL,格式如下:
1urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
urlstring 为 字符串的 url 地址,scheme 为协议类型,
allow_fragments 参数为 false,则无法识别片段标识符。相反,它们被解析为路径,参数或查询组件的一部分,并 fragment 在返回值中设置为空字符串。
以上实例输出结果为:
完整内容如下:
属性 |
索引 |
值 |
值(如果不存在) |
scheme |
0 |
URL 协议 |
scheme 参数 |
netloc |
1 |
网络位置部分 |
空字符串 |
path |
2 |
分层路径 |
空字符串 |
params |
3 |
最后路径元素的参数 |
空字符串 |
query |
4 |
查询组件 |
空字符串 |
fragment |
5 |
片段识别 |
空字符串 |
username |
|
用户名 |
None |
password |
|
密码 |
None |
hostname |
|
主机名(小写) |
None |
port |
|
端口号为整数(如果存在) |
None |
.quote()方法
将中文字符转换成 Unicode 编码格式
1kwd = urllib.parse.quote('原神')
2print(kwd) # %E5%8E%9F%E7%A5%9E
.urlencode()方法
可以将字典转化成 query 穿惨格式
1data = {
2 'wd':'原神'
3}
4data = urllib.parse.urlencode(data)
5print(data) # wd=%E5%8E%9F%E7%A5%9E
urllib.error
urllib.error 模块为 urllib.request 所引发的异常定义了异常类,基础异常类是 URLError。
urllib.error 包含了两个方法,URLError 和 HTTPError。
URLError 是 OSError 的一个子类,用于处理程序在遇到问题时会引发此异常(或其派生的异常),包含的属性 reason 为引发异常的原因。
HTTPError 是 URLError 的一个子类,用于处理特殊 HTTP 错误例如作为认证请求的时候,包含的属性 code 为 HTTP 的状态码, reason 为引发异常的原因,headers 为导致 HTTPError 的特定 HTTP 请求的 HTTP 响应头。
对不存在的网页抓取并处理异常:
1import urllib.request
2import urllib.error
3
4myURL1 = urllib.request.urlopen("https://www.runoob.com/")
5print(myURL1.getcode()) # 200
6
7try:
8 myURL2 = urllib.request.urlopen("https://www.runoob.com/no.html")
9except urllib.error.HTTPError as e:
10 if e.code == 404:
11 print(404) # 404
encode()方法
描述
encode() 方法以 encoding 指定的编码格式编码字符串。errors 参数可以指定不同的错误处理方案。
语法
encode()方法语法:
1str.encode(encoding='UTF-8',errors='strict')
参数
- encoding -- 要使用的编码,如"UTF-8"。
- errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个 UnicodeError。 其他可能得值有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通过 codecs.register_error() 注册的任何值。
返回值
该方法返回编码后的字符串。
decode()方法
描述
decode() 方法以 encoding 指定的编码格式解码字符串。默认编码为字符串编码。
语法
decode()方法语法:
1str.decode(encoding='UTF-8',errors='strict')
参数
- encoding -- 要使用的编码,如"UTF-8"。
- errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个 UnicodeError。 其他可能得值有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通过 codecs.register_error() 注册的任何值。
返回值
该方法返回解码后的字符串。
post 请求案例百度翻译
- Post 请求的参数必须编码,先通过
urlencode
转换为二进制形式,在通过encode
转换为utf-8
- 响应回来的数据是 json 需要进行反序列(loads)
1import json
2import urllib.request as request
3import urllib.parse as parse
4
5url = 'https://fanyi.baidu.com/sug'
6
7headers = {
8 "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
9}
10
11data = {
12 'kw': 'spider'
13}
14
15# post 请求参数必须进行编码
16# urlencode 是讲对象转化为query路径参数的形式(kw=spider),如果用post请则必须通过encode('utf-8')在将其转化为二进制形式
17data = parse.urlencode(data).encode('utf-8')
18
19# 请求对象定制
20UrlALl = request.Request(url, data, headers=headers)
21
22# 发送请求
23response = request.urlopen(UrlALl)
24
25# 请求响应数据
26context = response.read().decode('utf8')
27
28obj = json.loads(context)
29
30print(obj)
Cookie 反爬
有的加密接口会携带 cookie 或者其他令牌,这个不是固定的每个接口安全方式不一样,所有需要去分析,一般 cookie 是最常见的,在 headers 中添加
1headers = {
2 'Cookie': 'BAIDUID=A78C83243EC370D64EB9127421CDCD80:FG=1; BAIDUID_BFESS=A78C83243EC370D64EB9127421CDCD80:FG=1; BDUSS=duU0hBbzJhflBMQVZRMzB1Q0xRcHVKendKdnhRVjhiZkN1RzRwd0duQmc1eHRqSVFBQUFBJCQAAAAAAAAAAAEAAACWCc5fZ3bXytS0aG91c2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGBa9GJgWvRiNV; BDUSS_BFESS=duU0hBbzJhflBMQVZRMzB1Q0xRcHVKendKdnhRVjhiZkN1RzRwd0duQmc1eHRqSVFBQUFBJCQAAAAAAAAAAAEAAACWCc5fZ3bXytS0aG91c2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGBa9GJgWvRiNV; BIDUPSID=A78C83243EC370D64EB9127421CDCD80; PSTM=1660276134; ZFY=lTybp1mqT34VXA1zk3GnQ7ZEuvOwOkTsrZ5peYD5HLk:C; APPGUIDE_10_0_2=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1660527759; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1660527759; ab_sr=1.0.1_Y2RiYmNlYzA0MTQ1ZjA4Y2UzYWVjMDRmZWQxZjIwOTAyMGY3MDdmOThhYjIyZDk3ZTg2ZWE0OGE2YmIxYTBkNjIxYWI2ZGY3NjMzYmZiMTUwYjZkYTVkMWFhMzgzZWNlZjk4ZjYzYjRlODI1OTE5NjNhNDk1YTNmYzA2YTZjZDc1OGM2M2ZiMDkyM2JhMWU2MDExNWQwMWNmZWMyNTA3ZWViNmQzZjlmNGFjZWUwOGNmYmFkZDhhNDQxYjFlNTZi'
3}
handler 代理
1xxxxx
2
3request = request.Request(url, data, headers)
4
5proxies = {
6 'http':xxxxx
7}
8
9# hander build_opener open
10handler = urllib.request.build_.ProxyHandler(proxies = proxies)
11
12openr = urllib.request.build_opener(handler)
13
14response = openr.open(request)
15
16xxxxx