初探爬虫 ——《python 3 网络爬虫开发实践》读书笔记

零、背景


之前在 node.js 下写过一些爬虫,去做自己的私人网站和工具,但一直没有稍微深入的了解,借着此次公司的新项目,体系的学习下。

本文内容主要侧重介绍爬虫的概念、玩法、策略、不同工具的列举和对比上,至于具体工具和框架的使用,会单独开辟独立的文章。

下面的工具排行,从上往下表示从简单到复杂,从功能少到功能丰富。

一、爬虫相关工具


爬虫可以简单分为几步:抓取页面、分析页面和存储数据。

1、抓取页面

(1)接口抓取
  • urlin

  • httplib2

  • requests [推荐]

  • aiohttp [推荐]

urlin 和 httplib2 比较基础,需要配合一些库才能实现高级功能。

requests 比较高级,可以有文件上传、会话维持(session)、Cookies、SSL 证书验证、登录验证、代理设置等。

aiohttp ,提供异步 Web 服务的库。

从 Python3.5 版本开始,Python 中加入了 async/await。


接口抓取的缺点是抓不到 js 渲染后的页面,而下面介绍的模拟抓取能很好的解决问题。


(2)模拟抓取

也就是可见即可爬

  • Splash

  • Selenium [推荐]

  • Appium [推荐]

Splash 是一个 javascript 渲染服务。它是一个带有 HTTP API 的轻量级 Web 浏览器。


Selenium 是一个自动化测试工具,利用它我们可以驱动测览器执行特定的动作,如点击、下拉等操作。

Selenium + Chrome Driver,可以驱动 Chrome 浏览器完成相应的操作。

Selenium + Phantoms,这样在运行的时候就不会再弹出一个浏览器了。而且 Phantoms 的运行效率也很高。

Phantoms 是一个无界面的、可脚本编程的 Webkit 7 浏览器引擎。


Appium 是 App 版的 Selenium。

2、分析页面

抓取网页代码之后,下一步就是从网页中提取信息。


  • 正则

  • lxml

  • Beautiful Soup

  • pyquery

正则是最原始的方式,写起来繁琐,可读性差。

lxml 是 Python 的一个解析库,支持 HTML 和 XML 的解析,支持 XPah 解析方式。

Beautiful Soup 的 HTML 和 XML 解析器是依赖于 lxml 库的,所以在此之前请确保已经成功安装好了 lxml。

Beautiful Soup提供好几个解析器:

初探爬虫 ——《python 3 网络爬虫开发实践》读书笔记_第1张图片

pyquery 同样是一个强大的网页解析工具,它提供了和 jquery 类似的语法来解析 HTML 文档。


推荐:

Beautiful Soup(lxml)。lxml 解析器有解析 HTML 和 XML 的功能,而且速度快,容错能力强。

如果本身就熟悉 css 和 jquery 的话,就推荐 pyquery。

3、存储数据

  • 关系型
    MYSQL - python 环境需安装 PyMySQL

  • 非关系型
    Mongodb - python 环境需安装 Pymongo
    Redis

拓展:

NOSQL,全称 Not Only SQL,意为不仅仅是 SQL,泛指非关系型数据库。包括:

口 键值存储数据库:代表有 Redis、Voldemort 和 Oracle BDB 等

口 列存储数据库:代表有 Cassandra、Hbase 和 Riak 等。

口 文档型数据库:代表有 COUCHDB 和 Mongodb 等。

口 图形数据库:代表有 Neo4J、infogrid 和 Infinite Graph 等。

4、抓包

针对一些复杂应用,尤其是 app,请求不像在 chrome 的 console 里那么容易看到,这就需要抓包工具。

  • Wireshark

  • Fiddler

  • Charles [推荐]

  • mitmproxy(mitmdump) [推荐]

mitmproxy(mitmdump) 比 Charles 更强大的是,可以支持对接 Python 脚本去处理 resquest / response。

5、爬 APP 的最佳实践

方案:Appium + mitmdump

做法:用 mitmdump 去监听接口数据,用 Appium 去模拟 App 的操作

好处:即可绕过复杂的接口参数又能实现自动化提高效率。

缺点:有一些 app,如微信朋友圈的数据又经过了一次加密导致无法解析,这种情况只能纯用 Appium 了。但是对于大多数 App 来说,此种方法是奏效的。

二、爬虫框架


1、pyspider

pyspide 框架有一些缺点,比如可配置化程度不高,异常处理能力有限等,它对于一些反爬程度非常强的网站的爬取显得力不从心。

所以这里不多做介绍。

2、Scrapy

Scrapy 是一个基于 Twisted 的异步处理框架,是纯 Python 实现的爬虫框架。


Scrapy 包括:

Scrapy-Splash:一个 Scrapy 中支持 Javascript 渲染的工具。

Scrapy-Redis :Scrap 的分布式扩展模块。

Scrapyd :一个用于部署和运行 Scrapy 项目的工具。

Scrapyrt :为 Scrap 提供了一个调度的 HTTP 接口。

Gerapy :一个 Scrapy 分布式管理模块。


Scrapy 可对接:

Crawlspider : Scrap 提供的一个通用 Spider,我们可以指定一些爬取规则来实现页面的提取,

Splash / Selenium :自动化爬取

Docker


具体使用:待写

三、爬虫拓展的基础知识


1、URI、URL、URN 区别

URI 的全称为 Uniform Resource Identifier,即统一资源标志符。

URL 的全称为 Universal Resource Locator,即统一资源定位符。

URN 的全称为 Universal Resource Name,即统一资源名称。

初探爬虫 ——《python 3 网络爬虫开发实践》读书笔记_第2张图片

URI 可以进一步划分为URL、URN或两者兼备。URL 和 URN 都是 URI 子集。

URN 如同一个人的名称,而 URL 代表一个人的住址。换言之,URN 定义某事物的身份,而 URL 提供查找该事物的方法。


现在常用的http网址,如 http://www.waylau.com 就是URL。

而用于标识唯一书目的 ISBN 系统, 如:isbn:0-486-27557-4 ,就是 URN 。


但是在目前的互联网中,URN 用得非常少,所以几乎所有的 URI 都是 URL。

2、Robots 协议

(1)什么是 Robots 协议

Robots 协议也称作爬虫协议、机器人协议,它的全名叫作网络爬虫排除标准(Robots Exclusion Protocol),用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取。它通常是一个叫作robots.txt 的文本文件,一般放在网站的根目录下。

当搜索爬虫访问一个站点时,它首先会检查这个站点根目录下是否存在 robots.txt 文件,如果存在搜索爬虫会根据其中定义的爬取范围来爬取。如果没有找到这个文件,搜索爬虫便会访问所有可直接访问的页面。

(2)使用方法

robotx.txt 需要放在网站根目录。

User-agent: *
Disallow: /
Allow: /public/

Disallow表示不允许爬的页面,Allow表示允许爬的页面,User-agent表示针对哪个常用搜索引擎。

User-agent 为约定好的值,取值如下表:

初探爬虫 ——《python 3 网络爬虫开发实践》读书笔记_第3张图片

(3)什么场景下,网站不希望被搜索引擎爬到并收录

1、测试环境

2、管理后台(如 cms)

3、其它

(4)工具

1、Google的 Robots.txt 规范。

2、站长工具的 robots文件生成 工具。

3、Xpath

Xpath,全称 XML Path Language,即 XML 路径语言,它是一门在 XML 文档中査找信息的语言。它最初是用来搜寻 XML 文档的,但是它同样适用于 HTML 文档的搜索

Xpath 的选择功能十分强大,它提供了非常简洁明了的路径选择表达式。另外,它还提供了超过 100 个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等。

Xpath 于 1999 年 11 月 16 日成为 W3C 标准。

就好像 css 选择器。

四、验证码的识别


1、图形验证码

可以使用 Tesseract ,它是 Python 的一个 OCR 识别库。

2、滑动验证码

市面上用的最多的是这家提供的滑动验证码:http://www.geetest.com/ ,如 bilibili。

可以用自动化库,如 Selenium 模拟滑动(注意人去滑动按钮是先快后慢)。

3、微博宫格验证码

解决思路:模板匹配+模拟拖动

4、点触验证码

还有一个专门提供点触验证码服务的站点 Touclick,例如 12306 网站。

5、总结

上面说的第四个:点触验证码,应该是最难识别的了。

但互联网上有很多验证码服务平台,平台 7×24 小时提供验证码识别服务,一张图片几秒就会获得识别结果,准确率可达 90%以上。

个人比较推荐的一个平台是超级鹰,其官网为 https://www.chaoying.com 。其提供的服务种类非常广泛,可识别的验证码类型非常多,其中就包括点触验证码。

五、代理的使用 - 代理池


1、代理分类

(1)根据协议区分

FTP 代理服务器:主要用于访问 FTP 服务器,一般有上传、下载以及缓存功能,端口一般为 21、2121 等。

HTP 代理服务器:主要用于访问网页,一般有内容过滤和缓存功能,端口一般为 80、8080、3128等。

SSL/TLS代理:主要用于访问加密网站,一般有SSL或TLS加密功能(最高支持 128 位加密强度),端口一般为 443。

RTSP 代理:主要用于访问 Real 流媒体服务器,一般有缓存功能,端口一般为 554。

Telnet 代理:主要用于 telnet 远程控制(黑客入侵计算机时常用于隐藏身份),端口一般为 23。

POP3 SMTP 代理:主要用于 POP3 SMTP 方式收发邮件,一般有缓存功能,端口一般为 11025 。

SOCKS 代理:只是单纯传递数据包,不关心具体协议和用法,所以速度快很多,一般有缓存功能,端口一般为 1080。SOCKS 代理协议又分为 SOCKS4 和 SOCKS5,前者只支持 TCP,而后者支持 TCP 和 UDP,还支持各种身份验证机制、服务器端域名解析等。简单来说,SOCKS4 能做到的 SOCKS5 都可以做到,但 SOCKS5 能做到的 SOCKS4 不一定能做到。

(2)根据匿名程度区分

高度匿名代理:会将数据包原封不动地转发,在服务端看来就好像真的是一个普通客户端在访问,而记录的 IP 是代理服务器的 IP。

普通匿名代理:会在数据包上做一些改动,服务端上有可能发现这是个代理服务器,也有一定几率追查到客户端的真实 IP。代理服务器通常会加入的 HTIP 头有 HTTPVIA 和 HTTPXFORWARDEDFOR。

透明代理不但改动了数据包,还会告诉服务器客户端的真实 IP。这种代理除了能用缓存技术提高浏览速度,能用内容过滤提高安全性之外,并无其他显著作用,最常见的例子是内网中的硬件防火墙。

间谍代理:指组织或个人创建的用于记录用户传输的数据,然后进行研究、监控等目的的代理服务器。

2、购买代理

(1) 免费代理

网站上会有很多免费代理,比如西刺:http://www.xicidaili.com 。但是这些免费代理大多数情况下都是不好用的,所以比较靠谱的方法是购买付费代理。

(2) 收费代理

1、提供接口获取海量代理,按天或者按量收费,如讯代理;

如果信赖讯代理的话,我们也可以不做代理池筛选,直接使用代理。不过我个人还是推荐使用代理池筛选,以提高代理可用概率。自己再做一次筛选,以确保代理可用


2、搭建了代理隧道,直接设置固定域名代理,如阿布云代理。云代理在云端维护一个全局 IP 池供代理隧道使用,池中的 IP 会不间断更新。代理隧道,配置简单,代理速度快且非常稳定。

等于帮你做了一个云端的代理池,不用自己实现了。

需要注意的是,代理 IP 池中部分 IP 可能会在当天重复出现多次。


3、ADSL 拨号代理

ADSL (Asymmetric Digital Subscriber Line,非对称数字用户环路),它的上行和下行带宽不对称,它采用频分复用技术把普通的电话线分成了电话、上行和下行 3 个相对独立的信道,从而避免了相互之间的干扰。

我们利用了 ADSL 通过拨号的方式上网,需要输入 ADSL 账号和密码,每次拨号就更换一个 IP 这个特性。

所以我们可以先购买一台动态拨号 VPS 主机,这样的主机服务商相当多。在这里使用了云立方,官方网站: http://www.yunlifang.cn/dynamicvps.asp

3、代理池的实现

代理不论是免费的还是付费的,都不能保证都是可用的,因为:

1、此 IP 可能被其他人使用来爬取同样的目标站点而被封禁。

2、代理服务器突然发生故障。

3、网络繁忙。

4、购买的代理到期。

5、等等

所以,我们需要提前做筛选,将不可用的代理剔除掉,保留可用代理。这就需要代理池,来获取随机可用的代理

初探爬虫 ——《python 3 网络爬虫开发实践》读书笔记_第4张图片

代理池分为 4 个模块: 存储模块、获取模块、检测模块、接口模块

口 存储模块使用 Redis 的有序集合,用来做代理的去重和状态标识,同时它也是中心模块和基础模块,将其他模块串联起来。

口 获取模块定时从代理网站获取代理,将获取的代理传递给存储模块,并保存到数据库。

口 检测模块定时通过存储模块获取所有代理,并对代理进行检测,根据不同的检测结果对代理设置不同的标识。

口 接口模块通过WebAPI 提供服务接口,接口通过连接数据库并通过Web 形式返回可用的代理。

对于这里的检测模块,建议使用 aiohttp 而不是 requests,原因是:

对于响应速度比较快的网站来说,requests 同步请求和 aiohttp 异步请求的效果差距没那么大。但对于检测代理来说,检测一个代理一般需要十多秒甚至几十秒的时间,这时候使用 aiohttp 异步请求库的优势就大大体现出来了,效率可能会提高几十倍不止。

六、模拟登录 - cookies 池


1、为什么需要模拟登录

(1)有的数据必须要登录才能抓取。

(2)有时候,登录账号也可以降低被封禁的概率。

2、Cookies 池的实现

做大规模抓取,我们就需要拥有很多账号,每次请求随机选取一个账号,这样就降低了单个账号的访问颍率,被封的概率又会大大降低。

所以,我们可以维护一个登录用的 Cookies 池

架构跟代理池一样。可参考上文。

七、分布式爬虫 & 分布式爬虫的部署


待写

拓展


1、打开文件的模式

python 的 open() 支持的模式可以是只读/写入/追加,也是可以它们的组合型,具体如下:

模式 描述
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

1、r+ 和 w+ 都是读写,有什么区别?

答:前者是如果没有找到文件则抛错,后者是如果没有找到文件则自动创建文件。

2、a 可以看成是 w 的变种,附加上了”追加内容“的特性。

一般调用 open() 的时候还需要再调用 close()。 python 提供了一种简写方法,那就是使用 with as 语法。在 with 控制块结束时,文件会自动关闭,不需要 close() 了。调用写法如下:

with open('explore.txt', 'a', encoding ='utf-8') as file:    
    file.write('123' + '\n')

你可能感兴趣的:(初探爬虫 ——《python 3 网络爬虫开发实践》读书笔记)