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还有很多很多,但是以上是我们到目前为止需要知道的。可能你还有些不清楚,那么让我们来看一些代码吧。

aiohttpaiohttp是一个利用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

python asyncio教程_在Python3中使用asyncio库进行快速数据抓取的教程相关推荐

  1. Python爬虫4.2 — ajax(动态网页数据抓取)用法教程

    Python爬虫4.2 - ajax[动态网页数据]用法教程 综述 AJAX 介绍 什么是AJAX 实例说明 请求分析 获取方式 实例说明 其他博文链接 综述 本系列文档用于对Python爬虫技术的学 ...

  2. 网站开启https后很慢_网站优化中哪些设置会影响蜘蛛的抓取?对网站SEO产生什么影响...

    网站在优化中,要有一定的收录基础才能有更大的几率提升排名,并获得搜索引擎的喜爱.但在网站优化中难免会有一些细节没注意到而影响蜘蛛的抓取,下面就带大家一起了解一下. 一.登录设置 有些网站会设置注册账号 ...

  3. python爬取app播放的视频,Python爬虫工程师必学——App数据抓取实战视频教程

    爬虫分为几大方向,WEB网页数据抓取.APP数据抓取.软件系统数据抓取.本课程主要为同学讲解如何用python实现App数据抓取,课程从开发环境搭建,App爬虫必备利器详解,项目实战,到最后的多App ...

  4. python教程怎么抓起数据_介绍python 数据抓取三种方法

    三种数据抓取的方法正则表达式(re库) BeautifulSoup(bs4) lxml *利用之前构建的下载网页函数,获取目标网页的html,我们以https://guojiadiqu.bmcx.co ...

  5. c#使用正则表达式获取TR中的多个TD_[Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例...

    首先祝大家中秋节和国庆节快乐,欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都 ...

  6. python爬虫百度百科-python爬虫(一)_爬虫原理和数据抓取

    本篇将开始介绍Python原理,更多内容请参考:Python学习指南 为什么要做爬虫 著名的革命家.思想家.政治家.战略家.社会改革的主要领导人物马云曾经在2015年提到由IT转到DT,何谓DT,DT ...

  7. python实现食品推荐_通过Python语言实现美团美食商家数据抓取

    首先,我们先来打开美团美食商家页面,来分析一下. 如上面所提供的URL即为美团美食商家页面.或者我们通过美团官网打开一个美团美食商家页面,打开步骤如下:1.打开浏览器,输入 即可打开美团北京首页 2. ...

  8. 如何用python抓取文献_浅谈Python爬虫技术的网页数据抓取与分析

    浅谈 Python 爬虫技术的网页数据抓取与分析 吴永聪 [期刊名称] <计算机时代> [年 ( 卷 ), 期] 2019(000)008 [摘要] 近年来 , 随着互联网的发展 , 如何 ...

  9. Python爬虫入门实战之猫眼电影数据抓取(理论篇)

    前言 本文可能篇幅较长,但是绝对干货满满,提供了大量的学习资源和途径.达到让读者独立自主的编写基础网络爬虫的目标,这也是本文的主旨,输出有价值能够真正帮助到读者的知识,即授人以鱼不如授人以渔,让我们直 ...

最新文章

  1. ros 消息队列与缓冲区_Spring Boot消息队列系统:RocketMQ初入门
  2. eclipse解决maven编码UTF-8的不可映射字符
  3. 非自回归也能预训练:基于插入的硬约束生成模型预训练方法
  4. eclipse恢复界面默认设置
  5. Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)
  6. 总结一些写毕业论文背景研究可以参考的资源
  7. Thread.sleep还是TimeUnit.SECONDS.sleep
  8. 264 解码之 yuv
  9. C#LeetCode刷题之#190-颠倒二进制位(Reverse Bits)
  10. Linux系统下的RZSZ(文件传输工具)
  11. 永磁同步电机转子磁链_采用冻结磁导率的瞬态场永磁同步电机交直轴电感计算...
  12. 步步为营 .NET三层架构解析 三、SQLHelper设计
  13. matplotlib柱状图之子柱状图不同颜色—20种颜色列表
  14. HDS F900装机小结
  15. Completed 403 FORBIDDEN 后端解决跨域问题
  16. iPhone13有3D Touch吗 3D Touch有什么用
  17. python爬虫豆瓣top250_Python 爬取豆瓣TOP250实战
  18. html页面导出文件大小,【实战】通过 JS 将 HTML 导出为 PDF 文档
  19. 为了防止女朋友怼我,我就先用python爬了3600个怼人表情包等她来战!
  20. 聚合支付码是什么意思及它产生的背景

热门文章

  1. Win10电脑连接手机热点但无法上网怎么办
  2. 事务管理自定义事务管理器
  3. IOS开发笔记7-函数-C语言笔记
  4. M1芯片的MacBook安装docker
  5. 进程管理之PV操作的个人理解
  6. java获取明天的日期_java怎么获取昨天,今天,明天的日期?java中获取日期的函数
  7. 湖南大学校园网 TheServerIsNotResponding
  8. 最新淘汰服务器cpu,英特尔将推13款服务器CPU 淘汰7种笔记本CPU
  9. 7-9 集合相似度 (25分)
  10. [知识竞赛策划方案]那么如何用PPT制作知识竞赛所需要的题库?