您现在的位置是:群英 > 开发技术 > Python语言
怎么提升python爬虫效率,有什么技巧
Admin发表于 2022-05-06 17:42:46719 次浏览
相信很多人对“怎么提升python爬虫效率,有什么技巧”都不太了解,下面群英小编为你详细解释一下这个问题,希望对你有一定的帮助


文 | 闲欢

来源:Python 技术「ID: pythonall」

今天在浏览知乎时,发现一个有趣的问题:如何优化 Python 爬虫的速度?

他的问题描述是:

目前在写一个 Python 爬虫,单线程 urllib 感觉过于慢了,达不到数据量的要求(十万级页面)。求问有哪些可以提高爬取效率的方法?

这个问题还蛮多人关注的,但是回答的人却不多。

我今天就来尝试着回答一下这个问题。

程序提速这个问题其实解决方案就摆在那里,要么通过并发来提高单位时间内处理的工作量,要么从程序本身去找提效点,比如爬取的数据用gzip传输、提高处理数据的速度等。

我会分别从几种常见的并发方法去做同一件事情,从而比较处理效率。

简单版本爬虫

我们先来一个简单的爬虫,看看单线程处理会花费多少时间?

import time
import requests
from datetime import datetime
def fetch(url):
    r = requests.get(url)
    print(r.text)
start = datetime.now() 
t1 = time.time()
for i in range(100):
    fetch('http://httpbin.org/get') 
print('requests版爬虫耗时:', time.time() - t1)
# requests版爬虫耗时:54.86306357383728

我们用一个爬虫的测试网站,测试爬取100次,用时是54.86秒。

多线程版本爬虫

下面我们将上面的程序改为多线程版本:

import threading
import time
import requests
def fetch():
    r = requests.get('http://httpbin.org/get')
    print(r.text)
t1 = time.time()
t_list = []
for i in range(100):
    t = threading.Thread(target=fetch, args=())
    t_list.append(t)
    t.start() 
for t in t_list:
    t.join() 
print("多线程版爬虫耗时:", time.time() - t1)
# 多线程版爬虫耗时:0.8038511276245117

我们可以看到,用上多线程之后,速度提高了68倍。其实用这种方式的话,由于我们并发操作,所以跑100次跟跑一次的时间基本是一致的。这只是一个简单的例子,实际情况中我们不可能无限制地增加线程数。

多进程版本爬虫

除了多线程之外,我们还可以使用多进程来提高爬虫速度:

import requests
import time
import multiprocessing
from multiprocessing import Pool
MAX_WORKER_NUM = multiprocessing.cpu_count() 
def fetch():
    r = requests.get('http://httpbin.org/get')
    print(r.text) 
if __name__ == '__main__':
    t1 = time.time()
    p = Pool(MAX_WORKER_NUM)
    for i in range(100):
        p.apply_async(fetch, args=())
    p.close()
    p.join()
 
    print('多进程爬虫耗时:', time.time() - t1)
 
多进程爬虫耗时: 7.9846765995025635

我们可以看到多进程处理的时间是多线程的10倍,比单线程版本快7倍。

协程版本爬虫

我们将程序改为使用 aiohttp 来实现,看看效率如何:

import aiohttp
import asyncio
import time 
async def fetch(client):
    async with client.get('http://httpbin.org/get') as resp:
        assert resp.status == 200
        return await resp.text() 
async def main():
    async with aiohttp.ClientSession() as client:
        html = await fetch(client)
        print(html) 
loop = asyncio.get_event_loop() 
tasks = []
for i in range(100):
    task = loop.create_task(main())
    tasks.append(task) 
t1 = time.time() 
loop.run_until_complete(main()) 
print("aiohttp版爬虫耗时:", time.time() - t1) 
aiohttp版爬虫耗时: 0.6133313179016113

我们可以看到使用这种方式实现,比单线程版本快90倍,比多线程还快。

结论

通过上面的程序对比,我们可以看到,对于多任务爬虫来说,多线程、多进程、协程这几种方式处理效率的排序为:aiohttp > 多线程 > 多进程。因此,对于简单的爬虫任务,如果想要提高效率,可以考虑使用协程。但是同时也要注意,这里只是简单的示例,实际运用中,我们一般会用线程池、进程池、协程池去操作。

这就是问题的答案了吗?

对于一个严谨的程序员来说,当然不是,实际上还有一些优化的库,例如grequests,可以从请求上解决并发问题。实际的处理过程中,肯定还有其他的优化点,这里只是从最常见的几种并发方式去比较而已,应付简单爬虫还是可以的,其他的方式欢迎大家在评论区留言探讨。


通过以上内容的阐述,相信大家对“怎么提升python爬虫效率,有什么技巧”已经有了进一步的了解,更多相关的问题,欢迎关注群英网络或到群英官网咨询客服。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: python爬虫效率
相关信息推荐
2022-08-25 17:45:30 
摘要:这篇文章主要介绍了laravel admin实现分类树/模型树,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2021-11-02 17:18:10 
摘要:这篇文章给大家分享的是PHP中array_fill函数的的作用和用法。小编觉得挺实用的,因此分享给大家做个参考,下文将介绍array_fill的说明、语法、参数、返回值和实例这些,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。
2022-08-26 17:49:07 
摘要:jquery php实现实时数据更新的方法:1、创建数据表;2、通过创建服务器文件“demo.php”连接数据库并进行相关操作;3、创建显示数据的“fresh.html”网页即可。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部