我有一个使用 requests 和 lxml 在 Python 3 中构建的非常基本的站点地图抓取器。目的是建立某个网站的 URL 数据库。目前它的工作方式如下:对于每个要抓取的顶级站点地图,我触发一个 celery 任务。在此任务中,将解析站点地图以检查它是 sitemapindex
还是 urlset
。站点地图索引按层次结构指向其他站点地图,而网址集则指向结束网址 - 它们就像树中的叶子。
如果站点地图被标识为 sitemapindex
,则它包含的每个指向子站点地图的 URL 都会在单独的线程中进行处理,并从头开始重复该过程。
如果站点地图被识别为 urlset
,则其中的 URL 将存储在数据库中,并且此分支完成。
我一直在阅读有关协程、asyncio、gevent、async/await 等的内容,但我不确定我的问题是否适合使用这些技术来开发,或者性能是否会得到改善。
据我所知,协程在处理 IO 操作时很有用,以避免在 IO 操作运行时阻塞执行。但是,我还了解到它们本质上是单线程的,因此我知道当代码开始解析来自 IO 操作的 XML 响应时,没有并行化。
本质上问题是,我如何使用 coroutines/asyncio/insert_similar_technology 来实现这一点?我会从性能方面受益吗?
编辑:顺便说一句,我知道 Twisted 有一个专门的 SitemapSpider,以防万一有人建议使用它。
最佳答案
抱歉,我不确定我是否完全理解您的代码是如何工作的,但这里有一些想法:
您的程序是否下载多个网址?
如果是,asyncio 可用于减少程序等待网络 I/O 的时间。如果没有,asyncio 不会帮助你。
你的程序如何下载网址?
如果是一对一的,那么 asyncio 可以帮助您更快地获取它们。另一方面,如果您已经并行地获取它们(例如,使用不同的线程),您将不会从 asyncio 中获得太多好处。
我建议您阅读我关于 asyncio 的回答 here 。它很短,可以帮助您理解为什么以及何时使用异步代码。
关于python-3.x - 尝试将协程的概念应用到现有代码中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43338713/