【转载】爬虫篇——urllib3的基础知识(总结)

2023-11-17

一、快速入门

1、提出请求

# 导入urllib3模块
import urllib3
# 创建一个PoolManager对象,用于处理连接池和线程安全的所有详细信息
http = urllib3.PoolManager()
# 提出请求,请使用request()
r = http.request('GET','http://httpbin.org/robots.txt')
print(r.data) # b'User-agent: *\nDisallow: /deny\n'
  • request请求
import urllib3
import json

http = urllib3.PoolManager()
r = http.request('POST','https://httpbin.org/post',fields={'hello':'world'})
print(json.loads(r.data.decode('utf-8')))

2、响应内容

  • statusdata headers 属性
import urllib3
http = urllib3.PoolManager()
r = http.request('GET',"http://httpbin.org/ip")
# 响应状态
print(r.status) # 200
# 响应数据
print(r.data) # b'{\n  "origin": "120.239.165.180"\n}\n'
# 响应头文件
print(r.headers) # HTTPHeaderDict({'Date': 'Fri, 22 Apr 2022 02:34:03 GMT', 'Content-Type': 'application/json', 'Content-Length': '34', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'})
  • JSON内容

JSON内容可以通过解码和反序列化来加载。 data请求的属性:

import json
import urllib3

http = urllib3.PoolManager()
r = http.request('GET','https://httpbin.org/ip')
json_data = json.loads(r.data.decode('utf-8'))
print(json_data) # {'origin': '120.239.165.180'}
  • 二进制内容

data 响应的属性始终设置为表示响应内容的字节字符串

import urllib3
import json

http = urllib3.PoolManager()
r = http.request('GET','http://httpbin.org/bytes/8')
print(r.data) # b'\xa6\xe6\xb6\x7f\xc1\xd7\xbb9'
  • 对响应内容使用io包装器

​ 有时候你想用 io.TextIOWrapper 或类似的对象,如直接使用 HTTPResponse 数据。要使这两个接口很好地结合在一起,需要使用 auto_close 通过将其设置为 False 。默认情况下,读取所有字节后关闭HTTP响应,这将禁用该行为:

import io
import urllib3

http = urllib3.PoolManager()
r = http.request('GET', 'https://www.qq.com', preload_content=False)
r.auto_close = False
for line in io.TextIOWrapper(r):
    print(line)

3、请求数据

3.1 报头
import urllib3
import json

http = urllib3.PoolManager()
r = http.request('GET','https://httpbin.org/headers',headers={'X-Something': 'value'})
json_data_headers = json.loads(r.data.decode('utf-8'))['headers']
print(json_data_headers)
3.2 查询参数

A、为了 GET , HEAD 和 DELETE 请求,您可以简单地将参数作为字典传递到 fields 参数 request() 。

import urllib3
import json

http = urllib3.PoolManager()

r = http.request('GET', 'https://httpbin.org/get', fields={'get_key': 'get_value'})
json_data_args = json.loads(r.data.decode('utf-8'))['args']
print(json_data_args) # {'get_key': 'get_value'}
  • POST请求的特殊点:
import urllib3
import json

http = urllib3.PoolManager()
r = http.request('POST', 'https://httpbin.org/post', fields={'post_key': 'post_value'})
json_data_form = json.loads(r.data.decode('utf-8'))['args']
print(json_data_form)  # {}

B、为了 POST 和 PUT 请求时,需要在URL中手动编码查询参数。

import urllib3
import json
from urllib.parse import urlencode

http = urllib3.PoolManager()

encoded_args = urlencode({'arg': 'value'})
url = 'https://httpbin.org/post?' + encoded_args
r = http.request('POST', url)
print(json.loads(r.data.decode('utf-8'))['args'])  # {'arg': 'value'}
3.3 表单数据

​ 为了 PUT 和 POST 请求时,urllib3将在 fields 参数提供给 request() :

import urllib3
import json

http = urllib3.PoolManager()
r = http.request('POST', 'https://httpbin.org/post', fields={'post_key': 'post_value'})
json_data_form = json.loads(r.data.decode('utf-8'))['form']
print(json_data_form) # {'post_key': 'post_value'}
3.4 JSON
import json
import urllib3

http = urllib3.PoolManager()
data = {'attribute': 'value'}
headers = {'Content-Type': 'application/json'}
encoded_data = json.dumps(data).encode('utf-8')
print(encoded_data) # b'{"attribute": "value"}'
r = http.request('POST', 'https://httpbin.org/post', body=encoded_data, headers=headers)
print(json.loads(r.data.decode('utf-8'))['json']) # {'attribute': 'value'}
3.5 文件和二进制数据
⑴ 文件为txt文档:
import urllib3
import json

