快捷搜索:

python爬虫库之:urllib库使用教程(一)

Python3中urllib是一个URL处理包,这个包中集合了一些处理URL的模块,包括了request模块、error模块、parse模块和robotparser模块。

· urllib.request模块是用来打开和读取URL的;

· urllib.error模块包含一些有urllib.request产生 的错误,可以使用try进行捕捉处理;

· urllib.parse模块包含了一些解析URLs的方法;

· urllib.robotparser模块用来解析robots.txt文本文件.它提供了一个单独的RobotFileParser类,通过该类提供的can_fetch()方法测试爬虫是否可以下载一个页面。

在了解爬虫库urllib之前,我们需要先了解下HTTP的一些基本知识,HTTP的请求包含了八种,但我们平时用的比较多的只有3种:GET、POST和HEAD,其中HEAD主要是用在解密百度加密链接。

1

HTTP请求方式

HTTP的请求方法包括如下几种:

GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT

其中常用的请求方式是GET和POST:

GET请求:是以实体的方式得到由请求URL所指定资源的信息,如果请求URL只是一个数据产生过程,那么最终要在响应体中返回的是处理过程的结果所指向的资源,而不是处理过程的描述。一般来说我们输入一个网址时,默认的请求就是GET请求。

POST请求:用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它当作请求队列中请求URL所指定资源的附加新子项。比如网页上的注册、登录等等都是POST请求。

GET与POST方法有以下区别:

在客户端,GET方式通过URL提交数据,数据在URL中可以看到;POST方式的数据放置在实体区内提交,不能直接看到。

GET方式提交的数据最多只能有1024个字节,而POST则没有此限制。

安全性问题,使用GET的时候,参数会显示在地址栏上,而POST不会,所以,如果这些数据是非敏感数据,那么使用GET;如果用户输入的数据包含敏感数据,那么还是使用POST提交比较靠谱。(其实POST也是不安全的)

如何查看一个网页的请求方式?

用谷歌浏览器打开网页,按住ctrl+shift+i 键,在右边出现的列表项中点击“Network”,刷新网页,就可以看到请求方式:“Request Method: GET”

2

HTTP状态码含义

当浏览者访问一个网页时,浏览器会向网页所在的服务器放出请求。在浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(Response Header)用以响应浏览器的请求。HTTP状态码主要是为了标识此次HTTP请求的运行状态。下面是常见的HTTP状态码:

200 ——请求成功

301 —— 资源(网页等)被永久转移到其他URL(永久重定向)

302 ——资源(网页等)被临时转移到其他的URL(临时重定向)

304 —— 资源(网页)没有更新

403 —— 表示资源不可用。服务器理解客户的请求,但拒绝处理它,通常由于服务器上文件或目录的权限设置导致的WEB访问错误。

404 ——请求的资源(网页等)不存在

500 —— 服务器内部错误,主要是由于IWAM账号的密码错误造成的

503 —— 由于临时的服务器维护或者过载,服务器当前无法处理请求

3

HTTP头部信息

HTTP头部信息由众多的头域组成,每个头域又一个域名、冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空白符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。

Request Header:在请求头中可能包含以下内容:

GET代表的是请求方式

Host头域,用于指定请求资源的intenet主机和端口号,必须表示请求URL的原始服务器或网关的位置。

User-Agent头域,里面包含发出请求的用户信息,其中有使用浏览器的型号,版本和操作系统的信息。这个头域经常用来作为反爬虫的措施。

Accept请求报头域,用于指定客户端接收哪些类型的信息。

Accept-Language请求报头域,类似Accept,但是它用于指定一种自然语言。

Accept-Encoding请求报头域,用于指定客户端可接受的内容编码。

Connection报头域允许发送用于指定连接的选项。

Response Header:响应头中可能包含以下内容:

Date表示消息产生的日期和时间

Content-Type 实体报头域用于指明发送给接收者的实体正文的媒体类型。Transfer-Encoding:chunked表示输出的内容长度不能确定

Connection报头域允许发送用于指定连接的选项。

