0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一文汇总并发http请求最快的几种实现方式用

Linux爱好者 来源:Python七号 作者: somenzz 2021-10-20 14:36 次阅读

假如有一个文件,里面有 10 万个 url,需要对每个 url 发送 http 请求,并打印请求结果的状态码,如何编写代码尽可能快的完成这些任务呢?

Python 并发编程有很多方法,多线程的标准库 threading,concurrency,协程 asyncio,当然还有 grequests 这种异步库,每一个都可以实现上述需求,下面一一用代码实现一下,本文的代码可以直接运行,给你以后的并发编程作为参考:

队列+多线程定义一个大小为 400 的队列,然后开启 200 个线程,每个线程都是不断的从队列中获取 url 并访问。

主线程读取文件中的 url 放入队列中,然后等待队列中所有的元素都被接收和处理完毕。代码如下:

fromthreadingimportThread
importsys
fromqueueimportQueue
importrequests

concurrent=200


defdoWork():
whileTrue:
url=q.get()
status,url=getStatus(url)
doSomethingWithResult(status,url)
q.task_done()


defgetStatus(ourl):
try:
res=requests.get(ourl)
returnres.status_code,ourl
except:
return"error",ourl


defdoSomethingWithResult(status,url):
print(status,url)


q=Queue(concurrent*2)
foriinrange(concurrent):
t=Thread(target=doWork)
t.daemon=True
t.start()

try:
forurlinopen("urllist.txt"):
q.put(url.strip())
q.join()
exceptKeyboardInterrupt:
sys.exit(1)

运行结果如下:

77fe1322-3162-11ec-82a8-dac502259ad0.png

有没有 get 到新技能?

线程池

如果你使用线程池,推荐使用更高级的 concurrent.futures 库:

importconcurrent.futures
importrequests

out=[]
CONNECTIONS=100
TIMEOUT=5

urls=[]
withopen("urllist.txt")asreader:
forurlinreader:
urls.append(url.strip())

defload_url(url,timeout):
ans=requests.get(url,timeout=timeout)
returnans.status_code

withconcurrent.futures.ThreadPoolExecutor(max_workers=CONNECTIONS)asexecutor:
future_to_url=(executor.submit(load_url,url,TIMEOUT)forurlinurls)
forfutureinconcurrent.futures.as_completed(future_to_url):
try:
data=future.result()
exceptExceptionasexc:
data=str(type(exc))
finally:
out.append(data)
print(data)

协程 + aiohttp

协程也是并发非常常用的工具了:

importasyncio
fromaiohttpimportClientSession,ClientConnectorError

asyncdeffetch_html(url:str,session:ClientSession,**kwargs)->tuple:
try:
resp=awaitsession.request(method="GET",url=url,**kwargs)
exceptClientConnectorError:
return(url,404)
return(url,resp.status)

asyncdefmake_requests(urls:set,**kwargs)->None:
asyncwithClientSession()assession:
tasks=[]
forurlinurls:
tasks.append(
fetch_html(url=url,session=session,**kwargs)
)
results=awaitasyncio.gather(*tasks)

forresultinresults:
print(f'{result[1]}-{str(result[0])}')

if__name__=="__main__":
importsys
assertsys.version_info>=(3,7),"ScriptrequiresPython3.7+."
withopen("urllist.txt")asinfile:
urls=set(map(str.strip,infile))
asyncio.run(make_requests(urls=urls))

grequests[1]

这是个第三方库,目前有 3.8K 个星,就是 Requests + Gevent[2],让异步 http 请求变得更加简单。Gevent 的本质还是协程。

使用前:

pipinstallgrequests

使用起来那是相当的简单:

importgrequests

urls=[]
withopen("urllist.txt")asreader:
forurlinreader:
urls.append(url.strip())

rs=(grequests.get(u)foruinurls)

forresultingrequests.map(rs):
print(result.status_code,result.url)

注意 grequests.map(rs) 是并发执行的。运行结果如下:

78759172-3162-11ec-82a8-dac502259ad0.png

也可以加入异常处理:

>>>defexception_handler(request,exception):
...print("Requestfailed")

>>>reqs=[
...grequests.get('http://httpbin.org/delay/1',timeout=0.001),
...grequests.get('http://fakedomain/'),
...grequests.get('http://httpbin.org/status/500')]
>>>grequests.map(reqs,exception_handler=exception_handler)
Requestfailed
Requestfailed
[None,None,500]>]

最后的话

今天分享了并发 http 请求的几种实现方式,有人说异步(协程)性能比多线程好,其实要分场景看的,没有一种方法适用所有的场景,笔者就曾做过一个实验,也是请求 url,当并发数量超过 500 时,协程明显变慢。

编辑:jq
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    88

    文章

    3439

    浏览量

    92328
  • HTTP
    +关注

    关注

    0

    文章

    464

    浏览量

    30296
  • URL
    URL
    +关注

    关注

    0

    文章

    131

    浏览量

    14822
  • python
    +关注

    关注

    51

    文章

    4667

    浏览量

    83443

