首页 后端开发 Python教程 在Python3中使用asyncio库进行快速数据抓取的教程

在Python3中使用asyncio库进行快速数据抓取的教程

Jun 10, 2016 pm 03:16 PM
asyncio python 爬虫

web数据抓取是一个经常在python的讨论中出现的主题。有很多方法可以用来进行web数据抓取,然而其中好像并没有一个最好的办法。有一些如scrapy这样十分成熟的框架,更多的则是像mechanize这样的轻量级库。DIY自己的解决方案同样十分流行:你可以使用requests、beautifulsoup或者pyquery来实现。

方法如此多样的原因在于,数据“抓取”实际上包括很多问题:你不需要使用相同的工具从成千上万的页面中抓取数据,同时使一些Web工作流自动化(例如填一些表单然后取回数据)。我喜欢DIY的原因在于其灵活性,但是却不适合用来做大量数据的抓取,因为需要请求同步,所以大量的请求意味着你不得不等待很长时间。

在本文中,我将会为你展示一个基于新的异步库(aiohttp)的请求的代替品。我使用它写了一些速度的确很快的小数据抓取器,下面我将会为你演示是如何做到的。

asyncio的基本概念
asyncio是在python3.4中被引进的异步IO库。你也可以通过python3.3的pypi来安装它。它相当的复杂,而且我不会介绍太多的细节。相反,我将会解释你需要知道些什么,以利用它来写异步的代码。

简而言之,有两件事情你需要知道:协同程序和事件循环。协同程序像是方法,但是它们可以在代码中的特定点暂停和继续。当在等待一个IO(比如一个HTTP请求),同时执行另一个请求的时候,可以用来暂停一个协同程序。我们使用关键字yield from来设定一个状态,表明我们需要一个协同程序的返回值。而事件循环则被用来安排协同程序的执行。

关于asyncio还有很多很多,但是以上是我们到目前为止需要知道的。可能你还有些不清楚,那么让我们来看一些代码吧。

aiohttp
aiohttp是一个利用asyncio的库,它的API看起来很像请求的API。到目前为止,相关文档还不健全。但是这里有一些非常有用的例子。我们将会演示它的基本用法。

首先,我们会定义一个协同程序用来获取页面,并打印出来。我们使用 asyncio.coroutine将一个方法装饰成一个协同程序。aiohttp.request是一个协同程序,所以它是一个可读方法,我们需要使用yield from来调用它们。除了这些,下面的代码看起来相当直观:
 

@asyncio.coroutine
def print_page(url):
  response = yield from aiohttp.request('GET', url)
  body = yield from response.read_and_close(decode=True)
  print(body)
登录后复制

如你所见,我们可以使用yield from从另一个协同程序中调用一个协同程序。为了从同步代码中调用一个协同程序,我们需要一个事件循环。我们可以通过asyncio.get_event_loop()得到一个标准的事件循环,之后使用它的run_until_complete()方法来运行协同程序。所以,为了使之前的协同程序运行,我们只需要做下面的步骤:

loop = asyncio.get_event_loop()
loop.run_until_complete(print_page('http://example.com'))
登录后复制

一个有用的方法是asyncio.wait,通过它可以获取一个协同程序的列表,同时返回一个将它们全包括在内的单独的协同程序,所以我们可以这样写:

loop.run_until_complete(asyncio.wait([print_page('http://example.com/foo'),
                   print_page('http://example.com/bar')]))
登录后复制

另一个是asyncio.as_completed,通过它可以获取一个协同程序的列表,同时返回一个按完成顺序生成协同程序的迭代器,因此当你用它迭代时,会尽快得到每个可用的结果。

数据抓取
现在我们知道了如何做异步HTTP请求,因此我们可以来写一个数据抓取器了。我们仅仅还需要一些工具来读取html页面,我使用了beautifulsoup来做这个事情,其余的像 pyquery或lxml也可以实现。

在这个例子中,我们会写一个小数据抓取器来从海盗湾抓取一些linux distributions的torrent 链路(海盗湾(英语:The Pirate Bay,缩写:TPB)是一个专门存储、分类及搜索Bittorrent种子文件的网站,并自称“世界最大的BitTorrent tracker(BT种子服务器)”,提供的BT种子除了有自由版权的收集外,也有不少被著作人声称拥有版权的音频、视频、应用软件与电子游戏等,为网络分享与下载的重要网站之一–译者注来自维基百科)

首先,需要一个辅助协同程序来获取请求:

@asyncio.coroutine
def get(*args, **kwargs):
  response = yield from aiohttp.request('GET', *args, **kwargs)
  return (yield from response.read_and_close(decode=True))
登录后复制

解析部分。本文并非介绍beautifulsoup的,所以这部分我会简写:我们获取了这个页面的第一个磁链。

def first_magnet(page):
  soup = bs4.BeautifulSoup(page)
  a = soup.find('a', title='Download this torrent using magnet')
  return a['href']
登录后复制

在这个协同程序中,url的结果通过种子的数量进行排序,所以排名第一的结果实际上是种子最多的:

@asyncio.coroutine
def print_magnet(query):
  url = 'http://thepiratebay.se/search/{}/0/7/0'.format(query)
  page = yield from get(url, compress=True)
  magnet = first_magnet(page)
  print('{}: {}'.format(query, magnet))
登录后复制

最后,用下面的代码来调用以上所有的方法。

distros = ['archlinux', 'ubuntu', 'debian']
loop = asyncio.get_event_loop()
f = asyncio.wait([print_magnet(d) for d in distros])
loop.run_until_complete(f)
登录后复制