http = urllib3.PoolManager()
with open('example.txt', mode='r', encoding='utf-8') as fp:
    file_data = fp.read()

r = http.request('POST', 'https://httpbin.org/post',
                 fields={
                 	 # 将文件字段指定为 (file_name, file_data)
                     'filefield': ('example.txt', file_data),
                 })
json_data_files = json.loads(r.data.decode('utf-8'))['files']
print(json_data_files) # {'filefield': '..文本文档中的内容,其中换行显示为“\n”..'}
  • 显式指定文件的MIME类型(传递第三个项):
import urllib3
import json

http = urllib3.PoolManager()
with open('example.txt', mode='r', encoding='utf-8') as fp:
    file_data = fp.read()

r = http.request('POST', 'https://httpbin.org/post',
                 fields={
                     # 下面的第三个参数,指定文件的MIME类型
                     'filefield':('example.txt',file_data,'text/plain'),
                 })
json_data_files = json.loads(r.data.decode('utf-8'))['files']
print(json_data_files) # {'filefield': '..文本文档中的内容,其中换行显示为“\n”..'}
⑵ 文件为图片:
import urllib3
import json

http = urllib3.PoolManager()
with open('img001.jpg', mode='rb') as fp:
    binary_data = fp.read()
r = http.request('POST', 'https://httpbin.org/post',
				 # 发送二进制文件时,只需指定body参数
                 body=binary_data,
                 headers={
                     # 在Content-Type,设置指定文件类型
                     'Content-type': 'image/jpeg',}
                 )
json_data = json.loads(r.data.decode('utf-8'))['data']
print(json_data)

4、使用超时

4.1 控制请求在中止之前允许运行多长时间(以秒为单位)
import urllib3

http = urllib3.PoolManager()
# timeout 超过设置的4.0秒后,自动断开,并报错
r = http.request('GET', 'https://httpbin.org/delay/3', timeout=4.0)
print(r)  # <urllib3.response.HTTPResponse>

# timeout 超过设置的2.5秒后,自动断开,并报错
r1 = http.request('GET', 'https://httpbin.org/delay/3', timeout=2.5)
print(r1)  # MaxRetryError caused by ReadTimeoutError
4.2 精细控制,允许您指定单独的连接和读取超时
# Python版本:3.6
# -*- coding:utf-8 -*-

import urllib3

http = urllib3.PoolManager()

r = http.request('GET', 'http://httpbin.org/delay/3', timeout=urllib3.Timeout(connect=1.0))
print(r)  # <urllib3.response.HTTPResponse>

r1 = http.request('GET', 'http://httpbin.org/delay/3',
timeout=urllib3.Timeout(connect=1.0, read=2.0))
print(r1)  # MaxRetryError caused by ReadTimeoutError
4.3 PoolManager,设置超时
import urllib3

http = urllib3.PoolManager(timeout=3.0)
# 同上,请求受到相同的超时
http = urllib3.PoolManager(timeout=urllib3.Timeout(connect=1.0,read=2.0))

5、重试请求和重定向

5.1 重试请求
import urllib3

http = urllib3.PoolManager()
r = http.requests('GET', 'http://httpbin.org/ip', retries=10) # 重次10次
5.2 禁用所有重试和重定向逻辑
import urllib3

http = urllib3.PoolManager()

# NewConnectionError,新建连接错误,重试连接错误,因为链接不支持重试
# r = http.request('GET', 'http://nxdomain.example.com', retries=False)
# print(r.status) # NewConnectionError错误

r1 = http.request('GET', 'https://httpbin.org/redirect/1', retries=False)
print(r1.status)  # 302
5.3 精细控制,分配重试次数和重定向(多重定向)
  • 重定向没有一步到底会报错

    比如:下方的代码 redirect=2 代表重定向2次,实际重定向还有1次,故报错

# Python版本:3.6
# -*- coding:utf-8 -*-

import urllib3

http = urllib3.PoolManager()
# Retry(5, redirect=3):总共重试 5 次,但仅限于 2 次重定向,没有重定向一步到底(位)
r = http.request('GET','http://httpbin.org/redirect/3',retries=urllib3.Retry(5, redirect=2))
print(r.status) # 报错,MaxRetryError
  • 重定向一步到底

    比如:下方的代码 redirect=3 代表重定向3次,实际重定向共3次,故没有报错

# Python版本:3.6
# -*- coding:utf-8 -*-

import urllib3

http = urllib3.PoolManager()

# Retry(5, redirect=3):总共重试 5 次,但仅限于 2 次重定向,没有重定向一步到底(位)
r = http.request('GET','http://httpbin.org/redirect/3',retries=urllib3.Retry(5, redirect=3))
print(r.status) # 200

分析上方的重定向

Retry(5, redirect=3):总共重试 5 次,但仅限于 3 次重定向

重定向由 http://httpbin.org/redirect/3 重定向到 http://httpbin.org/get,中间重定向3次,次数少了会报错
-------------------------------------
次数          重定向到(指定的网页)
1       http://httpbin.org/redirect/2
2       http://httpbin.org/redirect/1
3       http://httpbin.org/get
5.4 禁用过多重定向
import urllib3

http = urllib3.PoolManager()

r = http.request('GET', 'http://httpbin.org/redirect/3',
                 retries=urllib3.Retry(redirect=2, raise_on_redirect=False))
print(r.status) # 302
5.5 设置重试策略:规定所有请求使用相同的重试策略
  • 规定所有请求,禁用重试请求
import urllib3

# 禁用重试
http = urllib3.PoolManager(retries=False)
  • 规定所有请求,分配重试总次数和重定向
import urllib3

# 精细控制,分配重试总次数和重定向
http = urllib3.PoolManager(retries=urllib3.Retry(5, redirect=2))

6、错误和异常

import urllib3

http = urllib3.PoolManager()
try:
    http.request('GET','nx.example.com',retries=False)
except urllib3.exceptions.NewConnectionError as e:
    print('连接失败!',e)

7、日志记录

更改 urllib3 记录器的日志级别

logging.getLogger("urllib3").setLevel(logging.WARNING)

二、高级用法

1、自定义池行为

import urllib3
# 向许多不同的主机发出请求,则增加此数量可能会提高性能,同时增加内存和套接字消耗
http = urllib3.PoolManager(num_pools=50)
  • 最大连接数:同时向同一主机发出许多请求,则增加此数量可能会提高性能
import urllib3

# 二者选一
http = urllib3.PoolManager(maxsize=10)
http = urllib3.HTTPConnectionPool('https://cn.bing.com', maxsize=10)

2、stream 和 I/O

在处理大型响应时,最好将响应内容流式传输

import urllib3

http = urllib3.PoolManager()
r = http.request(
    'GET',
    'https://httpbin.org/bytes/1024',
    preload_content=False)  # 预加载连接为False,即将http连接释放回连接池,以便重新使用
for chunk in r.stream(32): # stream()允许迭代响应内容的块
    print(chunk)
  • 把response当作文件对象,可以直接使用 read() 读取数据
import urllib3

http = urllib3.PoolManager()
response = http.request(
    'GET',
    'https://httpbin.org/bytes/1024',
    preload_content=False)
print(response.read(4)) # b'\xae\x95\n\xc2'
  • 调用read()将阻塞,直到有更多响应数据可用
import urllib3
import io

http = urllib3.PoolManager()
r = http.request(
    'GET',
    'https://httpbin.org/bytes/1024',
    preload_content=False)  # 预加载连接为False,即将http连接释放回连接池,以便重新使用
reader = io.BufferedReader(r, 8)
print(reader.read(4)) # b'\xcec\x1f\r'
# 释放连接
r.release_conn()
  • 使用这个类似文件的对象来执行诸如解码内容之类的操作 codecs
import urllib3
import json
import codecs

http = urllib3.PoolManager()
reader = codecs.getreader('utf-8')
r = http.request(
    'GET',
    'http://httpbin.org/ip',
    preload_content=False)
print(json.load(reader(r)))  # {'origin': '120.239.165.180'}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【转载】爬虫篇——urllib3的基础知识(总结) 的相关文章

