爬虫实战1—爬虫的基础技术
文章说明:本文是在学习一个网络爬虫课程时所做笔记,文章如有不对的地方,欢迎指出,积极讨论。
一、Python Windows环境搭建及基础类
下载并安装Anaconda,具体安装配置过程参照Anaconda安装
Anaconda:是一个用于科学计算的Python发行版,是一个和Canopy类似的科学计算环境,但用起来更加方便。自带的包管理器也很强大。可以完美的兼容Python2.7和Python3.5,并集成了许多packages,免去配置环境的烦恼。
二、HTML、CSS及JavaScript(详细教程参照w3school)
(一)HTML(Hyper Text Markup Language)超文本标记语言
HTML是用来描述网页的一种语言,它不是一种编程语言,而是一种标记语言。标记语言是一套标记标签,HTML使用标记标签来描述网页。
HTML标签是由尖括号包围的关键词(比如:<html>),且通常是成对出现的,第一个是开始标签(开放标签openning tag),第二个是结束标签(闭合标签closing tag)。(<html>…</html>)
HTML文档描述网页,包含HTML标签和纯文本,也被称为网页。
(二)CSS(Cascading Style Sheet )层叠样式表单(对大小写不敏感)
样式定义如何显示HTML元素,样式通常存储在样式表中。外部样式表可以极大提高工作效率,通常存储在CSS文件中。多个样式可以层叠为一。
层叠规则:
(1)浏览器缺省设置;
(2)外部样式表;
(3)内部样式表(位于标签内部);
(4)内联样式(位于HTML元素内部) 拥有最高的优先权
常用的CSS选择器有派生选择器、id选择器、类选择器和属性选择器。
(三)JavaScript
运行在(前端)浏览器上的编程语言,最典型的用在动态网页的数据、内容加载及呈现上,JavaScript做网络请求的时候最常用的技术成为AJAX(Asynchronous Javascript And Xml),专门用来异步请求数据。
三、HTTP协议及Python的DOM树选择器
(一)HTTP协议
HTTP协议(Hyper Text Transfer Protocol):超文本传输协议。是用于从万维网服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML文件、图片文件、查询结果等)。
HTTP工作原理:
(1)HTTP协议工作于客户端—服务端架构之上。浏览器作为HTTP客户端通过URL向HTTP服务端即Web服务器发送所有请求。
(2)Web服务器有Apache服务器、IIS服务器(Internet Information Services)等。
(3)Web服务器接到请求后,向客户端发送响应信息。
(4)HTTP默认端口为80,但是你也可以改为8080或者其他端口。
HTTP三点注意事项:
(1)HTTP是无连接:即限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
(2)HTTP是媒体独立的:只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type(Multipurpose Internet Mail Extensions 多用途的网际邮件扩充协议)内容类型。
(3)HTTP是无状态:无状态是指协议对于事物处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
Cookie:有时也用其复数形式cookies,值某些网站为了辨别用户身份,进行session跟踪而储存在用户本地终端(terminal)上的数据。
Session:“会话控制”,session对象存储特定用户会话所需的属性及配置信息。
HTTPS(Hyper Text Transfer Protocol over Secure Sockets Layer)
TCP/IP四层与IOS七层:
应用层 |
应用层(HTTP、FTP) |
表示层(每次连接只处理一个请求) |
|
会话层(建立通信连接,网络拨号) |
|
传输层 |
传输层(TCP、UDP协议) |
互联网络层 |
网络层(路由器,IP协议) |
网络接口层 |
数据链路层(交换机,STP,帧中继) |
物理层(电器连接) |
TCP/IP协议 (Transfer ControlProtocol / Internet Protocol)传输控制协议/互联网协议(详细教程参照TCP/IP教程)
TCP/IP是基于TCP和IP这两个最初的协议之上的不同通信协议的大的集合(协议族)。
又称网络通讯协议,由网络层IP协议和传输层TCP协议组成。定义电子设备如何进入互联网,以及数据如何在它们之间传输的标准。协议采用了4层的层次结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
IP:给因特网中每一台连网设备规定一个网址。接受由更低层(网络接口层)发来的数据包,并把数据包发送到更高层(TCP或UDP层);相反,也把TCP或UDP层接收来的数据包发送到更低层。IP数据包是不可靠的,因为IP并没有做任何事情来确定数据包是否接收顺序发送的或者有没有损坏。
TCP:是面向连接的通信协议,通过三次握手建立连接,通讯完成是要拆除连接。由于TCP是面向连接的,所以只能用于端到端的通讯。
三次握手:
第一次,建立连接时,客户端发送SYN包,并进入SYN-SENT状态,等待服务器确认;
第二次,服务器收到SYN包,确认客户的SYN包,同时自己也发送一个SYN包,即SYN+ACK,此时服务器进入SYN-RECV状态; ( synchronous +acknowledgement , 同步 + 确认 )
第三次,客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,此包发送完毕,客户端可服务器进入ESTABLISED状态。 ( established ,连接成功 )
完成三次握手,客户端与服务器开始传输数据。
改进的三次握手(关闭TCP连接):
第一步,当主机A的应用程序通知TCP数据已经传送完毕时,TCP向主机B发送一个带有FIN(finish)附加标记的报文段;
第二步,当主机B收到这个FIN报文段后,并不立即用FIN报文段回复主机A,而是先向主机A发送一个确定序号ACK,同时通知自己的相应的应用程序:对方要求关闭连接;
第三步,主机B的应用程序告诉TCP:我要彻底的关闭连接,TCP向主机A发送一个FIN报文段;
第四步,主机A收到这个FIN报文段好,向主机B发送一个ACK表示联机彻底释放。
HTTP请求方法
(1)get:无body,请求参数放在Query String 里,出现在URL中,是纯粹的请求数据的方法,不需要修改,是safe的。
(2)post:有body,上传一个自己的请求文件。不safe。
HTTP响应状态码
(1)1** 信息,服务器收到请求,需要请求者继续执行操作;
(2)2** 成功,操作被成功接收并处理;
(3)3** 重定向,需要进一步的操作以完成请求;
300(multiple choices)多种选择。存在多个可用的资源,可处理或丢弃
301(moved permanetly)永久移动。请求的资源已被永久的移动到新的URL,返回信息会包括新的URL,浏览器会自动定向到新URL。
302(found)临时移动。与301类似,但资源只是临时被移动。客户端应继续使用原有URL。
303(see other)查看其它地址。与301类似。
304(not modified)未修改。所请求的资源未修改,服务器返回此status code时,不会返回任何资源。
305(use proxy)使用代理。所请求的资源必须通过代理访问。
(4)4** 客户端错误,请求包含语法错误或无法完成请求;
400(bad request)请求有语法错误,不能被服务器所理解——检查请求的参数或者路径
401(unauthorized)请求未经授权,这个状态必须和WWW-Authenticate报头域一起使用——如果需要授权的网页,尝试重新登录
403(forbidden)服务器收到请求,但是拒绝服务——(1)如果是需要登录的网站,尝试重新登录;(2)IP被封,暂停爬取,并增加爬虫的等待时间,如果拨号网络,尝试重新连网更改IP
404(not found)请求资源不存在。比如输入错误的URL——直接丢弃
405(method not)客户端请求中的方法被禁止
(5)5xx 服务器错误,服务器在处理请求的过程中发生了错误。
500(internet server error)服务器内部错误,无法完成请求
501(not implemented)服务器不支持请求的功能,无法完成请求
503(server unavailable)服务器当前不能处理客户端的请求,一段时间后可能恢复正常
如果是500、501错误,可以直接放弃爬取。
PHP(Hypertext Preprocessor):超文本预处理器。创建动态交互性站点的服务器端脚本语言。
CGI(Common Gateway Interface):通用网关接口。CGI是外部应用程序(CGI程序)与web服务器之间的接口标准,是在CGI程序和web服务器之间传递信息的过程。
API和GUI都属于直接用户接口。
GUI(Graphic User Interface):图形用户接口。是指采用图形方式显示的计算机操作页面。
API(Application Program Interface):应用程序编程接口。是一些预先定义的函数,莫得是提供应用程序和开发人员基于某软件或是某硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制。 例程的作用类似于函数。例程是某个系统对外提供的功能接口或服务的集合。编写一个DLL(动态链接库 dynamic link library)文件的时候,里面的输出函数就是这个DLL的例程。
(二)DOM树(详细教程参照HTML DOM)
DOM(Document Object Model):文档对象模型。DOM是一种与浏览器、平台、语言无关的接口。
HTML DOM定义了访问和操作(如何获取、修改、添加或删除)HTML文档的标准方法。
DOM将HTML文档表达为树结构。
HTML DOM方法:可通过JavaScript对HTML DOM进行访问。熟悉软件开发的人员可以将HTML DOM理解为网页的API。
href属性:HypertextReference(超文本引用)
四、宽度与深度抓取介绍及比较
1.网页抓取原理:
宽度(BSF:Broad SearchFirst)
深度(DSP:Depth SearchFirst)
2.爬虫的抓取对象类型
(1)静态网页(维基百科)
(2)动态网页(淘宝、京东)
(3)Web Service(API数据获取)—更加高效
3.选择哪种策略
(1)重要的网页距离种子站点比较近(met-depth)
(2)万维网的深度并没有很深,一个网页有很多路径可以到达
(3)宽度优先有利于多爬虫并行合作抓取
(4)深度限制与宽度优先相结合(BSF + max-depth)
消息队列:在消息的传输过程中保存消息的容器。
五、不重复抓取策略及bloomfilter
(一)如何记录抓取历史(整个互联网网站是一个环)
1.将访问过的URL保存到数据库(效率太低)
2.用HashSet将访问过的URL保存起来。那只需接近O(1)的代价就可以查到一个URL是否查到一个URL是否被访问过了。(消耗内存)
3.URL经过MD5或SHA-1等单向哈希后在保存到HashSet或数据库。
4.Bit-Map方法。建立一个BitSet,将每个URL经过一个哈希函数映射到某一位。
MD5 —message digest algorithm(信息摘要算法)
任何人都有自己独一无二的指纹,与之类似,MD5可以为任何文件(不管其大小、格式、数量)产生一个同样独一无二的“数字指纹”,如果任何
人对文件做了任何改动,其MD5值也就是对应的“数字指纹”都会发生变化。
Hash,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。
Hashset类,是存在于java.util包中的类。同时也被称为集合,该容器中只能存储不重复的对象。
MD5签名是一个哈希函数,可以将任意长度的数据量转换为一个固定长度的数字(通常是4个整型,128位)。
(1)数字签名应用
(2)安全访问认证应用
提高效率:
1.评估网站的网页数量(例:site:www.mafengwo.cn)
2.选择合适的HASH算法和空间阙值,降低碰撞几率
3.选择合适的存储结构和算法
Bitmap:位图文件,扩展名可以上.bmp或者.dib。是Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示。位图文件图像效果好,但是非压缩格式的,需要占用较大存储空间,不利于在网络上传送。Jpg格式则恰好弥补了位图文件这个缺点。
Bitset:C++语言的一个类库,用来方便地管理一系列的bit位而不用程序员自己来写代码。
安装bitarray和mmh3: 在Anaconda Prompt里输入
pip install bitarray
pip install mmh3
Bitmap方式记录:
将URL的MD5值再次hash,用一个或多个bit位来记录URL1.确定空间大小
2.按倍增加槽位
3.HASH算法映射(murmurhash3,cityhash)python:mmh3bitarray
优势:对存储进行了进一步压缩,在MD5的基础上,可以从128位最多压缩到一位。
缺陷:碰撞概率增加。
(二)BloomFilter
Bloom Filter使用了多个哈希函数,当且仅当m个哈希结果一样时,才认为两个字符串是一样的。这样降低了碰撞的概率。
安装pybloomfilter:pip install pybloomfilter
如何有效记录抓取历史:
(1)多数情况下不需要压缩,尤其网页数量少的情况
(2)网页数量大的情况下,使用bloomfilter压缩
(3)重点是计算碰撞概率,并根据碰撞概率来确定压缩空间的阈值
(4)分布式系统,将散列映射到多台主机的内存