带有 difflib 的 Python Asyncio 缓慢爬行

Posted

技术标签:

【中文标题】带有 difflib 的 Python Asyncio 缓慢爬行【英文标题】:Python Asyncio with difflib slows to a crawl 【发布时间】:2017-03-25 10:34:54 【问题描述】:

我有一个脚本可以异步下载几个 url,然后通过 difflib 持续监控它们的变化

import asyncio
import difflib
import aiohttp

urls = ['http://www.nytimes.com/',
        'http://www.time.com/',
        'http://www.economist.com/']

async def get_url(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            old = await resp.text()
            print('Initial -',url)
        while True:
            async with session.get(url) as resp1:
                new = await resp.text()
            print('Got -',url)
            diff = difflib.unified_diff(old, new)

            for line in diff:
                print(line)
            old = new

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    ops = []
    for url in urls:
        ops.append(get_url(url))
    loop.run_until_complete(asyncio.wait(ops))

当我运行它并注释以下行时

        for line in diff:
            print(line)

脚本按预期运行,每秒检索每个 url 大约 3 次。

当取消注释行时,脚本会变慢,比连续运行检索要慢得多。

我不知道为什么会这样,这与 difflib 返回生成器有关吗?

【问题讨论】:

【参考方案1】:

首先,您的代码中有错误,而不是new = await resp.text(),它应该是new = await resp1.text()

unified_diff 使用字符串列表而不是直接使用字符串。您可以使用splitlines() 快速将字符串拆分为行:

diff = difflib.unified_diff(old.splitlines(), new.splitlines())

(目前长字符串中的每个字符都被视为一行!)

【讨论】:

以上是关于带有 difflib 的 Python Asyncio 缓慢爬行的主要内容,如果未能解决你的问题,请参考以下文章

python difflib.md

python中的difflib

python中的difflib

Python 之 Difflib

Python一起来找茬—difflib模块

python运维开发常用模块文件对比模块difflib