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学习笔记相关推荐

  1. Python学习笔记--exe文件打包与UI界面设计

    exe文件打包与UI界面设计 前言 一.基于tkinter实现的UI设计 1.1 库的选择及思路 1.2 定位方法的选用 1.3 Frame控件 1.4 变量设置 1.5 批量设置 1.6 Text文 ...

  2. NLP学习笔记25-情绪识别实战及数据集下载

    一 序 本文属于贪心NLP训练营学习笔记系列. 这节课在线性回归及正则里面穿插的讲.对于从逻辑回归开始明显感到主要就是 讲数学公式的推导了.好难. 二 情绪识别实战 Python吧就是看了点语法,所以 ...

  3. 爬虫(Spider)学习笔记

    title: Spider(蜘蛛)笔记 date: 2018-06-30 11:23:30 tags: Spider基础 作者:李忠林 Github: https://github.com/Leezh ...

  4. Intel oneAPI学习笔记之环境变量配置运行一个PyTorch程序

    前面两篇文章: Intel oneAPI学习笔记之基本概念&六大工具包一览 Intel oneAPI 学习笔记之 Centos 下安装 Intel® oneAPI Base Toolkit 和 ...

  5. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  6. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  7. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  8. 2020年Yann Lecun深度学习笔记(下)

    2020年Yann Lecun深度学习笔记(下)

  9. 2020年Yann Lecun深度学习笔记(上)

    2020年Yann Lecun深度学习笔记(上)

最新文章

  1. cpu渲染测试软件,CineBench渲染能力测试_CPUCPU评测-中关村在线
  2. wkhtmltopdf
  3. Android底层禁用WiFi和蓝牙功能
  4. http协言和web本质
  5. python---os
  6. 定义EJB 3.1视图(本地,远程,无接口)
  7. java 6 update 3_Java(TM) 6 Update(java运行环境) V 6.0.450.6 官方版
  8. LeetCode 351. 安卓系统手势解锁(回溯)
  9. PHP正则表达式提取超链接及其标题
  10. 治愈系英语笔记-4-不带动词的句子
  11. LR:Code-29723 Error: Failed to deliver a p2p message from parent to child process, reason。。。
  12. 矩阵分解在推荐系统中的应用:NMF和经典SVD实战
  13. EasyUI 收藏夹(私藏)
  14. C# ocr识别(Tesseract库)
  15. 中兴B860AV2.1、1.1T、2.1-A-M-T,通刷线刷固件及教程
  16. 【Linux】CMAQ实践部署
  17. 数据库MySQL入门-下
  18. 怎样在vs2010中添加图片资源呢?
  19. Hadoop回顾:(一)Hadoop生态系统简介
  20. about 日问输入法

热门文章

  1. 新博智慧救助 | 龙港市“就业启航”帮扶体系解决方案案例
  2. 八年Java开发心路历程,燕郊开发区java工程师招聘
  3. 禁用 Windows 远程桌面连接(mstsc)快捷键
  4. Shopify怎么添加发货方式
  5. wtfjs:一个有趣和棘手的 JavaScript 示例列表
  6. js绝对值(负值转正)
  7. Java SE 基础一
  8. js散度python代码踩坑
  9. Python图像处理八:图像频域滤波
  10. 关于位,字节和字的区别