爬虫

爬虫基础

爬虫就是获取网页并提取和保存信息的自动化程序。

Cookies里面保存了登录的凭证,有了它,只需在下次请求携带Cookies发送请求而不必重新输入用户名和密码。因此在爬虫中,有时候需要登录才能访问页面时,我们一般会直接将登录成功后截取的Cookies放在请求头里面直接请求,而不必重新模拟登录。

请求头

Accept:请求报文域,用于指定客户端可接受哪些类型的信息。

Accept-Language:指定客户端可接受的语言类型。

Accept-Encoding:指定客户端可接受的内容编码。

Host:用于指定请求资源的主机IP和端口号,其内容为请求URL的原始服务器或网关的位置。从HTTP1.1版本开始,请求必须包含此内容。

Cookie:也常用复数形式Cookies,这是网站为了辨别用户进行会话跟踪而存储在用户本地的数据。它的主要功能是维持当前会话。如:我们输入用户名和密码成功登陆到某个网站后,服务器会用会话保存登录状态信息,后面我们每次刷新或请求该站点的其他页面时,会发现都是登陆状态,这就是Cookies的功劳。Cookies里面有信息标识了我们所对应的服务器的会话,每次浏览器在请求该站点的页面时,都会在请求头中加上Cookies并将其发送给服务器,服务器通过Cookies识别出是我们自己,并且查出当前状态是登录状态,所以返回的是登陆后才能看到的网页内容。

Referer:此内容用来标识这个请求是从哪个页面发过来的,服务器可以拿到这一信息并作相应的处理,如来源统计,防盗链处理等。

User-Agent:简称UA,它是一个特殊的字符串头,可以是服务器识别客户使用的操作系统和版本,浏览器及版本等信息。在做爬虫的时候加上此信息可以伪装为浏览器;如果不加,很可能会被识别为爬虫。

Content-Type:也叫互联网媒体类型或者MIME类型,在HTTP协议消息头中,它用来表示具体请求中的媒体类型信息。如:text/html表示HTML格式,image/gif表示GIF图片,application/json表示JSON类型。

Content-Type 提交数据的方式
application/x-www-form-urlencoded 表单数据
multipart/form-data 表单文件上传
application/data 序列化JSON数据
text/xml XML数据

在爬虫中,若要构造POST请求,需要使用正确的Content-Type,并了解各种请求库的各个参数设置时使用的是哪种Content-Type,不然可能导致POST提交后无法正常响应。

请求头是请求的重要组成部分,再写爬虫时大部分情况下都需要设定请求头。

请求主体

请求体一般承载的内容是POST请求中的表单数据,而对于GET请求,请求体则为空。

响应三部分:响应状态码,响应头,响应体。

响应头

Date:标识响应产生的时间。

Last-Modified:指定资源的最后修改时间。

Content-Encoding:指定响应内容的编码。

Server:包含服务器的信息,比如名称和版本号等。

Content-Type:文档类型,指定返回的数据类型是什么,如text/html代表返回的是HTML文档,application/x-javascript则代表返回JavaScript文件,image/jpeg则代表返回图片。

Set-Cookie:设置Cookies,响应头中的Set-Cookie告诉浏览器需要将此内容放在Cookies中,下次请求携带Cookies请求。

Expires:指定响应的过期时间,可以使代理服务器或浏览器将加载的内容更新到缓存中。如果再次访问时,就可以直接从缓存中加载,降低服务器负载,缩短加载时间。

响应体

响应的正文数据都在响应体中,比如请求网页时,它的响应体就是网页的 HTML代码;请求一张图片时,它的响应体就是图片的二进制数据。我们做爬虫请求网页后,要解析的内容就是响应体。

会话

在Web中,会话对象用来存储特定用户会话所需的属性及配置信息,这样,当用户在应用程序的Web页之间跳转时,存储在会话对象中的变量将不会丢失,而是在整个用户会话中一直村下去。当用户请求来自应用程序的Web页时,如果该用户还没有会话,则Web服务器将自动创建一个会话对象。当会话过期或放弃后,服务器将终止该会话。

