吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2693|回复: 10
收起左侧

[Python 转载] 异步爬虫和同步单线程爬虫对比

  [复制链接]
thepoy 发表于 2020-12-7 21:00
本帖最后由 thepoy 于 2020-12-7 21:04 编辑

通常需要用爬虫的场景都需要并发或并行,也就离不开进程、线程或协程,而本示例就是一个简单的异步爬虫与同步爬虫的对比。

代码

异步爬虫代码:

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((end - start).total_seconds(), "秒")

同步爬虫代码:

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((end - start).total_seconds(), "秒")

结果

# 异步
20.837937 秒
# 同步(我实在没想到会耗时这么久...)
650.712683 秒

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

资源消耗相对较小,效率提升却如此巨大,所以在以后的爬虫中,我就优先考虑异步了。

有兴趣的朋友,可以尝试一下与多线程和多进程的效率对比,请在本贴贴出对比结果。

免费评分

参与人数 4吾爱币 +8 热心值 +4 收起 理由
zhu1979 + 1 + 1 谢谢@Thanks!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
banhave + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Zeaf + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

网络鱼 发表于 2020-12-7 21:27
前提是网站没有反爬机制以及服务器性能够好,不然的话高并发运行两秒就挂掉了
szwangbin001 发表于 2020-12-7 21:57
fanvalen 发表于 2020-12-7 23:52
快是快就是要考虑结果储存同一文件并且顺序排列,当然不考虑这些无所谓。
oktongguo 发表于 2020-12-8 00:24
Java写了个爬小说的,还没学多线程,那速度,两小时爬不完一个小说
 楼主| thepoy 发表于 2020-12-8 09:44
网络鱼 发表于 2020-12-7 21:27
前提是网站没有反爬机制以及服务器性能够好,不然的话高并发运行两秒就挂掉了

难道你还想一个爬虫爬全网不成?当然得根据实际情况写代码,反爬手段很多,能反爬就一样能异步高并发,服务器性能差,可以适当降低semaphore
 楼主| thepoy 发表于 2020-12-8 09:46
fanvalen 发表于 2020-12-7 23:52
快是快就是要考虑结果储存同一文件并且顺序排列,当然不考虑这些无所谓。

爬虫结果一般都保存在数据库里吧,如果在数据库里还需要考虑排序吗?order by不就好了?如果是保存到一个文件里,才可能需要考虑到排序问题。
ycz0030 发表于 2020-12-8 10:08
不错,学习了
凹凸曼大人 发表于 2020-12-8 16:36
异步的化,直接scrapy框架,简单好用,python的化,我直接多线程。 这样代码简洁,好写。
qqLinux 发表于 2020-12-17 23:05
python 爬虫还是用多进程好,效率是多线程的2倍,虽然还是被一定限制
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 07:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表