Python中有许多HTTP客户端。使用最广泛且最容易的是requests。

持续连接

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789

持续连接是自HTTP 1.1以来的标准,尽管许多应用程序并未使用它们。以简单模式使用请求时(例如使用get函数),连接会在返回时关闭,Session对象允许重用已经打开的连接。

import requests
session = requests.Session()
session.get("https://china-testing.github.io/")
# Connection is re-used
session.get("https://china-testing.github.io/")

每个连接都存储在连接池中(默认为10)

import requests
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(
pool_connections=100,
pool_maxsize=100)
session.mount('http://', adapter)
response = session.get("http://example.org")

重用TCP连接有许多性能优势:

  • 降低CPU和内存使用率(同时打开的连接较少)。

  • 减少了后续请求中的延迟(无TCP握手)。

  • 可以引发异常而不会关闭TCP连接。

HTTP协议还提供了流水线,流水线化允许在同一连接上发送多个请求,而无需等待答复(批处理)。不幸的是,请求库不支持此功能。但是,流水线请求可能不如并行发送它们那么快。实际上,HTTP 1.1协议强制以与发送请求相同的顺序发送答复-先进先出。

并行

requests的主要缺点是同步的。调用requests.get("http://example.org")会阻塞程序,直到HTTP服务器完全答复为止。可以通过使用并发线程提供的线程池来缓解此问题。它允许以非常快速的方式并行化HTTP请求。

from concurrent import futures
import requests
with futures.ThreadPoolExecutor(max_workers=4) as executor:
futures = [
executor.submit(
lambda: requests.get("http://example.org"))
for _ in range(8) ]
results = [
f.result().status_code
for f in futures]
print("Results: %s" % results)

也可以借助requests-futures的库:

来自requests_futures导入会话

from requests_futures import sessions

session = sessions.FuturesSession()

futures = [
session.get("http://example.org")
for _ in range(8)
]

results = [
f.result().status_code
for f in futures
]

print("Results: %s" % results)

在请求中使用期货

默认情况下,创建具有两个线程的工作程序,但是程序可以通过将max_workers参数甚至是自己的执行程序传递给FuturSession对象来轻松自定义此值,例如:FuturesSession(executor=ThreadPoolExecutor(max_workers=10))。

异步

如前所述,请求是完全同步的。这会在等待服务器回复时阻止应用程序,从而降低程序速度。在线程中发出HTTP请求是一种解决方案,但是线程确实有其自身的开销,这暗示着并行性,这并不是每个人总是很高兴在程序中看到的东西。

从版本3.5开始,Python使用异步将异步作为其核心。aiohttp库提供了一个基于asyncio之上的异步HTTP客户端。该库允许按顺序发送请求,但无需等待答复回来再发送新请求。与HTTP流水形成对比,aiohttp通过多个连接并行发送请求,避免了前面解释的排序问题。


