urllib3学习笔记
urllib3学习笔记
urllib3简介
urllib3是个功能强大、条理清晰,用于HTTP客户端的第三方模块,许多Python的原生系统已经开始使用urllib3。urllib3提供了很多Python标准库里没有的重要特性:
• 线程安全
• 连接池
• 客户端SSL/TLS验证
• 使用multipart编码上传文件
• Helpers 用于重试请求并处理HTTP重定向
• 支持gzip和deflate编码
• 支持HTTP和SOCKS代理
• 100%的测试覆盖率
发送网络请求
GET请求
使用urllib3模块发送网络请求时,首先需要创建PoolManager对象,通过该对象调用request()方法来实现网络请求的发送。request()方法的语法格式如下:
request(method, url, fields = None, headers = None, ** urlopen_kw)
常用参数说明:
§ method:必选参数,用于指定请求方式,如GET、POST、PUT等
§ url: 必选参数,用于设置需要请求的URL地址
§ fields:可选参数,用于设置请求参数
§ headers:可选参数,用于设置请求头
1、使用request()方法实现GET请求
示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :1/27/22 6:14 PM
# 文件 :request方法实现GET请求.py
# IDE :PyCharmimport urllib3 # 导入urllib3模块
url = "http://httpbin.org/get"
http = urllib3.PoolManager() # 创建连接池管理对象
r = http.request('GET',url) # 发送GET请求
print(r.status) # 打印请求状态码
运行结果:
200
2、使用PoolManager对象向多个服务器发送请求
一个PoolManager对象就是一个连接池管理对象,通过该对象可以实现向多个服务器发送请求。示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :1/27/22 6:14 PM
# 文件 :request方法实现GET请求.py
# IDE :PyCharmimport urllib3 # 导入urllib3模块
urllib3.disable_warnings() # 关闭ssl警告
jingdong_url = 'https://www.jd.com/' # 京东url地址
python_url = 'https://www.python.org/' # Python url地址
baidu_url = 'https://www.baidu.com/' # 百度url地址
http = urllib3.PoolManager() # 创建连接池管理对象
r1 = http.request('GET',jingdong_url) # 向京东地址发送GET请求
r2 = http.request('GET',python_url) # 向python地址发送GET请求
r3 = http.request('GET',baidu_url) # 向百度地址发送GET请求
print('京东请求状态码:',r1.status)
print('python请求状态码:',r2.status)
print('百度请求状态码:',r3.status)
备注
Python3.7, Python3.9.7可以正常运行以上程序,其他版本报错,即使import ssl也不能解决。
POST请求
1、使用request()方法实现POST请求
使用urllib3模块向服务器发送POST请求时,并不复杂,与发送GET请求相似,只是需要在request()方法中将method参数设置为’POST’, 然后将fields 参数设置为字典类型的表单参数。示例代码如下:
import urllib3 # 导入urllib3模块
urllib3.disable_warnings() # 关闭ssl警告
url = 'https://www.httpbin.org/post' # post请求测试地址
params = {'name':'Jack','country':'中国','age':30} # 定义字典类型的请求参数
http = urllib3.PoolManager() # 创建连接池管理对象
r = http.request('POST',url,fields=params) # 发送POST请求
print('返回结果:',r.data.decode('utf-8'))
结果如下:
备注
同样,Python3.7, Python3.9.7可以正常运行以上程序,其他版本报错,即使import ssl也不能解决。
从上图的运行结果看出,JSON信息中的form对应的数据为表单参数,只是chinese_name所对应的并不是’杰克’而是一段Unicode编码,对于这样情况,可以将请求结果编码方式设置为’unicode_escape’。如下:
print(r.data.decode('unicode_escape'))
重试请求
urllib3模块可以自动重试请求,这种相同的机制还可以处理重定向。在默认情况下request()方法的请求重试次数为3次,如果需要修改重试次数可以设置为retries参数。修改重试测试的示例代码如下:
import urllib3 # 导入urllib3模块
urllib3.disable_warnings() # 关闭ssl警告
url = 'https://www.httpbin.org/get' # get请求测试地址
http = urllib3.PoolManager() # 创建连接池管理对象
r = http.request('GET',url) # 发送GET请求,默认重试请求
r1 = http.request('GET',url,retries=5) # 发送GET请求,设置5次重试请求
r2 = http.request('GET',url,retries=False) # 发送GET请求,关闭重试请求
print('默认重试请求次数:',r.retries.total)
print('设置重试请求次数:',r1.retries.total)
print('关闭重试请求次数:',r2.retries.total)
运行结果如下:
executed in 1.78s, finished 22:07:40 2022-01-27
默认重试请求次数: 3
设置重试请求次数: 5
关闭重试请求次数: False
处理响应内容
1、获取响应头
发送网络请求后,将返回一个HTTPResponse对象,通过该对象中的info()方法即可获取HTTP响应头信息,该信息为字典(dict)类型的数据,所以需要通过for循环进行遍历才可清晰的看到每条响应头信息内容。示例代码如下:
import urllib3 # 导入urllib3模块try:urllib3.disable_warnings() # 关闭ssl警告url = 'https://www.sohu.com/get' # get请求测试地址http = urllib3.PoolManager() # 创建连接池管理对象r = http.request('GET',url) # 发送GET请求,默认重试请求response_header = r.info() # 获取响应头for key in response_header.keys(): # 循环遍历打印响应头信息print(key,':',response_header.get(key))
except:pass
运行结果如下:
executed in 484ms, finished 22:20:48 2022-01-27
Content-Type : text/html
Content-Length : 8511
Connection : keep-alive
Server : openresty
Date : Thu, 27 Jan 2022 14:20:48 GMT
Last-Modified : Wed, 27 Oct 2021 12:17:55 GMT
Vary : Accept-Encoding
ETag : "61794373-213f"
Cache-Control : no-cache, no-store, must-revalidate
Referrer-Policy : no-referrer-when-downgrade
Accept-Ranges : bytes
FSS-Cache : MISS from 3951190.5655136.5536880
FSS-Proxy : Powered by 3689042.5130844.5274728
2、JSON信息
如果服务器返回了一条JSON信息,而这条信息中只有某条数据为可用数据时,可以先将返回的JSON数据转为字典(dict)数据,接着直接获取指定键所对应的值即可。示例代码如下:
import urllib3 # 导入urllib3模块
import json # 导入json模块
try:urllib3.disable_warnings() # 关闭ssl警告url = 'https://www.httpbin.org/post' # post请求测试地址params = {'name': 'Jack', 'country': '中国', 'age': 30} # 定义字典类型的请求参数http = urllib3.PoolManager() # 创建连接池管理对象r = http.request('POST', url, fields=params) # 发送POST请求j = json.loads(r.data.decode('unicode_escape')) # 将响应数据转换为字典类型print('数据类型:', type(j))print('获取form对应的数据:', j.get('form'))print('获取country对应的数据:', j.get('form').get('country'))
except:pass
运行结果如下:
executed in 1.36s, finished 22:31:42 2022-01-27
数据类型: <class 'dict'>
获取form对应的数据: {'age': '30', 'country': '中国', 'name': 'Jack'}
获取country对应的数据: 中国
3、二进制数据
如果响应数据为二进制数据,也可以做出相应的处理。例如,响应内容为图片的二进制数据时,则可以使用open()函数,将二进制数据转换成图片。示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :1/27/22 10:48 PM
# 文件 :处理服务器返回的二进制数据.py
# IDE :PyCharmimport urllib3 # 导入urllib3模块
try:urllib3.disable_warnings() # 关闭ssl警告url = 'http://sck.rjkflm.com:666/spider/file/python.png' # 图片请求地址http = urllib3.PoolManager() # 创建连接池管理对象r = http.request('GET', url) # 发送网络请求print(r.data) # 打印二进制数据f = open('python.png', 'wb+') # 创建open对象f.write(r.data) # 写入数据f.close() # 关闭
except:pass
运行结果如下:
/Users/liuxiaowei/PycharmProjects/爬虫练习/venv/bin/python /Users/liuxiaowei/PycharmProjects/爬虫练习/Urllib3/处理响应内容/处理服务器返回的二进制数据.py
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x0e\x00\x00\x00\\\x08\x02\x00\x00\x00\x10\xe2\xcc\xba\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x.......'Process finished with exit code 0
复杂请求的发送
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 :PyCharmimport 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 Timeouturllib3.disable_warnings()
timeout = Timeout(connect=0.5, read=0.1) # 设置连接0.5秒, 读取0.1秒
from urllib3 import Timeouturllib3.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 :PyCharmimport 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 :PyCharmimport 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 :PyCharmimport 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内容较多,截取部分内容如上。
总 结:
urllib3学习笔记相关推荐
- Python学习笔记--exe文件打包与UI界面设计
exe文件打包与UI界面设计 前言 一.基于tkinter实现的UI设计 1.1 库的选择及思路 1.2 定位方法的选用 1.3 Frame控件 1.4 变量设置 1.5 批量设置 1.6 Text文 ...
- NLP学习笔记25-情绪识别实战及数据集下载
一 序 本文属于贪心NLP训练营学习笔记系列. 这节课在线性回归及正则里面穿插的讲.对于从逻辑回归开始明显感到主要就是 讲数学公式的推导了.好难. 二 情绪识别实战 Python吧就是看了点语法,所以 ...
- 爬虫(Spider)学习笔记
title: Spider(蜘蛛)笔记 date: 2018-06-30 11:23:30 tags: Spider基础 作者:李忠林 Github: https://github.com/Leezh ...
- Intel oneAPI学习笔记之环境变量配置运行一个PyTorch程序
前面两篇文章: Intel oneAPI学习笔记之基本概念&六大工具包一览 Intel oneAPI 学习笔记之 Centos 下安装 Intel® oneAPI Base Toolkit 和 ...
- PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call
您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...
- 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程
暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...
- 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移
暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...
- 2020年Yann Lecun深度学习笔记(下)
2020年Yann Lecun深度学习笔记(下)
- 2020年Yann Lecun深度学习笔记(上)
2020年Yann Lecun深度学习笔记(上)
最新文章
- cpu渲染测试软件,CineBench渲染能力测试_CPUCPU评测-中关村在线
- wkhtmltopdf
- Android底层禁用WiFi和蓝牙功能
- http协言和web本质
- python---os
- 定义EJB 3.1视图(本地,远程,无接口)
- java 6 update 3_Java(TM) 6 Update(java运行环境) V 6.0.450.6 官方版
- LeetCode 351. 安卓系统手势解锁(回溯)
- PHP正则表达式提取超链接及其标题
- 治愈系英语笔记-4-不带动词的句子
- LR:Code-29723 Error: Failed to deliver a p2p message from parent to child process, reason。。。
- 矩阵分解在推荐系统中的应用:NMF和经典SVD实战
- EasyUI 收藏夹(私藏)
- C# ocr识别(Tesseract库)
- 中兴B860AV2.1、1.1T、2.1-A-M-T,通刷线刷固件及教程
- 【Linux】CMAQ实践部署
- 数据库MySQL入门-下
- 怎样在vs2010中添加图片资源呢?
- Hadoop回顾:(一)Hadoop生态系统简介
- about 日问输入法