随机推荐

  • C语言-扫雷游戏程序设计

    文章目录 一 问题要求 1 问题描述 2 程序的功能 二 基本要求 1 要求分析 2 需求分析 四 设计概要 1 程序的设计概要 2 程序的主要流程 1 设置棋盘 2 布地雷 五 用户说明 六 测试结果 1 运行结果说明 2 测试结论 七
  • 区块链基本加密概念

    什么是区块链 目前狭义就任务就是一个超级账本 区块链可以用来做什么 可以用来无障碍的置换 既然是用来交易的 那么我们就要有一个地址存放我的资产 地址 举例比特资产地址 一个比特币地址由两部分组成 一部分是公钥哈希值经过Base58check
  • 面试:Spring&SpringMVC&Mybatis 面试必备面试题

    Spring SpringMVC Mybatis常见面试题 历史文章 多线程史上最全面试题 持续更新中 dubbo zookeeper55道高频面试题 附加答案 SpringCloud SpringBoot经典面试题 附加答案 Spring
  • linux进程snprintf函数功能,linux 之 snprintf函数用法

    int snprintf char restrict buf size t n const char restrict format 函数说明 最多从源串中拷贝n 1个字符到目标串中 然后再在后面加一个0 所以如果目标串的大小为n 的话 将
  • MapReduce实现TopN的效果

    1 背景 最近在学习Hadoop的MapReduce 此处记录一下如何实现 TopN 的效果 以及在MapReduce中如何实现 自定义分组 2 需求 我们有一份数据 数据中存在如下3个字段 订单编号 订单项和订单项价格 输出的数据 需求如
  • 最近邻检索(NN)和近似最近邻(ANN)检索

    文章目录 1 最近邻检索 Nearest Neighbor Search 1 1 概述 1 2 应用领域 2 最近邻检索的发展 2 1 精确检索 2 2 近似检索 参考文献 1 最近邻检索 Nearest Neighbor Search 1
  • 解决导入aliyun-sdk-vod-upload后仍报错的问题

    在手动下载阿里云的aliyun sdk vod upload jar包并执行mvn install install file DgroupId com aliyun DartifactId aliyun sdk vod upload Dve
  • STM32 Freertos 添加 外部sram heap_5.c

    1 添加外部SRAM 初始化 2 添加heap 5 c 3 初始化heap 5 c 外部堆栈 Define the start address and size of the two RAM regions not used by the
  • MYSQL基础命令及添加用户及权限操作

    用root管理打开mysql 1 连接数据库 mysql u root p或者 mysql h192 168 222 132 uroot p通过ip远程连接数据库 mysql h host u user p password P port
  • 啊哈C语言——安装啊哈C编译器

    安装啊哈C编译器 首先访问啊哈C语言编译器的官网www ahacpp com 下载啊哈 C语言编译器安装包 Windows 单击下载之后会跳转到腾讯微云 选中文件复选框 然后单击保存微云 这个时候会弹出登录框 选择自己喜欢的登录方式 然后再
  • 华为OD机试 - 全量和已占用字符集(Java)

    题目描述 给定两个字符集合 一个是全量字符集 一个是已占用字符集 已占用字符集中的字符不能再使用 要求输出剩余可用字符集 输入描述 输入一个字符串 一定包含 前为全量字符集 后的为已占用字符集 已占用字符集中的字符一定是全量字符集中的字符
  • drop mysql,MySQL删除大表更快的DROP TABLE办法

    本文内容遵从CC版权协议 可以随意转载 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址 http www penglixun com tech database mysql fast drop table use hard li
  • 【Python】植物大战僵尸-基于pygame模块-part2

    文章目录 版本介绍 一 种子栏类 SeedBank py 1 成员变量 2 方法 展示种子栏 二 主游戏类 MainGame py 1 成员变量 2 加载项 3 主事件项 三 最终效果 版本介绍 继上篇内容开发 该版本为ver1 1 后续版
  • go 进阶 请求代理相关: 二. ReverseProxy 基础讲解

    目录 一 ReverseProxy 基础 ReverseProxy 中提供了哪些功能 ReverseProxy 结构详解 ReverseProxy实现代理的简单示例 1 NewSingleHostReverseProxy 函数源码解释 2
  • 元宇宙大投资 & 元宇宙通证

    元宇宙大投资 元宇宙大投资 1 备战元宇宙大浪潮 元宇宙大投资 2 抓紧元宇宙本质 元宇宙大投资 3 决胜元宇宙投资 元宇宙大投资 4 元宇宙的终局 生物与数字的融合 元宇宙大投资 6 元宇宙中国之崛起 元宇宙大投资 7 全球投资脉络下的元
  • Linux 下搭建 Kafka 环境

    安装步骤 准备软件目录 mkdir datalake 上传之前下载好的安装包到 datalake 目录下 jdk 8u181 linux x64 gz kafka 2 11 2 1 0 tgz zookeeper 3 4 5 tar gz
  • Openwrt按键检测分析-窥探Linux内核与用户空间通讯机制netlink使用

    首先看一下Openwrt系统中关于按键功能的使用和修改 以18 06版本为例 按键功能实现在脚本中 比如18 06 package base files files etc rc button reset bin sh lib functi
  • 【闲趣】软链接:拯救你的C盘

    转载 本文主要解决电脑系统盘空间问题 虽然有一些软件我们修改了安装路径 但是无可避免的是还是有一些文件装在了C盘里 有没有什么办法可以把它们全部放到非系统盘呢 自从上次重装系统之后 电脑上的3dsmax也用不了了 今天想重新下载回来 但是之
  • Unity Frame Debugger和Profiler连接Android真机调试

    当用Profiler分析到不是代码导致的性能问题 当前场景最大的性能瓶颈是渲染时 或者自己写的Shader要调试时 都可以用Frame Debugger进行调试 按下列步骤设置打包 既可以用Profiler又可以用Frame Debugge
  • 【转载】爬虫篇——urllib3的基础知识(总结)

    一 快速入门 1 提出请求 导入urllib3模块 import urllib3 创建一个PoolManager对象 用于处理连接池和线程安全的所有详细信息 http urllib3 PoolManager 提出请求 请使用request