结论
好了,现在我们来到了这个部分。你有了一个异步工作的小抓取器。这意味着多个页面可以同时被下载,所以这个例子要比使用请求的相同代码快3倍。现在你应该可以用相同的方法写出你自己的抓取器了。

你可以在这里找到生成的代码,也包括一些额外的建议。

你一旦熟悉了这一切,我建议你看一看asyncio的文档和aiohttp的范例,这些都能告诉你 asyncio拥有怎样的潜力。

这种方法(事实上是所有手动的方法)的一个局限在于,没有一个独立的库可以用来处理表单。机械化的方法拥有很多辅助工具,这使得提交表单变得十分简单,但是如果你不使用它们,你将不得不自己去处理这些事情。这可能会导致一些bug的出现,所以同时我可能会写一个这样的库(不过目前为止无需为此担心)。

额外的建议:不要敲打服务器
同时做3个请求很酷,但是同时做5000个就不那么好玩了。如果你打算同时做太多的请求,链接有可能会断掉。你甚至有可能会被禁止链接网络。

为了避免这些,你可以使用semaphore。这是一个可以被用来限制同时工作的协同程序数量的同步工具。我们只需要在建立循环之前创建一个semaphore ,同时把我们希望允许的同时请求的数量作为参数传给它既可:

sem = asyncio.Semaphore(5)
登录后复制

然后,我们只需要将下面

page = yield from get(url, compress=True)
登录后复制

替换成被semaphore 保护的同样的东西。

with (yield from sem):
  page = yield from get(url, compress=True)
登录后复制

这就可以保证同时最多有5个请求会被处理。

额外建议:进度条
这个东东是免费的哦:tqdm是一个用来生成进度条的优秀的库。这个协同程序就像asyncio.wait一样工作,不过会显示一个代表完成度的进度条。

@asyncio.coroutine
def wait_with_progress(coros):
  for f in tqdm.tqdm(asyncio.as_completed(coros), total=len(coros)):
    yield from f
登录后复制

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

有什么手机APP可以将XML转换成PDF? 有什么手机APP可以将XML转换成PDF? Apr 02, 2025 pm 08:54 PM

无法找到一款将 XML 直接转换为 PDF 的应用程序,因为它们是两种根本不同的格式。XML 用于存储数据,而 PDF 用于显示文档。要完成转换,可以使用编程语言和库,例如 Python 和 ReportLab,来解析 XML 数据并生成 PDF 文档。

xml格式怎么打开 xml格式怎么打开 Apr 02, 2025 pm 09:00 PM

用大多数文本编辑器即可打开XML文件;若需更直观的树状展示,可使用 XML 编辑器,如 Oxygen XML Editor 或 XMLSpy;在程序中处理 XML 数据则需使用编程语言(如 Python)与 XML 库(如 xml.etree.ElementTree)来解析。

xml格式化工具推荐 xml格式化工具推荐 Apr 02, 2025 pm 09:03 PM

XML格式化工具可以将代码按照规则排版,提高可读性和理解性。选择工具时,要注意自定义能力、对特殊情况的处理、性能和易用性。常用的工具类型包括在线工具、IDE插件和命令行工具。

有没有免费的手机XML转PDF工具? 有没有免费的手机XML转PDF工具? Apr 02, 2025 pm 09:12 PM

没有简单、直接的免费手机端XML转PDF工具。需要的数据可视化过程涉及复杂的数据理解和渲染,市面上所谓的“免费”工具大多体验较差。推荐使用电脑端的工具或借助云服务,或自行开发App以获得更靠谱的转换效果。

如何在手机上高质量地将XML转换成PDF? 如何在手机上高质量地将XML转换成PDF? Apr 02, 2025 pm 09:48 PM

在手机上高质量地将XML转换成PDF需要:使用无服务器计算平台在云端解析XML并生成PDF。选择高效的XML解析器和PDF生成库。正确处理错误。充分利用云端计算能力,避免在手机上进行繁重任务。根据需求调整复杂度,包括处理复杂的XML结构、生成多页PDF和添加图片。打印日志信息以帮助调试。优化性能,选择高效的解析器和PDF库,并可能使用异步编程或预处理XML数据。确保良好的代码质量和可维护性。

手机XML转PDF,转换速度快吗? 手机XML转PDF,转换速度快吗? Apr 02, 2025 pm 10:09 PM

手机XML转PDF的速度取决于以下因素:XML结构的复杂性手机硬件配置转换方法(库、算法)代码质量优化手段(选择高效库、优化算法、缓存数据、利用多线程)总体而言,没有绝对的答案,需要根据具体情况进行优化。

XML如何修改注释内容 XML如何修改注释内容 Apr 02, 2025 pm 06:15 PM

对于小型XML文件,可直接用文本编辑器替换注释内容;对于大型文件,建议借助XML解析器进行修改,确保效率和准确性。删除XML注释时需谨慎,保留注释通常有助于代码理解和维护。进阶技巧中提供了使用XML解析器修改注释的Python示例代码,但具体实现需根据使用的XML库进行调整。修改XML文件时注意编码问题,建议使用UTF-8编码并指定编码格式。

XML修改内容需要编程吗 XML修改内容需要编程吗 Apr 02, 2025 pm 06:51 PM

修改XML内容需要编程,因为它需要精准找到目标节点才能增删改查。编程语言有相应库来处理XML,提供API像操作数据库一样进行安全、高效、可控的操作。

See all articles