网络爬虫基础
1.1 HTTP基本原理
1.1.1 URI和URL
URI即统一资源标志符,URL即统一资源定位符。
有这样一个链接,http://test.com/test.txt
,在这个链接中,包含了访问协议https,访问目录(即根目录),资源名称(test.txt)。通过这样的链接,可以在互联网上找到这个资源,这就是URI/URL。
URL是URI的子集,每个URL都是URI,但在URI中还包含另一个子类URN,即统一资源名称,可以唯一标识这本书,但是没有指定到哪里定位这本书。
在当今网络中,很少使用URN,一般来说URI就是URL。
1.1.2 超文本
超文本就是网页的HTML源代码。
在浏览器中任意打开一个页面,右击选择检查,点击Elements就可以看到网页的源代码,里面包含了各种标签,网站正是解析了这些代码才形成了网页,这些代码就是超文本。
1.1.3 HTTP和HTTPS
在URLhttp://test.com/test.txt
中,开头通常都是http
或者https
这就是访问资源需要的协议类型。
HTTP,中文名为超文本传输协议,用于从网络传输超文本数据道本地浏览器,保证高效而准确的传送超文本文档。
HTTPS,中文名为超文本传输安全协议,是HTTP的安全版,即HTTP下加入SSL层,简称HTTPS。因此,它传输的内容都是经过SSL加密的,它的主要作用是:
- 建立一个信息安全通道来保证数据传输安全。
- 确认网站的真实性。使用HTTPS的网站,都可以通过点击浏览器地址栏的锁头标志查看网站的真实信息。
1.1.4 HTTP请求过程
当我们在浏览器地址栏中输入了一个URL,回车之后,浏览器进行加载,就可以看到页面内容。
在这个过程中,就是我们的浏览器向网站服务器发送了一个请求,网站解析后,返回给浏览器一个回应,回应中包含了页面的源代码等,浏览器解析之后,就呈现出了网页。
1.1.5 请求
请求,由客户端向服务端发出,包括四部分内容:
- 请求方法
- 请求网站
- 请求头
- 请求体
1.请求方法
常见的请求方法有两种:GET和POST。
GET请求:在浏览器中输入URL并回车,这就是一个GET请求,请求的参数直接包含在URL中。
POST请求:在表单提交时发生,例如在登陆时,填写账号密码,点击登陆,通常就会发起一个POST请求,请求的数据通常一表单的形式传输。
GET和POST有如下区别:
- GET请求的参数通常包含在URL中,数据可以在URL中看到;post请求的URL不包含数据,数据以表单形式传输,包含在请求体中。
- GET请求提交的数据最多只有1024字节;POST在数据量上没有限制。
此外还有其他请求方法:
GET 请求页面,并返回页面内容。
HEAD 类似与GET请求,返回的相应中不含具体内容,用于获取报头。
POST 大多数用于提交表单或者上传文件,数据包含在请求体中。
PUT 从客户端向服务器传送的数据取代指定文档中的内容。
DELETE 请求服务器删除指定页面。
CONNECT 把服务器当跳板,让服务器代替客户端访问其他网页。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或者诊断。
2. 请求的网址
即是统一资源定位符URL。
3.请求头
用来说明服务器要使用的附加信息。
Accept:请求报头域,用于指定客户端可接受哪些信息。
Accept-Language:指定客户端可接受的语言类型。
Accept-Encoding:指定客户端可接受的内容编码。
Host:用于指定请求资源的主机IP和端口号,其内容为请求URL的原始服务器货网关的位置。
Cookie:也常用Cookies。这是网站为辨别用户而存储在用户本地的数据,主要功能为维持当前访问对话,登陆之后,服务器对应信息就会存储在Cookies中,每当浏览器向服务器发出请求时,就会在请求头中加入Cookies,服务器以此辨识用户身份,并且识别状态为登陆状态,返回登陆后的结果。
Referer:标识这个请求从哪个页面发出。
User-Agent:一个特殊的字符串头,使服务器识别用户的操作系统及版本,浏览器及版本等信息。制作爬虫时使用此信息伪装成浏览器。
Content-Type:及互联网媒体类型,在HTTP协议消息头中用来表示具体请求中的媒体信息类型。
4.请求体
一般来说,对于GET请求,请求体为空。
POST请求中,请求体承载表单数据。
并且在POST请求中,必须要有正确的Content-Type,对于各种请求库的各个参数设置对应的Content-Type。
1.1.6 响应
响应即是服务器返回给客户端的结果。可以分为三部分:响应状态码,响应头,响应体。
1.响应状态码
响应状态码表示服务器的响应状态。在爬虫中,可以根据状态码来判断服务器的响应状态。
2.响应头
响应头中包含了服务器对请求的应答信息。
- Date:标识响应产生的时间。
- Last-Modified:指定资源的最后修改时间。
- Content-Encding:指定响应内容的编码。
- Server:包含服务器的信息,比如名称,版本号等。
- Content-Type:文档类型,指定返回的数据类型是什么。
- Set-Cookies:设置Cookies。
- Expires:指定响应的过期时间,可以使代理服务器或浏览器将加载的内容更新到缓存中,再次访问时,就可以直接从缓存中加载,降低服务器负载,减短加载时间。
3.响应体
响应的正文数据都在响应体中。制作爬虫时,我们通过响应体得到网页的源代码,JOSN数据,从中提取相应内容。
2.2 网页基础
2.2.1 网页的组成
网页分为三大部分–HTML,CSS,JavaScript。把网页比作一个人,HTML相当于骨架,JavaScript相当于肌肉,CSS相当于皮肤。
1.HTML
HTML是一种描述网页的语言,即超文本标记语言。在网页中的文字,按钮,图片,视频等各种复杂的元素,其基础架构就是HTML。通过不同类型的标签来表示不同类型的元素,对标签进行不同的排列和嵌套形成了网页的框架。
2.CSS
CSS,即层叠样式表。
层叠,是指当在HTML中引用了数个样式文件,并且样式发生冲突时,浏览器能够依据层叠顺序处理。
样式,是指网页中文字大小,颜色,元素间距,排列等格式。
CSS是目前唯一的网页页面排版样式标准,它可以使页面变得更加美观。
在网页中,一般会统一定义整个网页的样式规则,并写入CSS文件(其后缀为.css)中。在HTML中,只需使用link标签,即可引入写好的CSS文件。
3.JavaScript
JavaScript简称JS,是一种脚本语言。搭配使用HTML和CSS,只能给用户提供一种静态信息,缺乏交互性,而JavaScript可以提供一种实时,动态,交互的页面功能,如加载进度条,提示框等。
JavaScript也是以单独文件进行加载,后缀名为js,在HTML中通过script标签即可引入。
综上,HTML定义了网页的内容和结构,CSS描述了网页的布局,JavaScript定义了网页的行为。
2.2.2 网页的结构
在一个简单的HTML中,首先在开头使用DOCTYPE来定义文档类型,其次是最外层的html标签,其内部是head标签和body标签,分别代表网页头和网页体。
在head中定义了一些页面的配置和引用,如:
- <meta charset=“UTF-8”> 就指定了网页的编码为UTF-8。
- title定义了网页的标题,显示在网页的选项卡中,不会显示在正文中。
在body标签中即是显示在网页正文中的内容。
div标签定义了网络中的区块,在其中可以设置id,class等属性,id属性唯一,我们可以通过id属性来获取对应区块。
一个网页的标准形式就是在html标签内嵌套head和body标签,head内定义网页的配置和引用,body内定义网页的正文。
2.2.3 节点树及节点间的关系
在html中,所有标签定义的内容都是节点,他们构成了一个HTML DOM树。
DOM是W3C(万维网联盟)的标准,即文档对象模型,它定义了访问HTML和XML文档的标准:
W3C文档对象模型(DOM)是中立与平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容,结构和样式。
W3C DOM 标准被分为三个不同的部分:
- 核心 DOM:针对任何结构化文档的标准模型。
- XML DOM:针对XML文档的标准模型。
- HTML DOM:针对HTML文档的标准模型。
根据W3C的HTML DOM标准,HTML文档中的所有内容都是节点。 - 整个文档都是一个文档节点。
- HTML元素都是元素节点。
- HTML元素内的文本是文本节点。
- 每个HTML属性都是属性节点。
- 注释是注释节点。
HTML DOM 将HTML文档视作树结构,这种结构被称为节点树。树中所有节点都可以通过JavaScript访问,所有HTML节点元素均可以被修改,创建删除。
在节点树中的节点彼此间拥有层级关系,用,父,子,兄弟等术语来描述这些关系。
顶端节点被称为根,每个节点都有父节点,同时可以拥有任意数量的子节点或者兄弟节点。
2.2.4 选择器
网页由一个个节点组成,CSS选择器会根据不同的节点来设置不同的样式规则。
我们可以使用CSS选择其来定位节点。
有三种常用的筛选方法:
-
- 根据id筛选,
#container
,以#
开头,后面紧跟id的名称。
- 根据id筛选,
- 2.根据class筛选,
.wrapper
,以.
开头,后面紧跟class的名称。 - 3.根据标签名筛选,比如想要选择二级标题,可以使用
h2
来选择。
此外,还支持嵌套选择,各个选择器间加上空格分隔开表示嵌套关系。
如#container .wrapper p
,就表示先选取id为container的节点,再选取其中class为wrapper的节点,再选取其中的p节点。
不加空格,则代表并列关系。
如div#container .wrapper p
,就表示先选取id为container的div节点,再选取其中class为wrapper的节点,再选取其中的p节点。
在CSS中还有许多其他的选取方式。
另外,还有其他常用的选择器,如Xpath,BS等。
2.3 爬虫的基本原理
把互联网比作一张大网,网的节点即是一个个网页,节点与节点间的连接就是网站与网站之间的链接关系。
爬虫就是在网络上爬行的蜘蛛,蜘蛛爬到一个节点,就相当于访问了一个网页,获取了它的信息,蜘蛛通过一个节点以后,还可以通过节点间的线到达下一个节点。
2.3.1 爬虫概述
爬虫就是获取网页并提取和保存信息的自动化程序。
1.获取网页
爬虫的首要工作就是获取网页,即获取网页的源代码,其中包含了网页中的有用信息。
向网站发送请求,返回的响应体就是页面源代码。关键部分就是构造请求发送给服务器,然后接受响应并将其解析出来。
2.提取信息
获取网页源代码后,接下来就是分析网络源代码,从中提取数据。
最通用的方法是通过正则表达式提取,这个方法非常万能,但在构造时比较复杂且容易出错。
此外,也可以根据网页的结构规则,根据网页节点属性,CSS选择器,Xpath选择器来提取,如Python中Beautful Soup,pyquery,lxml等。
3.保存数据
提取数据后,一般会将数据保存起来以便后续使用,如可以简单的保存为TXT文本或者JOSN文本,也可以保存到数据库中,如mysql或者MongoDB等。
4.自动化程序
爬虫获取的的数据人手工当然也可以获取,但当需要获取的数据量特别大或者想要快速获取大量数据的话,必然是要借助程序。爬虫就是代替人来完成这些操作的自动化程序。
2.3.2 能抓怎样的数据
常见的网页都是常规网页,使用着HTML代码,一般抓取的就是HTML代码。
也有些网页返回的不是HTML代码,而是JOSN字符串,这种数据同样可以抓取,而且提取数据更加方便。
此外,还有一些二进制文件,如图片,视频,音频等,我们同样可以通过爬虫进行抓取。
还有一些各种扩展名的文件,如CSS,JavaScript,配置文件等,同样可以抓取。
上述的文件,其实都有对应的URL,都是基于HTTP或者HTTPS协议的,只要是这种数据,都可以使用爬虫抓取。
2.3.3 JavaScipt渲染页面
有时通过urllib或者requests库进行抓取时,得到的源代码和在浏览器中看到的不一样。
这是因为网站使用了JavaScript进行渲染,这样的使用在现在的网站中越来越多。
使用这种技术的网站,它的HTML代码就是一个空壳。
例如在HTML中引入一个app.js文件,浏览器在加载这个HTML内容时,会去请求这个文件,获取到该文件后,就会执行其中的JavaScript代码,它会改变HTML中的节点,向其添加内容,得到完整的页面。
在使用urllib或者requests等库请求时,只能得到这个HTML代码,而无法加载这个JavaScript文件,就无法得到完整的源代码。
对于这样的页面,可以分析其后台Ajax接口,也可以使用Selenim,Splash来模拟JavaScript渲染。
2.4 会话和Cookies
2.4.1 静态网页和动态网页
将一段基本的HTML代码,将其保存为.html文件,放到某台具有公网IP的主机上,在主机上装上Apache等服务器,就可以把这台主机当服务器使用,其他人也可以访问这台服务器,这就是一个简单的网站。
这种网页的内容是由HTML代码编写,文字和代码都由HTML代码指定,这就是静态网页。它加载速度快,编写简单,但可维护性差,也不能根据URL灵活多变地显示内容。
而动态网页,它可以动态解析URL中参数的变化,关联数据库并动态呈现页面内容,非常的灵活多变,不止由HTML构成,还有HJP,PHP,Python等语言参与编写,其功能比静态网页丰富太多。
2.4.2 无状态HTTP
HTTP还有一个特点,无状态,指HTTP协议对于事物处理是没有记忆能力的。我们向服务器发送请求后,服务器解析此请求,然后返回对应响应,服务器负责完成这个过程,而如果还需要处理前面到信息,就需要重新请求,重复这个过程。这样太浪费资源了。
而会话和Cookies就是用来保持HTTP连接的技术。
会话在服务器端,用来保存用户的会话信息;
Cookies在客户端,在浏览器下次访问网页是自动附带上它,服务器通过识别Cooikes来鉴定用户,来判断用户是否是登陆状态,返回对应的响应。
因此在爬虫中,我们可以将登陆成功后获取的Cookies放在请求头中直接请求。
1.会话
在web中,会话对象用来存储特定用户会话所需的属性及配置信息。当用户在程序中的web页面跳转时,对应的变量始终存在于会话对象中。当用户请求来自应用程序的web页面,而没有对应的会话时,web服务器将会自动创建一个会话对象。
当会话对象过期或被放弃后,服务器将终止该对话。
2.Cookies
Cookies指某些网站为了辨别用户身份,进行会话跟踪而存储在用户本地终端上的数据。
-
会话维持
当客户端第一次请求服务器时,服务器会返回一个请求头中带有Set-Cookie字段的响应给客户端,以此标记用户,客户端浏览器会吧Cookies保存起来。当客户端下一次请求该网站时,会把Cookies放到请求头中一起提交给服务器,Cookies携带了会话ID信息,服务器通过此信息即可找到对应对应会话,以此来判断用户状态。
如果Cookies是无效的,或者会话过期了,将无法直接访问。
因此,Cookies和会话是配合使用的,一个处于客户端,一个处于服务器端,二者共同协作,实现了登陆会话控制。 -
属性结构
Cookies中有很多条目,其中每个条目都可以成为Cookie,它有以下属性: -
Name:该Cookie的名称。一旦创建,名称不可更改。
-
Value:该Cookie的值。如果为Unicode字符,需为字符编码。如果为二进制数据,则需要使用BASE64编码。
-
Domain:可以访问该Cookies的域名。如果设置为
.baidu.com
,则所有以baidu.com
结尾的域名都可以访问。 -
Max Age:该Cookie失效的时间,单位为秒。如果为正数,则该Cookie在Max Age秒后失效。如果为负数,则关闭浏览器时Cookies即失效,浏览器也不会以任何形式保存该Cookie。
-
Path:该Cookies的使用路径。如果设置为/path/,则只有路径为/path/的页面可以访问该Cookie。如果设置为/,则本域名下所有页面都可以访问该Cookie。
-
Size:此Cookie的大小。
-
HTTP字段:Cookie的httponly属性。若此属性为true,则只有在HTTP头中会带有此Cookies的信息,而不能从过document.cookie来访问此Cookie。
-
Secure:该Cookie是否仅被使用安全协议传输。安全协议有HTTOS和SSL等,在网络上传输数据之前先将数据加密。默认为false。
-
会话Cookie和持久Cookie
会话Cookie就是把Cookie放在浏览器内存中,浏览器关闭后该Cookie即失效。
持久Cookie就是把Cookie保存到客户端的硬盘中,下次还可以继续使用,用于长久的保持用户登陆状态。
2.4.3 会话的生命周期
当我们关闭浏览器,在浏览器内存中存储的Cookies随之消失,再此连接服务器时,也无法找到原来的会话。
在硬盘上存储的Cookies并不会消失,再次连接服务器时,任然能找到原来的会话,验证其登陆状态。
而无论服务器是否关闭,都不会导致会话的删除。除非程序通知服务器删除会话,否则会话会一直被保留。
这就需要服务器为会话设置一个失效时间,超过了失效时间,服务器才会删除会话以节省空间。
2.5 代理的基本原理
在做爬虫时,往往会遇到这种情况,最初爬虫正常运行,正常抓取数据,然而很快就会出现错误,打开网页时,可能就会提示“您的IP访问频率太高”。
这是因为,一些网站使用了一些反爬虫机制。比如,服务器会检测某个IP在单位时间内的请求次数,超过这个阈值,就会拒绝服务,甚至完全拒绝一段时间这个IP的请求,这就是封IP。
代理防止封IP的方式。
2.5.1 基本原理
代理就是代理服务器,它的功能是代理网络用户去取得网络信息。
在正常的交流中,客户端向web服务器发送请求,web客户端向客户端返回响应。
客户端(请求)->服务器,服务器(响应)->客户端。
代理服务器就是在客户端和服务器间加了一个中转站,此时进行交流时,就是
客户端(请求)->代理服务器->服务器,服务器(响应)->代理服务器->客户端。
在这个过程中web服务器识别的真实IP就不是本机的IP了,从而实现了IP伪装。
2.5.2 代理的作用
代理的作用可以简单列举如下:
- 突破自身IP限制,访问一些平时不能访问的站点。
- 访问一些单位或团体的内部资源。
- 提高访问速度:通常代理服务器都会设置一个较大的硬盘缓冲区,会保存外界通过的信息,其他用户访问相同信息时可以直接获取。
- 隐藏真实IP:通过代理隐藏自己IP,免受攻击。对于爬虫来说,使用代理可以隐藏自身IP,防止自身IP被封锁。
2.5.3 爬虫代理
当使用爬虫过程中遇到IP访问过快时,网站就会让我们输入验证码登陆或者直接封锁IP,通过代理,不断的更换IP,就可以欺骗服务器,达成我们的爬虫目的。
2.5.4 代理分类
1.根据协议区分
根据代理的协议,代理可以分为如下:
- FTP服务器:主要用于访问FTP服务器,一般有个,下载及缓存功能,端口一般为21,2121等。
- HTTP代理服务器:主要用于访问网页,一般有内容过滤和缓存功能,端口一般为80,8080,3128等。
- SSL/TLS代理:主要用于访问加密网站,一般有SSL或TLS加密功能,端口一般为443。
- RTSP代理:主要用于访问Real流媒服务器,一般有缓存功能,端口一般为554。
- Telent代理:主要用于telent远程控制(黑客入侵计算机时常用于隐藏身份),端口一般为23。
- POP3/SMTP代理:主要用于POP3/SMTP方式收发邮件,一般有缓存功能,端口一般为110/25。
- SCOKS代理:只是单纯传递数据包,不关心具体协议和用法,速度快得多。
2.根据匿名程度区分
根据代理的匿名程度,代理可以分为以下类别:
- 高度匿名代理:会将数据包原封不动的转发,在服务器端看来就好像真的是一个普通客户端在访问,而记录的IP是代理服务器的IP。
- 普通匿名代理:仅仅在数据包上做一些改动,服务器端上可能会发现这是代理服务器,可能会追查到真实IP。
- 透明代理:改动了数据包,还告诉服务器真实IP。仅能使用缓存技术提高浏览速度。
- 间谍代理:指组织或个人创建的用于记录用户传输的数据,进行研究,监控等目的的代理服务器。