import aiohttp
import asyncio
async def get(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return response
loop = asyncio.get_event_loop()
coroutines = [get("https://china-testing.github.io/") for _ in range(8)]
results = loop.run_until_complete(asyncio.gather(*coroutines))
print("Results: %s" % results)

所有这些解决方案都提供了不同的方法来提高HTTP客户端的速度。

性能

下面的代码向HTTPbin.org发送请求。本示例实现了上面列出的所有技术并对它们进行计时。


import contextlib
import time
import aiohttp
import asyncio
import requests
from requests_futures import sessions
URL = "http://httpbin.org/delay/1"
TRIES = 10
@contextlib.contextmanager
def report_time(test):
t0 = time.time()
yield
print("Time needed for `%s' called: %.2fs"
% (test, time.time() - t0))
with report_time("serialized"):
for i in range(TRIES):
requests.get(URL)
session = requests.Session()
with report_time("Session"):
for i in range(TRIES):
session.get(URL)
session = sessions.FuturesSession(max_workers=2)
with report_time("FuturesSession w/ 2 workers"):
futures = [session.get(URL)
for i in range(TRIES)]
for f in futures:
f.result()
session = sessions.FuturesSession(max_workers=TRIES)
with report_time("FuturesSession w/ max workers"):
futures = [session.get(URL)
for i in range(TRIES)]
for f in futures:
f.result()
async def get(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
await response.read()
loop = asyncio.get_event_loop()
with report_time("aiohttp"):
loop.run_until_complete(
asyncio.gather(*[get(URL)
for i in range(TRIES)]))

运行此程序将给出以下输出:

Time needed for `serialized' called: 12.12s
Time needed for `Session' called: 11.22s
Time needed for `FuturesSession w/ 2 workers' called: 5.65s
Time needed for `FuturesSession w/ max workers' called: 1.25s
Time needed for `aiohttp' called: 1.19s

Streaming

另一个有效的速度优化是流式传输请求。发出请求时,默认情况下会立即下载响应的正文。请求库提供的流参数或aiohttp的content属性都提供了一种在执行请求后不立即将全部内容加载到内存中的方法。

import requests

# Use `with` to make sure the response stream is closed and the connection can
# be returned back to the pool.
with requests.get('http://example.org', stream=True) as r:
print(list(r.iter_content()))

用aiohttp流

import aiohttp
import asyncio
async def get(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.content.read()
loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(get("https://china-testing.github.io/"))]
loop.run_until_complete(asyncio.wait(tasks))
print("Results: %s" % [task.result() for task in tasks])

为了避免无用地分配可能的数百兆内存,不加载全部内容非常重要。如果您的程序不需要整体访问整个内容,而是可以处理块,那么最好使用这些方法。例如,如果您要保存内容并将其写入文件,则仅读取一个块并同时写入它将比读取整个HTTP正文(分配大量的内存)具有更高的内存效率。然后将其写入磁盘。

我希望这可以使您更轻松地编写适当的HTTP客户端和请求。如果您知道任何其他有用的技术或方法,请随时在下面的评论部分写下来!

Python高性能HTTP客户端库requests的使用的更多相关文章

  1. 【Python】 http客户端库requests & urllib2 以及ip地址处理IPy

    requests requests是个HTTPClient库,相比于urllib,urllib2等模块比更加简洁易用 ■ get请求 作为示例,讲一下关于requests如何发起并处理一个get请求 ...

  2. 【网络爬虫入门02】HTTP客户端库Requests的基本原理与基础应用

    [网络爬虫入门02]HTTP客户端库Requests的基本原理与基础应用 广东职业技术学院  欧浩源 1.引言 实现网络爬虫的第一步就是要建立网络连接并向服务器或网页等网络资源发起请求.urllib是 ...

  3. 原!!win7-64 安装python的 redis客户端库

    安装python的redis客户端库 本人系统已装python2.7 利用cmd命令行: 1.cmd-->python -->>>进入python命令下 >>> ...

  4. 【Python爬虫】爬虫利器 requests 库小结

    requests库 Requests 是一个 Python 的 HTTP 客户端库. 支持许多 HTTP 特性,可以非常方便地进行网页请求.网页分析和处理网页资源,拥有许多强大的功能. 本文主要介绍 ...

  5. python第三方库requests详解

    Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTT ...

  6. python WEB接口自动化测试之requests库详解

    由于web接口自动化测试需要用到python的第三方库--requests库,运用requests库可以模拟发送http请求,再结合unittest测试框架,就能完成web接口自动化测试. 所以笔者今 ...

  7. (转)Python爬虫利器一之Requests库的用法

    官方文档 以下内容大多来自于官方文档,本文进行了一些修改和总结.要了解更多可以参考 官方文档 安装 利用 pip 安装 $ pip install requests 或者利用 easy_install ...

  8. python第三方库requests简单介绍

    一.发送请求与传递参数 简单demo: import requests r = requests.get(url='http://www.itwhy.org') # 最基本的GET请求 print(r ...

  9. Python爬虫利器一之Requests库的用法

    前言 之前我们用了 urllib 库,这个作为入门的工具还是不错的,对了解一些爬虫的基本理念,掌握爬虫爬取的流程有所帮助.入门之后,我们就需要学习一些更加高级的内容和工具来方便我们的爬取.那么这一节来 ...

随机推荐

  1. 阿里云OSS 服务端签名后直传之分片上传(结合element-ui的upload组件)

    分片上传(结合element-ui的upload组件实现自定义上传) async uploadFree(content){ let data = await this.getOssToken(); / ...

  2. python面试题:redis数据库

    来源链接: https://www.cnblogs.com/jasontec/p/9699242.html https://www.cnblogs.com/Java3y/p/10266306.html ...

  3. java 数据结构(一):java常用类 一 String类

    java.lang.String类的使用1.概述String:字符串,使用一对""引起来表示.1.String声明为final的,不可被继承2.String实现了Serializa ...

  4. 数据可视化之powerBI基础(七)一文带你熟悉PowerBI建模视图中的功能

    https://zhuanlan.zhihu.com/p/67316729 PowerBI 3月的更新,正式发布了建模视图,而之前只是预览功能.新的建模视图到底有什么用,下面带你认识一下它的主要功能. ...

  5. Ethical Hacking - GAINING ACCESS(10)

    CLIENT SIDE ATTACKS Use if server-side attacks fail. If IP is probably useless. Require user interac ...

  6. P1469 找筷子

    摘要:有n根(n为奇数)长短不一的筷子,里面可以凑成(n-1)/2双筷子,只剩下一根不能凑对,问那根不能凑对的筷子有多长. 乍听起来好像不难,桶是一个好东西,可是一看数据:对于100%的数据,N< ...

  7. 第一讲 Windows10系统下IDE-CLion的安装与配置

    01 为什么使用CLion?02 CLion安装方法03 CLion的基本使用04 课程形式及答疑说明 toc 参考链接: Window10上CLion极简配置教程 学生免费注册Pycharm专业版 ...

  8. javascript兼容性:展开运算符 ... 的降级

    展开运算符 ... 是一个很好用的ES6新特性,用的好的话,可以节约很多代码. 但是作为ES6特性,它有兼容性问题,而且Babal(在线转码网页)并不会转换展开运算符. 展开运算符大体分为两种用法:展 ...

  9. 新款iPad Pro4的电池续航和充电速度对比

    3月18日晚苹果官网上架了两款新iPad Pro,两款iPad Pro 2020外观大小分别为11英寸和12.9英寸,搭载苹果A12Z仿生芯片,起售价分别为6288元和7899元.那么两款iPad P ...

  10. APP自动化 -- swipe(滑动屏幕)