-
2022-01-28 11:00:18
一种对requests各种请求方法的封装,提高使用效率,特别注意的是data格式(具体业务具体分析),有的是json格式,直接上代码吧。
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Author : Jianhua Wang # @Site : # @File : HttpHandle.py # @Software: PyCharm import requests import json import warnings class HttpHandle: def __init__(self): self.http = requests.session() self.headers = {"Content-Type": "application/json;charset=UTF-8"} self.result = None warnings.simplefilter("ignore", ResourceWarning) def get(self, url, params=None, **kwargs): """重构get方法""" try: if "headers" not in kwargs: kwargs['headers'] = self.headers # kwargs['headers'] = {"Accept":"application/json"} res = self.http.get( url, params=params, **kwargs
更多相关内容 -
python requests指定出口ip的例子
2020-09-18 23:23:26今天小编就为大家分享一篇python requests指定出口ip的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
构建高效的python requests长连接池详解
2020-09-16 22:19:42主要介绍了构建高效的python requests长连接池详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
Python requests上传文件实现步骤
2020-12-16 21:46:34官方文档:https://2.python-requests.org//en/master/ 工作中涉及到一个功能,需要上传附件到一个接口,接口参数如下: 使用http post提交附件 multipart/form-data 格式,url : http://test.com/flow/upload, ... -
python requests模块及依赖包.zip
2020-06-24 14:24:15python requests模块的安装包,以及requests所需的依赖包certifi、chardet等等 -
Python requests获取网页常用方法解析
2020-09-17 21:51:29主要介绍了Python requests获取网页常用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
python requests post多层字典的方法
2020-09-19 19:17:02今天小编就为大家分享一篇python requests post多层字典的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
python requests.post带head和body的实例
2020-09-19 19:06:34今天小编就为大家分享一篇python requests.post带head和body的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
win与linux系统中python requests 安装
2020-09-21 11:59:47requests是Python的一个HTTP客户端库,跟urllib,urllib2类似,今天我们主要来谈谈win与linux系统中python requests的安装方法以及使用指南 -
python requests官方中文文档( 高级用法 Requests 2.18.1 文档 )
2018-08-13 23:24:55python requests官方中文文档,进阶用法。本文档覆盖了requests库的一些高级特性 -
Python Requests库详解
2018-08-24 16:00:44Python Requests库详解,pdf版本,适用于爬虫初学者。 -
python requests证书问题解决
2020-09-18 16:48:23主要介绍了python requests证书问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
Python Requests Essentials.pdf 最新 原版
2018-10-30 13:28:17A fast-paced guide that demonstrates the use of Python Requests with the help of examples Learn web scraping with Beautiful Soup and Python Requests libraries Interact with social networking sites ... -
Go-Requests-Go一个类似于PythonRequests的Go语言HTTP请求库
2019-08-13 22:40:01Requests-Go,一个类似于 Python Requests 的 Go 语言 HTTP 请求库 -
python requests模块下载
2014-01-08 23:43:12requests是python的一个HTTP客户端库,跟urllib,urllib2类似,那为什么要用requests而不用urllib2呢?官方文档中是这样说明的:“ python的标准库urllib2提供了大部分需要的HTTP功能,但是API太逆天了,一个简单的... -
详解Python requests 超时和重试的方法
2020-09-19 20:27:23主要介绍了详解Python requests 超时和重试的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
requests-cache 是为 Python 的 Requests 库提供了持久化缓存支持的 Python 模块-python
2021-06-18 19:45:18requests-cache 是为 Python 的 Requests 库提供了持久化缓存支持的 Python 模块 requests-cache Requests-cache 是一个透明的持久缓存请求(版本 >= 1.1.0)库。 用法示例 只需编写: import requests import ... -
Python requests模块基础使用方法实例及高级应用(自动登陆,抓取网页源码)实例详解
2020-09-17 22:45:24主要介绍了Python requests模块基础使用方法实例及高级应用(自动登陆,抓取网页源码,Cookies)实例详解,需要的朋友可以参考下 -
Python requests
2016-12-19 20:34:56Python requests模块 -
Python requests乱码的五种解决办法
2021-12-25 10:35:05使用requests模块请求网页内容,经常会出现乱码,例如: import requests res = requests.get("https://www.baidu.com/") print(res.text) 乱码的原因是内容编码和解码方式不一致导致的,解决办法有以下几种解决...使用requests模块请求网页内容,经常会出现乱码,例如:
import requests res = requests.get("https://www.baidu.com/") print(res.text)
乱码的原因是内容编码和解码方式不一致导致的,解决办法有以下几种解决办法:第一种:apparent_encoding
import requests res = requests.get("https://www.baidu.com/") res.encoding = res.apparent_encoding print(res.text)
第二种:content utf-8解码
一种临时性的解决办法,不建议用这种方法,相当于写死代码了。
import requests res = requests.get("https://www.baidu.com/") try: txt = res.content.decode('gbk') except UnicodeDecodeError as e: # print(e) txt = res.content.decode('utf-8') print(txt)
第三种:chardet
import requests import chardet res = requests.get("https://www.baidu.com/") encoding = chardet.detect(res.content)['encoding'] print(res.content.decode(encoding))
第四种:cchardet
cchardet需要提前安装一下:
pip install cchardet
。import requests import cchardet res = requests.get("https://www.baidu.com/") encoding = cchardet.detect(res.content)['encoding'] print(res.content.decode(encoding))
第五种:encode + decode
import requests import cchardet res = requests.get("https://www.baidu.com/") res_encoding = res.encoding # 响应的编码方式 con_encoding = cchardet.detect(res.content)['encoding'] # 内容的编码方式 print(res.text.encode(res_encoding).decode(con_encoding)) # 重新编解码text
-
python的requests模块文件.zip
2020-03-22 11:38:14写Pyhton代码的时候,需要用上requests模块,只好自己来先安装一下requests模块,Pyhton安装都是用pip来安装模块的。现在的高版本Pyhton在安装的...2.将requests文件夹贴粘到PYTHON的安装路径下的Lib文件夹下就可以了。 -
Python requests库核心源码解析
2020-08-07 18:20:17Requests is an elegant and simple ...Requests库是出自于大神 Kenneth Reitz 之手,我之前看过他写的《Python编程之美》,这本书可以让我们编写的代码更Pythonic,工程结构更加优美。Requests库的源码地.Requests is an elegant and simple HTTP library for Python, built for human beings.
Python requests是最常用的Python第三方库之一,可用于发送HTTP请求,其采用了直观的API设计风格,使用起来非常简单方便。
Requests库是出自于大神 Kenneth Reitz 之手,我之前看过他写的《Python编程之美》,这本书可以让我们编写的代码更Pythonic,工程结构更加优美。Requests库的源码地址在:Github psf/requests,将其源码下载到本地之后,打开工程我们会发现其工程结构和代码规范都非常的优美,而且代码的核心逻辑也非常简洁,特别适合刚开始尝试阅读源码的同学学习。今天这篇文章就对Python requests库进行一个简单的源码分析。
1. 简单实例
首先,我们还是先用requests库编写一个简单的入门实例,然后再从实例作为入口深入分析其源码。
>>> import requests >>> url = 'https://api.github.com/repos/psf/requests' >>> r = requests.get(url) >>> r.ok True >>> r.json()['description'] 'A simple, yet elegant HTTP library.' >>>
Requests库将常用的HTTP操作在api层进行了封装,我们可以非常方便地发起get/post/put/delete/head等操作,如果我们的应用场景比较复杂,也可以直接使用其内部对象进行定制化开发。
2. 核心流程
下图呈现了我们上面实例中get请求的核心时序流程,这里将一些非关键的步骤给忽略掉了,有兴趣的话可以自己去细读源码。接下来我们逐层解析时序图中涉及到的对象和流程。
首先是api层,requests库的api模块中封装了 get, post, options, head, put, delete等方法,我们可以直接调用这几个方法发起HTTP请求,这些方法中都调用了request()
方法,request方法的代码如下,这里实例化了一个Session对象,然后调用了Session对象的request方法发起请求。def request(method, url, **kwargs): with sessions.Session() as session: return session.request(method=method, url=url, **kwargs)
3. Session
Session对象可用于保存请求的状态,比如证书、cookies、proxy等信息,可实现在多个请求之间保持长连接。如果我们是直接使用的api层的方法发起的请求,那么在请求结束之后,所有的状态都会被清理掉。如果我们需要频繁向服务端发起请求,那么使用Session实现长连接可以大大提升处理性能。
Session类中维护了多个HTTPAdpater对象,分别用于处理不同scheme的请求,代码如下,我们也可以通过
Session.mount()
方法设置我们自定义的HTTPAdapter,比如根据要求重新设置重试次数等等。class Session(SessionRedirectMixin): def __init__(self): ...... self.adapters = OrderedDict() self.mount('https://', HTTPAdapter()) self.mount('http://', HTTPAdapter())
Session类继承自SessionRedirectMixin类,SessionRedirectMixin类中实现了用于进行HTTP重定向的能力,这块就不细看了。
我们来看Session对象的
request()
方法,该方法主要用于发送请求,方法中首先调用了prepare_request()
方法将一些请求数据提前封装到了一个PreparedRequest对象中,然后在后面请求的过程中都是使用的该对象。PreparedRequest对象中将请求的method, url, header, cookie, body等数据进行了预处理。class PreparedRequest(...): ...... def prepare(self, method=None, url=None, headers=None, files=None, data=None, params=None, auth=None, cookies=None, hooks=None, json=None): self.prepare_method(method) self.prepare_url(url, params) self.prepare_headers(headers) self.prepare_cookies(cookies) self.prepare_body(data, files, json) self.prepare_auth(auth, url) self.prepare_hooks(hooks)
回到request方法中,下一步会将该request对象和一些请求配置信息一起通过调用
Session.send()
方法将请求发送出去。send方法的逻辑比较简单,就是先获取对应的HTTPAdapter,然后调用adapter的send方法发起请求,最后收到应答之后再判断是否要进行重定向。方法中包含了很多非关键代码,这里就不贴源码了。4. HTTPAdapter
接下来看HTTPAdapter类,之前讲了Session对象主要是用来保存请求的状态的,其实HTTPAdapter才是实际用于发送请求的组件。
我们看HTTPAdapter类的构建方法可以知道,Adapter中主要维护了三个对象,max_retries用于请求重试,proxy_manager用于维护与proxy的连接,poolmanager属性维护了一个连接池PoolManager对象。我们在创建HTTPAdapter的时候可以指定连接池的大小和请求最大重试次数。
这里之所以使用连接池,是为了对连接到相同服务端的请求的连接进行复用,我们知道在一次请求过程中,TCP连接的建立和断开是非常耗时的,如果能够把建立连接这一步省掉那将会大大提升请求性能。连接池的细节我们在下一小节再详细解析。
def send(self, request, ...): conn = self.get_connection(request.url, proxies) self.cert_verify(conn, request.url, verify, cert) resp = conn.urlopen(...) return self.build_response(request, resp)
接下来我们来看HTTPAdapter类的send方法,该方法的代码比较长,清除掉其他非核心代码,主要包括以下四步,代码如上。
- 首先是调用
get_connection()
方法从proxy_manager或者poolmanager中获取到连接,这里代码中用的虽然是connection变量名,但是实际上这里获取的是一个连接池HTTPConnectionPool对象,具体使用的是哪个连接发送请求其实是在连接池HTTPConnectionPool中去自动选择的。这里如果有使用proxy,那么这里就是获取的连接到proxy的一个连接池。 - 然后下一步就是调用
cert_verify()
方法将TLS证书设置到连接中去,如果使用HTTPS的话。 - 接下来就是调用连接池HTTPConnectionPool的
urlopen()
方法,获取一个连接,发送请求,获取响应,这里获取到的响应还是urllib3库中的原生response对象。 - 最后一步是调用
build_response()
方法将urllib3库中的原生response对象封装为requests库中的Response对象。
5. PoolManager
PoolManager对象是urllib3库中的成员,requests库直接在HTTPAdapater类中封装了urllib3库的组件实现了连接池。我们这里对PoolManager对象进行一个简单的解析。
PoolManager中维护了若干个连接池HTTPConnectionPool或者HTTPSConnectionPool,每个连接池又维护了若干条Connection,这里默认的大小是10个连接池,每个连接池10条连接,但是我们可以在创建PoolManager的时候自行指定。
PoolManager中针对具有scheme、host、port三个属性相同的请求使用同一个连接池,每个连接池维护了一个连接队列,当获取连接时会优先从队列中获取一条现成的连接,如果没有现成的则新创建一条连接,连接使用完成之后会再次添加回队列中,以便后续可以继续使用。
6. 优秀工程实践
其实requests库除了代码非常优美值得我们学习之外,其使用到的工程实践也是值得我们在自己的项目中学习借鉴的。
Requests项目的主目录下除了requests目录用于放置源码外,还包含了docs目录存放文档的网页源码,一个项目除了源码,清晰准确的文档也是非常重要的。在tests目录下存放的是在编码过程中同步编写的测试用例,另外主目录下还有CI脚本,每次往项目中集成新代码时都会执行CI,自动运行测试用例,保证新合入代码未破坏之前的功能。另外主目录下还有HISTORY文件,用于详细记录每个版本的变更内容,方便版本发布,另外还有项目依赖包文件、README等。
Requests库的代码组织结构也是值得学习的,模块根据功能组织,清晰明确。另外__version__
模块存放了项目的版本相关信息,在__init__
中将api层的接口方法以及一些核心模型直接暴露出去,这样对于使用者使用起来会更加的方便。7. 总结
这篇文章从源码的核心流程以及工程实践对Python requests库进行了基本的解析,如果想进一步学习其中优美的地方可以自己深度阅读源码。我觉得requests库在Python开发者中之所以这么受欢迎,最主要的原因就是其功能简洁并稳定,接口使用非常方便,另外其清晰的文档也起到了很重要的作用。
- 首先是调用
-
python+requests+unittest API接口测试实例(详解)
2020-09-21 07:11:50下面小编就为大家带来一篇python+requests+unittest API接口测试实例(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
Python使用requests提交HTTP表单的方法
2020-12-23 23:09:27Python的requests库, 其口号是HTTP for humans,堪称最好用的HTTP库。 使用requests库,可以使用数行代码实现自动化的http操作。以http post,即浏览器提交一个表格数据到web服务器,为例,来说明requests的使用。 ... -
Python requests 模块
2020-12-12 14:01:19requestsPython 的内置 urllib 模块,可以用于访问资源,但是,用起来比较麻烦。requests 是一个第三方库,在处理 URL 资源上面非常方便,这也是入门爬虫比较推荐的库之一。安装 requests如果安装了 Anaconda 这一步...requests
Python 的内置 urllib 模块,可以用于访问资源,但是,用起来比较麻烦。
requests 是一个第三方库,在处理 URL 资源上面非常方便,这也是入门爬虫比较推荐的库之一。
安装 requests
如果安装了 Anaconda 这一步可以省略,否则,可以使用下面的命令来安装 requests:
$ pip install requests
上手 requests
发送请求
使用 requests,需要先导入 requests 模块:
>>> import requests
使用 get() 获取某个页面。以 requests 官方文档提及的 Github 公共时间线为例:
>>> url = "https://api.github.com/events"
>>> resp = requests.get(url)
在这里,requests 的 get() 方法返回一个 Response 对象,赋值给变量 resp。现在可以通过这个对象获取需要的内容。
响应内容
>>> resp.status_code # 响应码,200 表示正常访问
200
>>> resp.text
'[{"id":"11696703469","type":"CreateEvent","actor":{"id":59443325,"login":"mahmoudjafarinejad",...'
>>> resp.encoding
'utf-8'
status_code 返回的是响应码,200 在这里表示正常访问。resp.text 在这里返回的是响应的内容。在返回的响应内容,requests 会自动推测文本编码,可以使用 encoding 属性来查看具体使用了什么编码,例如文中使用该属性返回 utf-8。
二进制响应内容
返回的 Response 对象,可以使用 content 属性获得字节对象:
>>> resp.content
b'[{"id":"11696703469","type":"CreateEvent","actor":{"id":59443325,"login":"mahmoudjafarinejad",...'
JSON 响应内容
requests 可以处理 JSON 数据。但这中间也有些需要注意的地方,先看代码:
>>> resp.json()
[{'id': '11697045499', 'type': 'IssueCommentEvent', 'actor': {'id': 5268763, 'login': 'zz-jason', ...]
在这里使用 json() 可以获得 JSON 内容。这里需要注意:如果解码失败,该方法会抛出异常。例如,若返回的响应码是 401,尝试访问 resp.json() 时,就会抛出 ValueError: No JSON object could be decoded 异常。
还有一个需要注意的地方,并不是说成功调用 resp.json() 就表示响应成功。有些服务器在失败的响应中包含一个 JSON 对象。这个时候调用 resp.json() 返回的将是这个包含错误细节的 JSON 对象。所以要检测是否响应成功还需要配合使用 resp.status_code。
传递 URL 参数
当访问网页的时候,我们可能会遇到带参数的 URL,当使用 requests 的时候,我们可以传入 dict 作为参数传入(这里以 http://httpbin.org 为例):
>>> resp = requests.get('http://httpbin.org/get', params={'key1': 'value1', 'key2': 'value2'})
>>> resp.url
'http://httpbin.org/get?key1=value1&key2=value2'
在上面的例子当中,传入 key1=value1 和 key2=value2 到指定的 URL 中。使用 resp.url 可以看到 URL 已被正确编码。
传递 dict 作为参数的时候,dict 中值为 None 的键都不会被添加到 URL 的查询字符串中。
定义请求头
有时候直接使用 get() 方法访问网站时,返回的响应码并不是 200。这是因为有些网站有反爬机制,这个时候可以定义请求头,模拟浏览器正常访问网站,这里我们以豆瓣为例,在没有定义请求头的情况下尝试使用 get() 方法:
>>> url ="https://www.douban.com/"
>>> resp = requests.get(url)
>>> resp.status_code
418
可以看到这里返回的响应码是 418。现在定义请求头,再次访问:
>>> headers = {'User-Agent': 'Mozilla/5.0'}
>>> resp = requests.get(url, headers=headers)
>>> resp.status_code
200
这个时候,返回的响应码为 200,表示访问成功。那么这个时候就可以利用返回的 Response 对象获取需要的内容。
这里提醒下: 就上面以豆瓣为例,不要频繁发起请求,若是频繁请求,有可能会被认为是恶意攻击,而且这样也会对服务器造成负担。
POST 请求
当需要发送一些编码为表单形式的数据。这个时候,可以使用 post() 方法,并传递一个字典给 data 参数。requests 在发出请求的时候会将传入的数据字典编码为表单形式:
>>> data = {'key1': 'value1', 'key2': 'value2'}
>>> resp = requests.post('http://httpbin.org/post', data=data)
>>> print(resp.text)
{
...
"form": {
"key1": "value1",
"key2": "value2"
},
...
}
timeout 参数
可以告诉 requests 在经过 timeout 参数所给定的时间停止响应。(timeout 参数以秒为单位)
>>> resp = requests.get(url, timeout=2)
这里表示在 2 秒后超时。
以上关于 requests 简单上手的内容,更多详细的内容可以访问下面的链接进行详细参阅:
参考资料
来源
"Requests: HTTP for Humans™".requests.readthedocs.io.Retrieved 5 March 2020.
廖雪峰.“Python 教程”.liaoxuefeng.com.[2020-03-05].
欢迎关注微信公众号《书所集录》
-
Python_Requests使用.pdf
2019-12-27 10:45:17Python_Requests使用, Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests它会比url lib更加方便,urlLib库可以处理客户端的请求和服务器端的请求,还可以解析URL地址 ... -
Python Requests实现天气预报
2022-03-28 19:28:18Python、Requests、Lxml、XPath、Pyttsx3 -
Python requests 中文乱码问题解决方案
2022-03-22 14:34:39方案一:requests请求成功时,设置它的编码 注:前提是知道它的编码,一般通过鼠标右键网页就可以查看网页原代码 方案二:利用apparent_encoding 注:apparent_encoding本质上是requests本身对网页源码的猜测... -
python使用requests.session模拟登录
2020-09-18 20:54:25最近开发一套接口,写个Python脚本,使用requests.session模拟一下登录.本文通过实例代码给大家介绍python使用requests.session模拟登录,感兴趣的朋友跟随小编一起看看吧