会话维持

当客户端第一次请求服务器时,服务器会返回一个请求头中带有Set-Cookie字段的响应给客户端,用来标记是哪一个用户,客户端浏览器就会把此Cookies放到请求头一起提交给服务器,Cookies携带了会话ID信息,服务器检查该Cookies即可找到对应的会话是什么,然后再判断会话来以此来辨认用户状态。

在成功登录某个网站时,服务器就会告诉客户端设置哪些Cookies信息,在后续访问页面时客户端会把Cookies发送给服务器,服务器再找到对应的会话加以判断。如果会话中某些设置登录状态的变量是有效的,那就证明用户处于登录状态,此时返回登陆之后才可以查看的网页内容,浏览器解析便可以看到了。

反之,如果传给服务器的Cookies是无效的,或者会话已经过期了,我们将不能继续访问页面,此时可能会收到错误的响应或者跳转到登录页面重新登陆。

所以,Cookies和会话需要配合,一个处于客户端,一个处于服务端,两者共同协作就实现会话控制。

会话Cookie与持久Cookie

从表面意思来说,会话Cookie就是把Cookie放在浏览器内存中,浏览器在关闭之后该Cookie即失效;持久Cookie则会保存到客户端的硬盘中,方便下一次使用,用于长久保持用户登录状态。

因此一些持久化登陆的网站其实就是把Cookie的有效时间和会话有效期设置得较长,下次我们再访问页面时仍然携带之前的Cookie,就可以直接保持登录状态。

会话误区

在谈论会话机制时,人们认为“只要关闭浏览器,会话就会消失”。可以想象一下会员卡的例子除非顾客主动对店家提出销卡,否则店家绝不会轻易删除顾客的资料。对会话来说,也是一样,除非程序通知服务器删除一个会话,否则服务器会一直保留。比如,程序一般都是在我们做注销操作时才去删除会话。

但是当我们关闭浏览器时,浏览器不会主动在关闭之前通知服务器他将关闭,所以服务器根本不会有机会知道浏览器已经关闭。之所以会有这种错觉是因为大部分会话机制都使用会话Cookie来保存会话ID信息,而关闭浏览器后Cookies就消失了,再次连接服务器时,也就无法找到原来的会话了。如果服务器设置的Cookies保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的Cookies发送给服务器,则再次打开浏览器能找到原来的会话ID,依旧还是可以保持登录状态的。

而恰恰是由于关闭浏览器不会导致会话被删除,这就需要服务器为会话设置一个失效的时间,当距离客户端上一次使用会话的时间时,服务器就可以认为客户端已经停止了活动,才会把会话删除以节省存储空间。

代理

代理的基本原理

我们在做爬虫时经常会遇到这种情况,最初爬虫正常运行,但过一会就报403Forbidden错误,可能会看到“您的IP访问频率太高”这样的提示,原因是网站采取了反爬虫措施。比如,服务器会检测某个IP在单位时间内的请求次数,如果超过了这个阈值就会直接拒绝服务,返回一些错误信息,这种情况称为封IP。这时就可以采用代理来实现IP伪装。

代理实际是代理服务器,proxy server,功能是代理网络用户去取得网络信息,形象地说是网络信息的中转站,在我们正常请求一个网站时,是发送了请求给Web服务器,WEb服务器把响应传回给我们。如果设置了代理服务器,实际上就是在本机和服务器之间架一座桥,此时本机不是直接向Web服务器发起请求,而是向代理服务器发起请求,请求会发送给代理服务器,然后由代理服务器再发送给Web服务器,接着由代理服务器再把Web服务器返回的响应转发给本机,这样就可正常访问网页了,但这个过程中Web服务器识别出的真实IP就不再是我们本机的IP了,就成功实现了IP伪装,这就是代理的原理。

使用代理隐藏真实的IP,让服务器误以为是代理服务器在请求自己,这样在爬取过程中不断更换代理就不会被封锁,可达到很好的效果

