前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python为什么要使用异步来进行爬取?

Python为什么要使用异步来进行爬取?

作者头像
@莜莜
修改2021-04-12 15:41:59
3610
修改2021-04-12 15:41:59
举报
文章被收录于专栏:爬小虫爬小虫

有些时候,我们使用爬虫下载图片,视频什么的,而下载这些文件都是一个耗时的操作。如果采用之前那种同步的方式下载。那效率肯会特别慢。这时候我们就可以考虑使用多线程的方式来下载这类文件。

多线程是为了同步完成多项任务,通过提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。 最简单的比喻多线程就像火车的每一节车厢,而进程则是火车。车厢离开火车是无法跑动的,同理火车也可以有多节车厢。多线程的出现就是为了提高效率。同时它的出现也带来了一些问题。

通常需要用爬虫的场景都需要并发或并行,也就离不开进程、线程或协程,我们接下来通过爬取1000条文章来看看异步爬虫与同步爬虫的差距。

异步爬虫代码:

代码语言:javascript
复制

import asyncio
import json
import aiohttp

from typing import List, Optional
from datetime import datetime

class Spider:
    def __init__(self, urls: List[str], headers: Optional[dict] = None, cookie: Optional[str] = None):
        self.urls = urls
        self.headers = headers
        self.cookies = None if cookie else {'cookie': cookie}

        self.loop = asyncio.get_event_loop()

        self.result = list()

    def excute(self):
        self.loop.run_until_complete(self.spiders())
        self.loop.close()

        with open('main.json', 'w') as f:
            json.dump(self.result, f)

    async def spiders(self):
        semaphore = asyncio.Semaphore(250)
        spider = [self.run(url, semaphore) for url in self.urls]
        await asyncio.wait(spider)

    async def run(self, url, semaphore):
        async with semaphore:
            async with aiohttp.ClientSession(loop=self.loop, headers=self.headers, cookies=self.cookies) as session:
                async with session.get(url) as response:
                    text = await response.text()
                    self.result.append(json.loads(text))

if __name__ == "__main__":
    urls = []
    for i in range(1, 1001):
        urls.append(f'http://httpbin.org/anything?page={i}')
    s = Spider(urls)
    start = datetime.now()
    s.excute()
    end = datetime.now()

    print("多线程")
    print((end - start).total_seconds(), 

同步爬虫代码:

代码语言:javascript
复制

import json
import requests

from datetime import datetime

if __name__ == "__main__":
    start = datetime.now()
    result = []
    for i in range(1, 1001):
        url = f'http://httpbin.org/anything?page={i}'
        result.append(requests.get(url).json())

    with open('test.json', 'w') as f:
        json.dump(result, f)

    end = datetime.now()
    print("同步")
    print((end - start).total_seconds(), "秒")

从结果来看,在爬取1000条链接的场景中,异步爬虫效率是同步爬虫的30多倍

代码语言:javascript
复制

# # 异步
# 26.43秒
# # 同步
# 621.35秒

资源消耗相对较小,效率提升却如此巨大,所以在以后的爬虫中,还是推荐大家使用多线程,多进程之类的用来提高工作效率。

以上就是今天给大家分享的内容,源代码获取请回复“多线程对比”。有兴趣的朋友,可以尝试一下多线程和多进程的效率对比,看看多进程和多线程的区别。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档