Part8:HTTP协议及Requests库方法:
为了更好的了解和理解这样的一些方法,我们更应该理解HTTP协议。
什么是HTTP协议:
URL的合适是http://后面加三个域:
实例:
HTTP URL的理解:
HTTP协议对资源的操作:
GET方法我们可以通过GET能够把网上URL位置的资源拿下来。
HEAD方法:获取URL资源的头部信息。比如说当我们发现资源很大,我们不可能把资源完全拿下来或者说拿下来的代价很大时可以请求head获得头部信息,并且分析这个资源大概得内容。
POST方法:请求向URL位置的资源后附加新的数据。这个时候它不改变URL位置现有的资源的内容,只是在它的后面新增用户所提交的资源。
PUT方法:指的是向URL存取一个资源,也就是我们将我们自己的data放到这个URL的位置上。而用PUT方法时,URL原来的资源将会被覆盖掉。
PATCH方法是指向URL的位置资源进行局部更新。比如说我们想把URL位置资源中的某些元某些数据修改掉,我们就用PATCH。
DELETE方法:指删掉URL位置存储的相关资源。
我们可以把互联网或Intenet当做一个云端,那么云端是存储的所有资源,它实际上只是一个使用URL来做相关的描述,也叫标识。如果我们想获取这个资源的时候,我们可以用GET或HEAD方法。GET方法获得全部资源,HEAD方法获得资源的头部信息。如果我们想把自己的资源放到这个URL对应的位置上,我们可以使用PUT POST PATCH方法。如果我们想删掉这个URL对应的现有资源,我们可以用DELETE。
事实上,HTTP协议通过URL对资源做定位,通过这6个常用的方法对资源进行管理,每一次操作都是独立无状态的,就是这个操作和下一次操作没有关系。在HTTP协议的世界里,网络通道和服务器都是黑盒子,它能看到的就是URL链接以及对URL链接的相关操作。
那么在这6个方法中,我们重点理解PATCH 和PUT的区别。我们举一个例子,比如说在URL的位置上有一组数据,这个数据叫UserInfo(表示的是用户信息)。那它包含了好多字段,比如包括UserID、UserName等20个字段。
现在的需求是:用户只修改了UserName,其他并没有改变。我们想把这样的信息更新到服务器上,这里可以采用PATCH方法,使用PATCH方法时,我们只需要使用HTTP协议向URL重新提交UserName就行了。
如果不用PATCH方法,我们也可以用PUT方法,我们知道PUT方法会覆盖URL所对应的资源,所以为了不覆盖掉这个资源,我们必须将UserInfo所对应的20个字段同时再次的提交到URL对应的位置上,包括你更新的UserName。如果恰巧你没有提交其他字段,只提交了UserName,那么这个URl对应的位置上就只剩UserName的信息了。
比较PATCH和PUT我们发现PATCH的最大好处就是节省网络带宽。当URL资源对应很庞大的资源的时候我们只需要改其中一个,那我们就用PATCH来去修改那一个,而不要用PUT去重新提交那么多的资源。
所以PATCH也是HTTP协议改良后的一个新增指令。
HTTP协议与Request库的方法与功能是一一对应的:
这里面我们以下的几个方法:
我们用head()方法去访问一个链接,我们用r.headers来展现反馈的头部信息的内容。当我试图展示全部内容用r.text的时候,发现内容是空的。所以用head()方法很少的网络流量获取网络资源的概要信息。
post()方法:
我们可以用post方法向服务器提交新增数据,比如这里我们首先建立一个字典叫payload,它里面包含两个键值对,key1:value1和key2:value2。然后我们用post()方法去提交这样的一个字典,我们看一下返回的内容r.text。我们发现key1:value1和key2:value2被放到了from的字段下,这说明当我们向URL去post一个字典或者post键值对的时候,那么键值对会默认的被存储到表单的字段下。
那么我们不提交键值对呢?比我我们提交的就是一个字符串ABC,那我们可以发现ABC被存到了data的相关字段下,这是post方法根据客户提交内容的不同,在服务器上会做相关的整理。
put()方法也一样:
与post方法类似,只不过它能够将原有的数据覆盖掉。
Part9:4 Requests库主要方法解析
我们反复强调Requests库的7个主要方法,那么我们下面一个一个地看一下这些方法的主要功能。
requests库的request()方法是所有方法的基础方法。那么它有3个参数method、URL、和控制访问参数。
我们一一来看一下:
request()的7种请求方式分别为:GET HEAD POST PUT PATCH DELRTE OPTIONS
事实上,前六种我们都接触过,OPTIONS事实上是服务器获取一些服务器跟客户端能够打交道的参数。这里面并不与获取的资源直接相关,因此我们平时使用中用的比较少。
那么在这7种方式中,如果我们选定了一种我们可以用request直接实现,我可以用request库的对应方法,比如说requests.GET、requests.HEAD、requests.POST来实现。而那样的方法是基于request的这个函数之上封装起来的。
URL我们都知道是链接,我们就不多说了。那么requset这13个访问控制参数分别是什么呢?我们一一介绍一下。
第一个参数叫params,是指能够增加到URL中的参数,怎么理解呢?我们看一个例子:
首先我们建立一个字典,里面有两个键值对,然后我们用GET方法向某一个链接请求同时提供了这个字典作为params相关参数,由于访问控制参数用**开头的,也就是说它是可选的。那我们对这样的13个字段中任何一个使用时需要用命名方法来调用它的参数,也就是说我们用params=它的值kv的方式来调用它。这时我们再去打印r.url链接发现在我们给定的url中,它的后面多了一个问号,问号里面有key1:value1和key2:value2.也就是说通过这样一个参数可以把一些键值对增加到url中,使得url再去访问时,不只访问是这个资源,而同时带入一些参数,那服务器可以接受这些参数并根据这些参数筛选出部分资源返回回来。后面我们会有例子重点介绍这个参数的使用。
data是第二个控制参数,它是字典、字节序或文件对象。它是重点作为向服务器提交或提供资源时使用,这里边我们举两个例子:
我们构建一个键值对,然后我们用POST的方法,把它当做data的一部分去提交,这个时候我们所提交的键值对并不放在url链接里而是放在url对应位置的地方作为数据来储存。我们当然也可以向data域赋值一个字符串,那么这个字符串就可以存到前面url链接所对应的位置。
第三个控制参数叫json.看到名字就能想到它是json格式的数据,json格式在HTTP HTML相关的web开发中用到的非常常见,也是HTTP协议最经常使用的格式。它也是作为内容部分可以向服务器提交,比如我们用字典构造一个键值对,然后我们可以把它赋值给json参数,那么这个键值对就赋值到服务器的json上。
第四个控制参数是headers:
headers实际上是HTTP协议头的相关域,他对应了向某个url访问时所发起的HTTP的头字段。简单说我们可以用这个字段来定制访问某一个url的HTTP的协议头。
举个例子:我们可以定一个字典,我们去修改HTTP协议中user-agent的字段,我们把user-agent变为Chrome/10。那么在访问某个链接时,我们可以把这样的字段赋值给headers,此时headers再去向服务器访问时,服务器看到的user-agent的字段就是Chrome/10,Chrome/10是指Chrome浏览器的第十个版本,比如说我们可以模拟任何我们想模拟的浏览器向服务器发起访问。而这种模拟浏览器的方法就是在headers字段中来实现。后面我们有例子来介绍这个字段的具体使用。
第五个参数是cookies,指的是从HTTP协议中解析cookie,那么它可以是字典或CookieJar的形式。
第六个参数是auth字段,它是一个元组类型,它是支持HTTP协议认证功能。
那么Cookie和anth字段都是Requests库的高级功能。
第七个参数files字段,是字典类型,顾名思义它是向服务器传输文件时使用的字段。我们可以定义一个字典,用file以对应的文件为键值对,用open的方式打开这个文件,并把这个文件与file做一个关联,同时对应到相关的url上。这样的方法我们可以向某一个链接提交某一个文件,这个在特定应用时还是很有用的。
第八个参数是timeout参数是指设定的超时时间,以秒为单位。当我们发起一个GET请求时,我们可以设置一个timeout时间,如果在timeout时间内我们的请求内容没有返回回来,那么它将产生timeout一个异常。
第九个参数是proxies字段,它是个字典类型,可以为我们爬取网页设定访问代理服务器,可以增加登录认证。
在这里面我们可以增加两个代理,一个是HTTP访问时使用的代理,而在这代理中我们可以增加用户名和密码的设置。我们再增加一个HTTPS的代理服务器,那么在我们访问百度时,我们所使用的IP地址就是代理服务器的IP地址,使用这个字段可以有效地隐藏用户爬取网页的源的IP地址信息,能够有效地防止对爬虫的逆追踪。
第十个参数是allow_redirects,这个字段是一个开关,表示允不允许对url做重定向。
第十一个参数stream字段也是一个开关,指对获取的内容是否进行立即下载。默认情况是立即下载。
第十二个参数是verify字段,是一个认证SSL证书的字段。
第十三个参数是cert字段,是保存本地SSL证书路径的字段。那么这四个字段分别对应的都是一些高级功能,我们在这里先不去详细介绍。
request函数一共包含13种访问控制参数,这些参数都是可选项,我们再看一遍。
除了requests的函数之外,还有其他的6个函数。
那么GET函数,GET方法获得某一个url链接的相关资源,这里面的params参数就是request里面的那个对应的参数。我们就不额外介绍了。
这里面的12个控制访问参数就是requsts方法中除了params之外的十二个访问参数,完全是一样的,所以我们也不介绍了。
requests.head字段除了url外它的访问控制参数一共有十三个。与requests完全一样。
requests.post函数有四个基本的参数:
requests.put:
requests.patch:
requests.delete:
为什么这么设计呢?事实上在使用后六个方法的时候,由于这这些方法会常用到某一些访问控制参数,所以他就把这些参数作为一个显示定义的参数量放到了函数的设计里面。而那些不是特别常用的都放到了访问控制可选的参数字段里面。
requests.get方法是所有方法中最常用的方法。为什么这么说呢?因为在HTTP协议中,向某一个url去提交资源的功能,在服务器上是严格受控的,这里面有很大的安全问题,如果某一个url是允许任何用户无限制地向上传输相关资源的,那么就会出现很多问题。比如说我们可以用大量的垃圾信息去使得服务器的资源消耗完,甚至我们可以传输一些不可控的或者恶意的内容到某一个url上,这都是对网络空间不负责任的表现。因此在我们使用requests库的时候,最常使用的是get方法,也就是说我们用get方法来爬取一些内容,并且部分地向服务器提交一些内容。
Part10:内容小结。
requests库只有7个对外使用的方法,分别如下
而事实情况是,由于网络安全的限制,我们很难向一个url去发起post put patch 和delete的请求。而requests库的方法又是一个基础方法。因此真正使用requests库,如果我们作为爬虫工具来说,最常使用的是get方法。
对于某些特别大的url链接,我们使用head方法来获得它的资源概要。因此对于requests库来讲,我们重点掌握get和head就可以了。
那么作为入门级的过去网页的功能,我们需要掌握一个爬取网页的一个通用代码框架。如下图
大家一定要记住,网络连接有风险,异常处理很重要。所以一定要用try except的方式来保证网络连接的异常被有效地处理。
r.raise_for_status ()是最核心的代码。也就是respons对象的raise_for_status函数。
Part11:网络爬虫引发的问题
按尺寸来划分,有三大类
第一类:爬取网页
规模小,数据量也小,
第二类:爬取网站,
比如我们要爬取携程网的内容,如果速度不快,可可能还赶不上携程自己数据更新的速度,那就不行了。所以我们要使用更专业的库Scrapy。
第三类:爬取全网。规模很大,但是只有一个作用就是建立全Internet搜索引擎。比如谷歌百度这样的提供搜索引擎功能的公司背后都有一个能够爬取全Internet所有资源的爬虫。它的爬取速度是非常关键的。这样的爬虫只有定制开发,不可能有第三方库提供相关的应用。
小规模的爬虫占去百分之九十的爬虫。
对于网络爬虫有很多不同的声音。这位网络爬虫会带来很多的问题,对于一个服务器来说,比如我运行了一个网站,那么网络爬虫就像骚扰电话一样对这个网站带来很致命的骚扰功能。因为我们架一个web服务器,它默认只接受人类的访问。而爬虫跟人类所不同的是它能够用计算机的快速功能来去获取相关的资源,甚至它爬取的速度要比人类要快到百倍甚至千倍。按照服务器来讲,它是默认按照人数来约定它的访问能力,但是如果有服务器来爬取相关的内容,甚至一秒钟可以爬取十万次甚至几十万次的情况下,服务器是很难一下提供那么高的性能的。因此对于某些爬虫受限于编写者的水平和目的,那么这样的爬虫会为web服务器带来巨大的资源开销。从而对网站的运行者来讲,爬虫形成了骚扰。
除了骚扰功能外,网络爬虫还会带来一定的法律风险。由于服务器上的数据是有产权归属的,比如说新浪上提供的新闻数据归新浪公司所有。如果在微博上我提供的微博数据是归用户和微博公司共同所有。而网络爬虫获得数据后,将这些数据进行牟利的话,将会带来法律风险。事实上,我们在世界范围内也看到了这样的案例,有相关的法院判处爬虫赔偿服务器网站巨额费用的这样的一个实际的案例。
此外网络爬虫还会给个人带来很大的隐私泄露的风险。举个例子,我可以在网站上放很多个人的照片,我可能通过简单的密码或者简单的目录保护方式来防止被人类通过浏览的方式获得。但是对于网络爬虫来讲,他可以具备一定的突破能力,能够破解一定的访问控制甚至能够对那些外部很难找到的链接来进行爬取,从而获得相关的数据,而获得的数据又是个人隐私的数据,那么就能把你的隐私泄露出去。
综上,我们将网络爬虫引发的问题最为突出的三个是:1.服务器性能骚扰问题 2.内容层面的法律风险 3.个人隐私泄露问题。因此我们说网络爬虫的使用时要有他的规则的。那么在实际的使用中一些较大网站都对网络爬虫有相关的限制,而整个Internet上也将网络爬虫作为一个可规范的功能来看待。
那对于一般的服务器来讲,我们可以用两种方式来限制网络爬虫,如果服务器的所有者,网站的所有者他有一定的技术能力,他可以通过来源审查来限制网络爬虫。来源审查方法比较简单,他首先判断所有请求的HTTP的头部找到他的user-agent字段,我们知道在进行HTTP访问的时候,无论是浏览器还是访问的软件 ,他都会把自己设定一个标识放到user-agent字段。那么对于网站的服务器来讲他要判断HTTP的协议头,如果user-agent字段不是预定的浏览器,比如说不是IE10不是我们已知的浏览器,那他很有可能就是一个爬虫。所以我们可以通过限制HTTP协议的协议头来限制网络爬虫。
简单说,作为网站的维护者,可以只响应已知的浏览器或友好的网络爬虫,这是来源审查的办法。但是这个办法需要对维护网站人员的技术能力有一定的要求。
另外一种方法就是通过发布通告的方法:也就是所谓的Robots协议。之歌方法有点像告示牌,告知所有爬虫网站爬取的策略,并要求遵守爬虫,告诉你哪些是可以爬取的哪些是不可以爬取的。发布公告形式仅仅是通过发布来体现,至于是否遵守那是由网络爬虫自身来决定。但是通过这两个方法,互联网上形成了对网络爬虫的一个道德和技术的有效限制。
Part12:Robots协议
下面我们来介绍一下Robots协议,Robots是机器人的意思。那Robots协议是什么呢?它实际上是叫Robots Exclusion Standard网络爬排除标准。Robots协议的一个很重要的作用就是网站告知网站哪些页面可以抓取,哪些不行。我们之前讲过说一个网站要想限制网络爬虫,他有两个办法,一个办法是审查来源,一个办法是通过Robots协议来做到告知。那么Robots协议就是这样的一个功能。
他的具体使用是放到网站的根目录下的一个文件,这个文件叫做Robots.txt文件。在这个文件中写明了在一个网站里哪些目录是允许爬虫去爬取的,哪些目录是不允许的。那通过这样的形式你如果写了一个爬虫,你就要尊重网站的维护人员对网站资源的一个管理。
Robots协议很有趣,其实很多的网站甚至全Internet主流的网站都支持Robots协议。我们能看一下京东的Robots协议:
我们来一行一行的看一下,第一个叫User-agent:*,这什么意思呢?它指的是对于任何的网络爬虫来源,它定义为User-agent。也就是说无论对于一个怎样的网络爬虫都应该遵守如下的协议。
第二行叫做Disallow:/?*,表示是不允许,也就是说任何爬虫都不允许访问?*,也就是说以?开头的路径。
再往下看,第三行Disallow:/pop/*.html,也就是说任何网络爬虫都不允许访问pop*.html。
第四行Disallow:/pinpai/*.html?*,就是符合这个通配符的也是不允许任何网络爬虫访问的。
此外,京东的Robots协议又提供了User-agent:Etaospider这样的一个内容,其实不止是Etaospider,后面还有四个网络爬虫,也就是说这四个网络爬虫,我们都看到这四个后面都跟着一句Disallow根目录,指的是这四个网络爬虫不允许爬取京东的任何资源。那么我们可以理解为这四个网络爬虫是一个恶意爬虫 ,被京东发现后认为他们恶意的获取京东的内容,因此拒绝他们对京东的任何数据的访问。
那返回来看什么是Robots协议呢?Robots协议他通过了一个基本语法来告知所有的爬虫它内部的资源能够被访问的权限。那这个语法就是User-agent和Disallow。
User-agent表明的是哪些爬虫,如果我们像代表所有的网络爬虫就用User-agent:*。
Disallow代表的是你不允许这个爬虫访问的资源的目录,那么有了这样的一个基本的协议,你就可以对你整个网站的内容做一个相关的规范,使得所有的网络爬虫知道可以访问哪里,不可以访问哪里。
除了京东的Robots协议,我们可以看看其他的真实的 Robots协议。这里面给出了一些链接,包括百度的Robots协议,新浪新闻的Robots协议,qq的Robots协议,qq新闻的Robots协议和我们国家教育部的Robots协议。这里面要注意Robots协议一定要放在网站的根目录下,但是对于新浪来讲www.xinlang.com.cn和news.xinlang.com.cn他是两个不同的根目录。所以呢,我们去看www.xinlang.com.cn他的Robots协议和news.xinlang.com.cn它的Robots协议是不同的。甚至我们拿到一个sports.xinlang.com.cn也就是体育新闻频道他和新闻频道也是不一样的。
这里面很有趣,并不是所有的网站都有Robots协议。比如说我们国家的教育部的网站,如果你去打开这样一个链接发现它并没有Robots协议,甚至都没有Robots.txt文件。那么Robots协议规定,如果一个网站不提供Robots.txt文件,那就说明这个网站允许所有爬虫无限制的爬取其内容。有空访问一下图中的五个小链接,看一下链接Robots协议的内容,同事理解一下Robots协议在真实环境中使用的具体方法。
Part13:Robots协议的遵守方式
我们看一下Robots协议的使用,对于任何网络爬虫来讲,他应该自动或人工的识别Robots.txt文件,根据文件的内容在进行爬取。如果我们不写这样的一个代码,我们可以打开某一个网站,我们看一下Robots协议,根据他的规则来进行合理的爬取,然而Robots协议是建议但非约束性的,也就是说网络爬虫可以不遵守Robots协议 ,但是可能会存在法律风险。对与Robots协议的使用该怎样理解呢?一般情况下的网络访问一定要遵守Robots协议,但是对于很小的,类似于人类访问的爬虫我们可以不遵守Robots协议:
Part14:内容小结
网络爬虫会带来很多问题,那么针对这些问题互联网设计了Robots协议,Robots协议用基本的简单的语法来约定一个网站的内容,哪些可以被爬取。那么在我们编写网络爬虫的技术范畴内,所有的网络爬虫都应该遵守Robots协议。无论你是自动识别Robots协议还是人工来看Robots协议。如果你的网络爬虫小到跟人类访问网站方式相类似,那也可以不遵守。但是要注意您获取的资源不能进行商业用途。