urllib3学习笔记
urllib3简介
复杂请求的发送
1、设置请求头
大多数的服务器都会检测请求头信息,判断当前请求是否来自浏览器的请求。使用request()方法设置请求头信息时,只需要为headers参数指定一个有效的字典(dict)类型的请求头信息即可。请求头信息读取后,将"User-Agent"设置为字典(dict)数据中的键,后面的数据设置为字典(dict)中的value。示例代码如下:
import urllib3 # 导入urllib3模块
urllib3.disable_warnings() # 关闭ssl警告
url = 'https://www.httpbin.org/get' # get请求测试地址
# 定义火狐浏览器请求头信息
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0'}
http = urllib3.PoolManager() # 创建连接池管理对象
r = http.request('GET', url, headers=headers, verify=False) # 发送GET请求
print(r.data.decode('utf-8')) # 打印返回内容
运行结果如下:
executed in 1.40s, finished 07:33:34 2022-01-28
{
"args": {
},
"headers": {
"Accept-Encoding": "identity",
"Host": "www.httpbin.org",
# "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0",
"X-Amzn-Trace-Id": "Root=1-61f32bd0-37ff58b06026bb395cec3423"
},
"origin": "222.163.139.128",
"url": "https://www.httpbin.org/get"
}
2、设置超时
在没有特殊要求的情况下,可以将设置超时的参数与时间填写在request()方法或者是PoolManager()实例对象中,示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :1/28/22 7:43 AM
# 文件 :设置超时.py
# IDE :PyCharm
import urllib3 # 导入urllib3模块
urllib3.disable_warnings() # 关闭ssl警告
baidu_url = 'https://www.baidu.com/' # 百度超时请求测试地址
python_url = 'https://www.python.org/' # Python超时请求测试地址
http = urllib3.PoolManager() # 创建连接池管理对象
try:
r = http.request('GET',baidu_url,timeout=0.01)# 发送GET请求,并设置超时时间为0.01秒
except Exception as error:
print('百度超时:',error)
http2 = urllib3.PoolManager(timeout=0.1) # 创建连接池管理对象,并设置超时时间为0.1秒
try:
r = http2.request('GET', python_url) # 发送GET请求
except Exception as error:
print('Python超时:',error)
运行结果如下:
executed in 447ms, finished 07:47:17 2022-01-28
百度超时: HTTPSConnectionPool(host='www.baidu.com', port=443): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x7fdfa57e8f40>, 'Connection to www.baidu.com timed out. (connect timeout=0.01)'))
如果需要更精确的设置超时,可以使用Timeout实例对象,在该对象中可以单独设置连接超时与读取超时。示例代码如下:
import urllib3
from urllib3 import Timeout
urllib3.disable_warnings()
timeout = Timeout(connect=0.5, read=0.1) # 设置连接0.5秒, 读取0.1秒
from urllib3 import Timeout
urllib3.disable_warnings()
timeout = Timeout(connect=0.5, read=0.1)
http = urllib3.PoolManager(timeout=timeout)
http.request('GET', 'https://www.python.org/')
http = urllib3.PoolManager(timeout=timeout)
http.request('GET', 'https://www.python.org/')
或者是
timeout = Timeout(connect=0.5, read = 0.1) # 设置连接0.5秒,读取0.1秒
http = urllib3.PoolManager() # 创建连接池管理对象
http.request('GET', 'https://www.python.org/', timeout=timeout) # 发送请求
3、设置代理IP
在设置代理IP时,需要创建PrxoyManager对象,在该对象中最好填写两个参数:一个是proxy_url,表示需要使用的代理IP,另一个参数是headers,用于模拟浏览器请求,避免被后台服务器发现。示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :1/28/22 9:19 AM
# 文件 :创建ProxyManager对象设置代理IP.py
# IDE :PyCharm
import urllib3 # 导入urllib3模块
url = "http://httpbin.org/ip" # 代理IP请求测试地址
# 定义火狐浏览器请求头信息
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0'}
# 创建代理管理对象
proxy = urllib3.ProxyManager('http://124.93.201.59:42672',headers = headers)
r = proxy.request('get',url,timeout=2.0) # 发送请求
print(r.data.decode()) # 打印返回结果
运行结果如下:
/Users/liuxiaowei/PycharmProjects/爬虫练习/venv/bin/python /Users/liuxiaowei/PycharmProjects/爬虫练习/Urllib3/复杂请求发送/创建ProxyManager对象设置代理IP.py
{
"origin": "124.93.201.59"
}
注意
免费代理存活时间比较短,如果代理IP失效,读者可以自己上网查找正确有效的代理IP。
上传文件
request()方法提供了两种比较常用的文件上传方式,一种通过fields参数以元组形式分别指定文件名、文件内容以及文件类型,这种方式适合上传文本文件时使用。示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :1/28/22 9:32 AM
# 文件 :通过指定fields参数上传文本文件.py
# IDE :PyCharm
import urllib3 # 导入urllib3模块
import json # 导入json模块
with open('test.txt') as f: # 打开文本文件
data = f.read() # 读取文件
http = urllib3.PoolManager() # 创建连接池管理对象
# 发送网络请求
r = http.request( 'POST','http://httpbin.org/post',fields={
'filefield': ('example.txt', data),})
files = json.loads(r.data.decode('utf-8'))['files'] # 获取上传文件内容
print(files) # 打印上传文本信息
运行结果如下:
{
'filefield': '在学习中寻找快乐'}
如果需要上传图片则可以用第二种方式,在request()方法中指定body参数,该参数所对应的值为图片的二进制数据,然后还需要使用headrs 参数为其指定文件类型。示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :1/28/22 10:06 AM
# 文件 :通过body参数上传图片文件.py
# IDE :PyCharm
import urllib3 # 导入urllib3模块
with open('python.jpg','rb') as f: # 打开图片文件
data = f.read() # 读取文件
http = urllib3.PoolManager() # 创建连接池管理对象
# 发送请求
r = http.request('POST','http://httpbin.org/post',body = data,headers={
'Content-Type':'image/jpeg'})
print(r.data.decode()) # 打印返回结果
运行结果如下:
{
"args": {
},
"data": "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAAALEAAABACAYAAABV55Z5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAABkjSURBVHhe7V0JnBTF9f7m2GNmbxaWBYTdBWG5QTkVwXAETJQo+eOB0YiAGuMRVBQxIT/UyOGxJkoERQQiURE0opioEAzIIQIibBaQ+5Z7Wdhrdq7/e9XTM9093dO9skFX51tqvp7q9151V71+XVVdPdha9P9....",
"files": {
},
"form": {
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "6542",
"Content-Type": "image/jpeg",
"Host": "httpbin.org",
"User-Agent": "python-urllib3/1.26.8",
"X-Amzn-Trace-Id": "Root=1-61f34fef-5a1b4e936722224d2e6c1dbf"
},
"json": null,
"origin": "222.163.139.128",
"url": "http://httpbin.org/post"
}
说明:返回的数据中data内容较多,截取部分内容如上。
总 结: