这是我最想推荐给程序员们看的基于Python3.4实现的爬虫书


互联网包含了迄今为止最有用的数据集,而且大部分能够免费公开访问。可是,这些数据难以复用。它们被嵌入在网站的结构和样式当中,须要抽取出来才能使用。从网页中抽取数据的过程又称为网络爬虫,随着愈来愈多的信息被发布到网络上,网络爬虫也变得愈来愈有用。
python

今天介绍的这一本书《用Python写网络爬虫(第2版)》是Python网络爬虫畅销图书全新升级版,上一版年度畅销近4万册,而本书针对Python 3.x编写,提供示例完整源码和实例网站搭建源码,确保你能够在本地成功复现爬取网站环境,并保障网站的稳定性与可靠性以及代码运行结果的可再现性。 书中使用的全部代码均已使用Python 3.4+测试经过,而且能够在异步社区下载到。正则表达式


点击封面查看更多详情shell


“网络爬虫什么时候有用”数据库


假设我有一个鞋店,而且想要及时了解竞争对手的价格。我能够天天访问他们的网站,与我店铺中鞋子的价格进行对比。可是,若是我店铺中的鞋类品种繁多,或是但愿可以更加频繁地查看价格变化的话,就须要花费大量的时间,甚至难以实现。再举一个例子,我看中了一双鞋,想等到它促销时再购买。我可能须要天天访问这家鞋店的网站来查看这双鞋是否降价,也许须要等待几个月的时间,我才能如愿盼到这双鞋促销。上述这两个重复性的手工流程,均可以利用本书介绍的网络爬虫技术实现自动化处理。后端

在理想状态下,网络爬虫并非必需品,每一个网站都应该提供API,以结构化的格式共享它们的数据。然而在现实状况中,虽然一些网站已经提供了这种API,可是它们一般会限制能够抓取的数据,以及访问这些数据的频率。另外,网站开发人员可能会变动、移除或限制其后端API。总之,咱们不能仅仅依赖于API去访问咱们所需的在线数据,而是应该学习一些网络爬虫技术的相关知识。api

“本书基于Python 3”浏览器

在本书中,咱们将彻底使用Python 3进行开发。Python软件基金会已经宣布Python 2将会被逐步淘汰,而且只支持到2020年;出于该缘由,咱们和许多其余Python爱好者同样,已经将开发转移到对Python 3的支持当中,在本书中咱们将使用3.6版本。本书代码将兼容Python 3.4+的版本。缓存

若是你熟悉Python Virtual EnvironmentsAnaconda的使用,那么你可能已经知道如何在一个新环境中建立Python 3了。若是你但愿以全局形式安装Python 3,那么咱们推荐你搜索本身使用的操做系统的特定文档。就我而言,我会直接使用Virtual Environment Wrapper,这样就能够很容易地对不一样项目和Python版本使用多个不一样的环境了。使用Conda环境或虚拟环境是最为推荐的,这样你就能够轻松变动基于项目需求的依赖,而不会影响到你正在作的其余工做了。对于初学者来讲,我推荐使用Conda,由于其须要的安装工做更少一些。安全

“编写第一个网络爬虫”服务器

为了抓取网站,咱们首先须要下载包含有感兴趣数据的网页,该过程通常称为爬取(crawling)。爬取一个网站有不少种方法,而选用哪一种方法更加合适,则取决于目标网站的结构。本文中,咱们首先会探讨如何安全地下载网页,而后会介绍以下3种爬取网站的常见方法:

  • 爬取网站地图;

  • 使用数据库ID遍历每一个网页;

  • 跟踪网页连接。

到目前为止,咱们交替使用了抓取和爬取这两个术语,接下来让咱们先来定义这两种方法的类似点和不一样点。

1.1抓取与爬取的对比

根据你所关注的信息以及站点内容和结构的不一样,你可能须要进行网络抓取或是网站爬取。那么它们有什么区别呢?

网络抓取一般针对特定网站,并在这些站点上获取指定信息。网络抓取用于访问这些特定的页面,若是站点发生变化或者站点中的信息位置发生变化的话,则须要进行修改。例如,你可能想要经过网络抓取查看你喜欢的当地餐厅的每日特点菜,为了实现该目的,你须要抓取其网站中平常更新该信息的部分。

与之不一样的是,网络爬取一般是以通用的方式构建的,其目标是一系列顶级域名的网站或是整个网络。爬取能够用来收集更具体的信息,不过更常见的状况是爬取网络,从许多不一样的站点或页面中获取小而通用的信息,而后跟踪连接到其余页面中。

除了爬取和抓取外,咱们还会在第8章中介绍网络爬虫。爬虫能够用来爬取指定的一系列网站,或是在多个站点甚至整个互联网中进行更普遍的爬取。

通常来讲,咱们会使用特定的术语反映咱们的用例。在你开发网络爬虫时,可能会注意到它们在你想要使用的技术、库和包中的区别。在这些状况下,你对不一样术语的理解,能够帮助你基于所使用的术语选择适当的包或技术(例如,是否只用于抓取?是否也适用于爬虫?)。

1.2下载网页


要想抓取网页,咱们首先须要将其下载下来。下面的示例脚本使用Python的urllib模块下载URL。


当传入URL参数时,该函数将会下载网页并返回其HTML。不过,这个代码片断存在一个问题,即当下载网页时,咱们可能会遇到一些没法控制的错误,好比请求的页面可能不存在。此时, urllib会抛出异常,而后退出脚本。安全起见,下面再给出一个更稳建的版本,能够捕获这些异常。


如今,当出现下载或URL错误时,该函数可以捕获到异常,而后返回 None

1.重试下载

下载时遇到的错误常常是临时性的,好比服务器过载时返回的503 Service Unavailable错误。对于此类错误,咱们能够在短暂等待后尝试从新下载,由于这个服务器问题如今可能已经解决。不过,咱们不须要对全部错误都尝试从新下载。若是服务器返回的是404 Not Found这种错误,则说明该网页目前并不存在,再次尝试一样的请求通常也不会出现不一样的结果。

互联网工程任务组(Internet Engineering Task Force)定义了HTTP错误的完整列表,从中能够了解到4xx错误发生在请求存在问题时,而5xx错误则发生在服务端存在问题时。因此,咱们只须要确保download函数在发生5xx错误时重试下载便可。下面是支持重试下载功能的新版本代码。


如今,当 download函数遇到 5xx错误码时,将会递归调用函数自身进行重试。此外,该函数还增长了一个参数,用于设定重试下载的次数,其默认值为两次。咱们在这里限制网页下载的尝试次数,是由于服务器错误可能暂时尚未恢复。想要测试该函数,能够尝试下载 http://httpstat.us/500,该网址会始终返回 500错误码。


从上面的返回结果能够看出, download函数的行为和预期一致,先尝试下载网页,在接收到 500错误后,又进行了两次重试才放弃。

2.设置用户代理

默认状况下,urllib使用Python-urllib/``3.x做为用户代理下载网页内容,其中3.x是环境当前所用Python的版本号。若是能使用可辨识的用户代理则更好,这样能够避免咱们的网络爬虫碰到一些问题。此外,也许是由于曾经历过质量不佳的Python网络爬虫形成的服务器过载,一些网站还会封禁这个默认的用户代理。

所以,为了使下载网站更加可靠,咱们须要控制用户代理的设定。下面的代码对download函数进行了修改,设定了一个默认的用户代理‘wswp’(即Web Scraping with Python的首字母缩写)。


如今,若是你再次尝试访问 meetup.com,就可以看到一个合法的HTML了。咱们的下载函数能够在后续代码中获得复用,该函数可以捕获异常、在可能的状况下重试网站以及设置用户代理。
1.3网站地图爬虫

在第一个简单的爬虫中,咱们将使用示例网站robots.txt文件中发现的网站地图来下载全部网页。为了解析网站地图,咱们将会使用一个简单的正则表达式,从<loc>标签中提取出URL。

咱们须要更新代码以处理编码转换,由于咱们目前的download函数只是简单地返回了字节。下面是该示例爬虫的代码。


如今,运行网站地图爬虫,从示例网站中下载全部国家或地区页面。

正如上面代码中的 download方法所示,咱们必须更新字符编码才能利用正则表达式处理网站响应。Python的 read方法返回字节,而正则表达式指望的则是字符串。咱们的代码依赖于网站维护者在响应头中包含适当的字符编码。若是没有返回字符编码头部,咱们将会把它设置为默认值UTF-8,并抱有最大的但愿。固然,若是返回头中的编码不正确,或是编码没有设置而且也不是UTF-8的话,则会抛出错误。还有一些更复杂的方式用于猜想编码(参见 https://pypi.python.org/pypi/chardet),该方法很是容易实现。

到目前为止,网站地图爬虫已经符合预期。不过正如前文所述,咱们没法依靠Sitemap文件提供每一个网页的连接。下一节中,咱们将会介绍另外一个简单的爬虫,该爬虫再也不依赖于Sitemap文件。

1.4ID遍历爬虫

本节中,咱们将利用网站结构的弱点,更加轻松地访问全部内容。下面是一些示例国家(或地区)的URL。

  • http://example.python-scraping.com/view/Afghanistan-1

  • http://example.python-scraping.com/view/Australia-2

  • http://example.python-scraping.com/view/Brazil-3

能够看出,这些URL只在URL路径的最后一部分有所区别,包括国家(或地区)名(做为页面别名)和ID。在URL中包含页面别名是很是广泛的作法,能够对搜索引擎优化起到帮助做用。通常状况下,Web服务器会忽略这个字符串,只使用ID来匹配数据库中的相关记录。下面咱们将其移除,查看http://example.python-scraping.com/view/1,测试示例网站中的连接是否仍然可用。测试结果如图1.1所示。



图1.1

从图1.1中能够看出,网页依然能够加载成功,也就是说该方法是有用的。如今,咱们就能够忽略页面别名,只利用数据库ID来下载全部国家(或地区)的页面了。下面是使用了该技巧的代码片断。


如今,咱们可使用该函数传入基础URL。

在这段代码中,咱们对ID进行遍历,直到出现下载错误时中止,咱们假设此时抓取已到达最后一个国家(或地区)的页面。不过,这种实现方式存在一个缺陷,那就是某些记录可能已被删除,数据库ID之间并非连续的。此时,只要访问到某个间隔点,爬虫就会当即退出。下面是这段代码的改进版本,在该版本中连续发生屡次下载错误后才会退出程序。

上面代码中实现的爬虫须要连续5次下载错误才会中止遍历,这样就很大程度上下降了遇到记录被删除或隐藏时过早中止遍历的风险。

在爬取网站时,遍历ID是一个很便捷的方法,可是和网站地图爬虫同样,这种方法也没法保证始终可用。好比,一些网站会检查页面别名是否在URL中,若是不是,则会返回404 Not Found错误。而另外一些网站则会使用非连续大数做为ID,或是不使用数值做为ID,此时遍历就难以发挥其做用了。例如,Amazon使用ISBN做为可用图书的ID,这种编码包含至少10位数字。使用ID对ISBN进行遍历须要测试数十亿次可能的组合,所以这种方法确定不是抓取该站内容最高效的方法。

正如你一直关注的那样,你可能已经注意到一些TOO MANY REQUESTS下载错误信息。如今无须担忧它,咱们将会在1.5节的“高级功能”部分中介绍更多处理该类型错误的方法。

1.5连接爬虫

到目前为止,咱们已经利用示例网站的结构特色实现了两个简单爬虫,用于下载全部已发布的国家(或地区)页面。只要这两种技术可用,就应当使用它们进行爬取,由于这两种方法将须要下载的网页数量降至最低。不过,对于另外一些网站,咱们须要让爬虫表现得更像普通用户,跟踪连接,访问感兴趣的内容。

经过跟踪每一个连接的方式,咱们能够很容易地下载整个网站的页面。可是,这种方法可能会下载不少并不须要的网页。例如,咱们想要从一个在线论坛中抓取用户帐号详情页,那么此时咱们只须要下载帐号页,而不须要下载讨论贴的页面。本文使用的连接爬虫将使用正则表达式来肯定应当下载哪些页面。下面是这段代码的初始版本。

要运行这段代码,只须要调用 link_crawler函数,并传入两个参数:要爬取的网站URL以及用于匹配你想跟踪的连接的正则表达式。对于示例网站来讲,咱们想要爬取的是国家(或地区)列表索引页和国家(或地区)页面。

咱们查看站点能够得知索引页连接遵循以下格式:

  • http://example.python-scraping.com/index/1

  • http://example.python-scraping.com/index/2

国家(或地区)页遵循以下格式:

  • http://example.python-scraping.com/view/Afghanistan-1

  • http://example.python-scraping.com/view/Aland-Islands-2

所以,咱们能够用/(index|view)/这个简单的正则表达式来匹配这两类网页。当爬虫使用这些输入参数运行时会发生什么呢?你会获得以下所示的下载错误。

能够看出,问题出在下载 /index/1时,该连接只有网页的路径部分,而没有协议和服务器部分,也就是说这是一个 相对连接。因为浏览器知道你正在浏览哪一个网页,而且可以采起必要的步骤处理这些连接,所以在浏览器浏览时,相对连接是可以正常工做的。可是, urllib并无上下文。为了让 urllib可以定位网页,咱们须要将连接转换为 绝对连接的形式,以便包含定位网页的全部细节。如你所愿,Python的 urllib中有一个模块能够用来实现该功能,该模块名为 parse。下面是 link_crawler的改进版本,使用了 urljoin方法来建立绝对路径。

当你运行这段代码时,会看到虽然下载了匹配的网页,可是一样的地点老是会被不断下载到。产生该行为的缘由是这些地点相互之间存在连接。好比,澳大利亚连接到了南极洲,而南极洲又连接回了澳大利亚,此时爬虫就会继续将这些URL放入队列,永远不会到达队列尾部。要想避免重复爬取相同的连接,咱们须要记录哪些连接已经被爬取过。下面是修改后的 link_crawler函数,具有了存储已发现URL的功能,能够避免重复下载。

当运行该脚本时,它会爬取全部地点,而且可以如期中止。最终,咱们获得了一个可用的连接爬虫!

本文摘自《用Python写网络爬虫(第2版)》


《用Python写网络爬虫》


史上首本Python网络爬虫图书全新升级版

针对Python 3.x编写

提供示例完整源码和实例网站搭建源码

本书目录

(滑动手机查看)

第1章 网络爬虫简介 1

1.1 网络爬虫什么时候有用 1

1.2 网络爬虫是否合法 2

1.3 Python 3 3

1.4 背景调研 4

1.4.1 检查robots.txt 4

1.4.2 检查网站地图 5

1.4.3 估算网站大小 6

1.4.4 识别网站所用技术 7

1.4.5 寻找网站全部者 9

1.5 编写第一个网络爬虫 11

1.5.1 抓取与爬取的对比 11

1.5.2 下载网页 12

1.5.3 网站地图爬虫 15

1.5.4 ID遍历爬虫 17

1.5.5 连接爬虫 19

1.5.6 使用requests库 28

1.6 本章小结 30

第2章 数据抓取 31

2.1 分析网页 32

2.2 3种网页抓取方法 34

2.2.1 正则表达式 35

2.2.2 Beautiful Soup 37

2.2.3 Lxml 39

2.3 CSS选择器和浏览器控制台 41

2.4 XPath选择器 43

2.5 LXML和家族树 46

2.6 性能对比 47

2.7 抓取结果 49

2.7.1 抓取总结 50

2.7.2 为连接爬虫添加抓取回调 51

2.8 本章小结 55

第3章 下载缓存 56

3.1 什么时候使用缓存 57

3.2 为连接爬虫添加缓存支持 57

3.3 磁盘缓存 60

3.3.1 实现磁盘缓存 62

3.3.2 缓存测试 64

3.3.3 节省磁盘空间 65

3.3.4 清理过时数据 66

3.3.5 磁盘缓存缺点 68

3.4 键值对存储缓存 69

3.4.1 键值对存储是什么 69

3.4.2 安装Redis 70

3.4.3 Redis概述 71

3.4.4 Redis缓存实现 72

3.4.5 压缩 74

3.4.6 测试缓存 75

3.4.7 探索requests-cache 76

3.5 本章小结 78

第4章 并发下载 79

4.1 100万个网页 79

4.2 串行爬虫 82

4.3 多线程爬虫 83

4.4 线程和进程如何工做 83

4.4.1 实现多线程爬虫 84

4.4.2 多进程爬虫 87

4.5 性能 91

4.6 本章小结 94

第5章 动态内容 95

5.1 动态网页示例 95

5.2 对动态网页进行逆向工程 98

5.3 渲染动态网页 104

5.3.1 PyQt仍是PySide 105

5.3.2 执行JavaScript 106

5.3.3 使用WebKit与网站交互 108

5.4 渲染类 111

5.5 本章小结 117

第6章 表单交互 119

6.1 登陆表单 120

6.2 支持内容更新的登陆脚本扩展 128

6.3 使用Selenium实现自动化表单处理 132

6.4 本章小结 135

第7章 验证码处理 136

7.1 注册帐号 137

7.2 光学字符识别 140

7.3 处理复杂验证码 144

7.4 使用验证码处理服务 144

7.4.1 9kw入门 145

7.4.2 报告错误 150

7.4.3 与注册功能集成 151

7.5 验证码与机器学习 153

7.6 本章小结 153

第8章 Scrapy 154

8.1 安装Scrapy 154

8.2 启动项目 155

8.2.1 定义模型 156

8.2.2 建立爬虫 157

8.3 不一样的爬虫类型 162

8.4 使用shell命令抓取 163

8.4.1 检查结果 165

8.4.2 中断与恢复爬虫 167

8.5 使用Portia编写可视化爬虫 170

8.5.1 安装 170

8.5.2 标注 172

8.5.3 运行爬虫 176

8.5.4 检查结果 176

8.6 使用Scrapely实现自动化抓取 177

8.7 本章小结 178

第9章 综合应用 179

9.1 Google搜索引擎 179

9.2 Facebook 184

9.2.1 网站 184

9.2.2 Facebook API 186

9.3 Gap 188

9.4 宝马 192

9.5 本章小结 196



京东预售



当当预售



今日互动

学会爬虫,你最想作的第一件事儿是什么?为何?截止时间7月21日17时,留言+转发本活动到朋友圈,小编将抽奖选出2名读者赠送纸书2本,文末留言点赞最多的自动得到图书1本。




长按二维码,能够关注咱们哟天天与你分享IT好文。在“异步图书”后台回复“关注”,便可免费得到2000门在线视频课程


点击阅读原文,购买《用Python写网络爬虫(第2版)》


相关文章
相关标签/搜索