代理作用:
  1. 突破自身限制,访问一些平时不能访问的站点。

  2. 访问一些单位或团体内部资源:比如使用教育网内地址段访问免费代理服务器,就可以实现对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。

  3. 提高访问速度:通常代理服务器都设置了一个较大的硬盘缓存区,当有外界的信息通过时,同时也将其保存到缓存区中,当其他用户再访问相同的信息时,则直接由缓存区中取出信息,传给用户,以提高访问速度。

  4. 隐藏真实的IP:上网者也可以通过这种方法隐藏自己的IP免受攻击。对于爬虫来说,我们用代理就是为了隐藏自身IP,防止自身的IP被封锁。

代理分类
  1. 根据协议区分:

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

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

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

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

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

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

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

  2. 根据匿名程度区分

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

    普通匿名代理: 会在数据包上做一些改动 服务端上有可能发现这是个代理服务器,也有一定几率追查到客户端的真实 代理服务器通常会加入的 Hπ?头有 HTTP VIA HTTP X FOR DED FOR

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

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

基本库

使用urllib

urllib库是Python内置的HTTP请求库,不需安装即可使用。包含4个模块:

  1. request:它是最基本的 HTTP 请求模块,可以用来模拟发送请求 就像在浏览器里输入网址然后回车一样,只需要给库方法传入 RL 及额外的 数,就可以模拟实现这个过程了
  2. error 异常处理模块,如果出现请求错误 可以捕获这些异常,然后进行重试或作以保证程序不会意外终止
  3. parse 个工具模块,提供了许多 URL 处理方法,比如拆分、解析 合并
  4. robot parser :主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,它其实用得 较少。
发送请求

使用urllib的request模块方便实现请求的发送并得到响应。利用它可模拟浏览器的一个请求发起过程,同时他还带有处理授权验证(authentication),重定向(redirection),浏览器的Cookies以及其他内容。

1
2
3
import urllib.request
response = urllib.request.urlopen('https://www.python.org')
print(response);
  1. 利用最基本的urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault-False,context=None)方法,可以完成最基本的简单网页的GET请求抓取。

  2. 1
    class urllib.request.Request(url,data=None,headers={},origin_req_host=None,unveriable,method=Node)

    url为必传参数,data要传时必须传bytes(字节流)类型,若为字典,可用urllib.parse模块的urlencode()编码。

    headers是一个字典,它是一个请求头,我们可以在构造函数请求时通过headers参数直接构造,也可以通过调用请求实例的add_header()方法添加。添加请求头最常用的方法就是通过修改User-Agent来伪装浏览器,默认的User-Agent是Python-urllib,我们可以通过修改它来伪装浏览器。比如伪装成火狐浏览器,可将它设置为:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0

    origin_req_host指的是请求方的host名称或者IP地址。

    unverifiable表示这个请求是否是无法通过验证的,默认是False,意思是说用户没有足够的权限来选择接受这个请求的结果。如:我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,这是unverifiable的值就是true。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from urllib import request,parse
    url = 'http://httpbin.org/post'
    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0',
    'Host': 'httpbin.org'
    }
    dict = {
    'name': 'Germy'
    }
    data = bytes(parse.urlencode(dict),encoding='utf8')
    req = request.Request(url=url,data=data,headers=headers,method='POST')
    response = request.urlopen(req)
    print(response.read().decode('utf8'))
文章目录
  1. 1. 爬虫基础
    1. 1.0.1. 请求头
    2. 1.0.2. 请求主体
    3. 1.0.3. 响应头
    4. 1.0.4. 响应体
    5. 1.0.5. 会话
    6. 1.0.6. 会话Cookie与持久Cookie
    7. 1.0.7. 会话误区
  • 2. 代理
    1. 2.0.1. 代理的基本原理
    2. 2.0.2. 代理作用:
    3. 2.0.3. 代理分类
  • 3. 基本库
    1. 3.0.1. 使用urllib
    2. 3.0.2. 发送请求
  • |