原文标题:如何用最快的方式发送 10 万个 http 请求?

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    鸿蒙OS开发实战:【网络管理HTTP数据请求

    应用通过HTTP发起一个数据请求,支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。
    的头像 发表于 04-01 16:31 167次阅读
    鸿蒙OS开发实战:【网络管理<b class='flag-5'>HTTP</b>数据<b class='flag-5'>请求</b>】

    鸿蒙原生应用开发-网络管理HTTP数据请求

    、场景介绍 应用通过HTTP发起个数据请求,支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。 二、接口说明
    发表于 03-29 17:51

    arkts http 发起请求失败

    http 发起请求 官网Http
    发表于 03-23 00:33

    HTTP协议的运作方式请求/响应的步骤

    基于HTTP的客户/服务器模式的信息交换过程它分四个过程建立连接、发送请求信息、发送响应信息、关闭连接。
    的头像 发表于 02-01 11:02 727次阅读
    <b class='flag-5'>HTTP</b>协议的运作<b class='flag-5'>方式</b>及<b class='flag-5'>请求</b>/响应的步骤

    HTTP 中GET 和 POST 的区别

    一、概述 HTTP请求报文 GET 方法的特点 POST 方法的特点 GET 和 POST 的区别 二、HTTP请求报文 首先我们要解决的第一个问题是:GET 和 POST 是
    的头像 发表于 11-11 14:40 574次阅读
    <b class='flag-5'>HTTP</b> 中GET 和 POST 的区别

    【EsDA 应用】快速实现串口转HTTP请求

    本文将基于EsDA开发套件快速实现将串口数据转换为HTTP请求的应用开发,实现串口设备与网络服务的互联互通,提供便捷和高效的串口数据转换功能。项目简介
    的头像 发表于 11-09 08:25 475次阅读
    【EsDA 应用】快速<b class='flag-5'>实现</b>串口转<b class='flag-5'>HTTP</b><b class='flag-5'>请求</b>

    上位机和下位机之间什么方式传输速率最快

    上位机(嵌入式带显示体模块)和下位机(单片机执行或者收集信息)之间什么方式传输速率最快,USB,串口选哪个?
    发表于 11-07 08:05

    安信可Ai-WB2模组HTTP 客户端 POST请求方法

    文章目录 一、准备工作 二、连接路由器 三、HTTP客户端POST请求方法(适用于POST少量数据) 四、HTTP 客户端 POST 请求方法(推荐
    的头像 发表于 10-30 17:27 327次阅读
    安信可Ai-WB2模组<b class='flag-5'>HTTP</b> 客户端 POST<b class='flag-5'>请求</b>方法

    并发场景下请求合并

    我们在服务器端把请求合并,只发出一条SQL查询数据库,数据库返回后,服务器端处理返回数据,根据一个唯一请求ID,把数据分组,返回给对应用户。
    的头像 发表于 10-09 16:05 184次阅读
    高<b class='flag-5'>并发</b>场景下<b class='flag-5'>请求</b>合并

    如何测试HTTP请求示例

    电子发烧友网站提供《如何测试HTTP请求示例.zip》资料免费下载
    发表于 07-13 11:35 1次下载
    如何测试<b class='flag-5'>HTTP</b><b class='flag-5'>请求</b>示例

    基于Nginx配置origin限制跨域请求

    按照等保要求,跨域的不安全性,需要修复。 这个需要根据客户端传递的请求头中的Origin值,进行安全的跨站策略配置,目的是对非法的origin直接返回403错误页面。 漏洞复现 复现方式
    的头像 发表于 06-26 10:49 829次阅读
    基于Nginx配置origin限制跨域<b class='flag-5'>请求</b>

    如何使用 ESP-AT实现HTTP请求

    ESP-AT作为乐鑫开发的可直接用于量产的物联网应用固件,可以简单完成网络的连接,以及设备与服务器之间的数据传输。本文将介绍如何使用 ESP-AT实现HTTP请求
    的头像 发表于 05-23 17:12 780次阅读
    如何使用 ESP-AT<b class='flag-5'>实现</b><b class='flag-5'>HTTP</b><b class='flag-5'>请求</b>

    边缘计算相关论文汇总

    刚读研发现找论文真的很累   给大伙做个论文汇总吧  近三年ccf A  B期刊论文(无会议论文) 资源链接: 边缘计算论文汇总CCFAB2018-2020(近二百篇论文)_有关边缘计算的论文
    发表于 05-18 15:45 0次下载
    边缘计算相关论<b class='flag-5'>文汇总</b>

    HTTP的状态消息

     HTTP状态消息是指HTTP服务器在响应客户端请求时返回的状态信息。状态消息由数字状态码和可选的文本描述组成,主要有以下几种类型
    发表于 05-06 16:01 289次阅读

    HTTP协议的运作方式

    客户端发起请求:客户端向服务端发送HTTP请求报文,报文包括请求行、请求头、请求体等内容,其中
    发表于 05-06 15:52 540次阅读
    <b class='flag-5'>HTTP</b>协议的运作<b class='flag-5'>方式</b>