Cache-Contorl用于指定缓存指定,缓存指令是单向的,且是独立的。

Expires实体报头域给出响应过期日期和时间。(用来查看缓存过期时间)

Last-Modified实体报头域用于指示资源的最后修改日期和时间。

4

urllib的request类

该方法打开一个url链接,url可以是一个字符串对象或者是一个Request对象(使用urllib.request.Request类创建的对象),如果url字符串是无效的url:

url中没有冒号那么就会报ValueError异常

url中有冒号但是是不正确的url格式,则报URLError异常

data参数是要发送给服务器的数据,一般就是表单数据(比如登录注册的表单信息),在python中表现为字典的方式,因此我们一般用字典来创建表单。如果该参数不填或是None那么默认请求方式就是GET请求,如果给了data参数,那么请求方式就会变为POST请求。但是data数据必须是application/x-www-form-urlencoded格式的。

timeout参数是请求超时参数,单位是秒。其它参数基本用不到,就不需要了解了。

geturl() 返回资源所在的url

info() 返回响应头信息

getcode() 返回响应状态码

当请求错误的时候会引发URLError异常,因此可以通过捕获这个异常来判断是否请求成功。

这里需要说明的是,基本上所有的网页爬虫代码都需要在开始的地方对header参数进行赋值,就是模拟真实用户的客户端发送给网页服务器的请求头信息。否则以真实的爬虫身份去抓取网页的话,某些设置了反爬机制的网站就会限制爬虫访问,而我们的运行程序就会报错:“http.client.RemoteDisconnected: Remote end closed connection without response”截图如下:

这个时候我们就需要先用urllib.request.Request()方法来设置header参数,设置后就可以正常访问了:

2. urllib.request.Request(url[, data][, headers][, origin_req_host][, unverifiable])

这个是urllib的一个抽象类,用于构造一个http请求对象实例。

url参数必需是一个有效的url字符串

data参数跟urlopen方法的data参数是一样的,也是用于POST请求发送表单数据的字典。

header参数就是发送给网页服务器的请求头信息,也是用字典来创建的请求报头,但是不需要转换,直接赋值即可。

origin_req_host 参数填的是请求网页的host或者是ip,一般不需要用到。

unverifiable 参数设置网页是否需要验证,默认是False,这个参数一般也不用设置。

request类Request方法常用的内置方法

Request.add_data(data) 设置data参数,如果一开始创建的时候没有给data参数,那么可以使用该方法追加data 参数

Request.get_method() 返回HTTP请求方法,一般返回GET或是POST

Request.has_data() 查看是否设置了data参数

Request.get_data() 获取data参数的数据

Request.add_header(key, val) 添加头部信息,key为头域名,val为域值

Request.get_full_url() 获取请求的完整url

Request.get_host() 返回请求url的host(主域名)

Request.set_proxy(host, type) 设置代理,第一个参数是代理ip和端口,第二个参数是代理类型(http/https)

5

urllib内置异常库:urllib.error

1.urllib.error.URLError

所有urllib请求的异常基类,所有请求过程中的异常都可以通过这个异常捕获到,可以通过reason属性来查看发生异常的原因

try:

req = urllib.request.urlopen('https://www.baidu.com/')

except urllib.error.URLError as err:

print(err.reason)

2.urllib.error.HTTPError

捕获请求过程中的HTTP错误异常,这个异常是URLError的子类。该异常类有两个属性:

code属性得到异常发生的http状态码,可以通过该属性知道引发http请求错误的是哪个状态码

reason 引发异常的原因

一般用法,因为HTTPError是URLError的子类,因此可以通过捕获URLError来捕获所有的异常,然后再通过判断异常是否有code属性来判断是否是HTTPError异常,然后再做处理。

了解了HTTP和urllib库的一些基本语法后,我们就可以开始网页爬虫之路了。下次的教程中,东尧将以“糗事百科”网站为例,教大家如何运用urllib库的方法来抓取网站上的段子、评论、数量等等数据,并将抓取结果保存到文件中。

您可能还会对下面的文章感兴趣: