decode函数的用法_urllib库的用法(上)

阅读提示

理解本文内容需要具备python基础知识爬虫基础知识(HTML、JS)

爬虫基础可参考以往文章:

爬虫基础——HTTP基本原理

爬虫基础——网页基础

爬虫的基本原理

爬虫基础——会话和Cookie

爬虫基础——代理的基本原理

urllib库的作用

在爬虫的基本原理中,我们已经讲过,爬虫的第一个步骤是获取网页,urllib库就是用来实现这个功能:向服务器发送请求,得到服务器响应,获取网页的内容。

Python的强大就在于提供了功能齐全的类库,来帮助我们完成这个请求,通过调用urllib库,我们不需要了解请求的数据结构,HTTP、TCP、IP层的网络传输通信,以及服务器应答原理等等。

我们只需要关心以下三点,然后通过几行调用urllib库的代码,就能够获得我们想要的网页内容。

  • 请求的URL是什么
  • 传递的参数是什么
  • 如何设置可选的请求头

urllib库的构成

在python2中,曾经有urllib和urllib2两个库来实现请求的发送,但目前通用的python3版本中,两个库的功能已经合并成一个库,统一为urllib,它是python内置函数,不需要额外安装即可使用。

urllib的四个模块

466f094410cc7dc04832a0770890948c.png

【1】requsetHTTP请求模块,可以用来模拟发送请求,只需要传入URL及额外参数,就可以模拟浏览器访问网页的过程。

【2】error异常处理模块,检测请求是否报错,捕捉异常错误,进行重试或其他操作,保证程序不会终止。

【3】parse工具模块,提供许多URL处理方法,如拆分、解析、合并等。

【4】robotparser:识别网站的robots.txt文件,判断哪些网站可以爬,哪些网站不可以爬,使用频率较少。

发送请求

1.urlopen( )

urlopen是request模块中的方法,用于抓取网页。

官方文档:(https://docs.python.org/3/library/urllib.request.html)

下面以代码举例,我们抓取百度的网页。

代码示例

import 

df112e73ec97865071959a9724f36c71.png

返回的结果比较多,随便截取其中一部分,可以看出是百度的网页HTML源代码。

a071661dcd7791b1cd65ac37973996e1.png

我们只用几行代码,就完成了百度的抓取,并打印了网页的源代码,接下来,我们看一看我们获得的响应内容response到底是什么?利用type()方法来输出响应的类型

import 

9283ff62c54fa7b386e0ea291748abd0.png

输出结果如下:

35b21f429166bee64417ba2cd1b90fdf.png

它是一个HTTPResponse类型的对象

包含方法:read()、readinto()、getheader()、getheaders()、fileno()等

包含属性:msg、version、status、reason、debuglevel、closed等属性。

通过调用以上的方法和属性,就能返回我们所需的信息。

比如一开始我们打印获取网页内容时,就用到了read()方法。

调用status属性则可以得到返回结果的状态码,200代表强求成功,404代表网页未找到等。

再看一个代码示例加深理解:

import 

0779f57fef2303ca25425c30b3fad8de.png

返回结果:

31f2dd3816ce5956bf059484ca4b9f3b.png

在打印的三行代码中

第一行输出了响应的状态码(200代表正常)

第二行输出了响应的头信息

第三行通过调用getheader()方法并传递参数Server,获取了第二行响应头信息中的Server对应的值BWS/1.1。

参数

利用基本的urlopen()方法可以完成最基本的简单网页GET方法抓取。

如果想达成更复杂一些的任务,需要给链接传递一些参数,该如何实现?

urlopen()的函数原型如下:

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None) 

除了第一个参数传递URL之外,我们还可以传递其参数,比如data(附加数据)、timeout(超时时间)等。

data参数

data用来指明发往服务器请求中的额外的参数信息,data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为POST方式发送请求

data参数是可选的,如果要添加该参数,需要使用bytes()方法将参数转化为二进制数据。

还是通过代码示例理解:

import 

4d3171ecda259936856fefc79c47895e.png

首页这里请求的站点是http://httpbin.org,它是一个HTTP请求测试网站,记住它后面举例会经常用到它。

这次我们要使用post方式请求,而不是get,因为post是需要携带表单信息的(类似登陆的用户名和密码)所以我们要在urlopen函数中传递data参数。

前面讲了data参数必须是bytes型。

bytes()这个方法第一个参数需要str(字符串类型),这里就需要用到urllib库的parse模块里的urlencode()方法来将参数字典转化为字符串。第二个参数是指定编码格式,这里指定为utf-8。

运行结果如下:

4bbb34fe9a7972040e67f11888f351c5.png

可以看到,我们传递的参数data中的字典键值对"word":"hello"出现在了form字段中,这表明了表单提交的方式,以POST方式传输数据。

timeout参数

timeout参数用于设置超时时间,单位为秒,意思是如果请求时间超过了设置的时间,还没有得到响应,就会抛出异常,在实际爬虫中,我们要对许多URL发起请求,中途肯定会出现爬取异常的URL,短时间无法获得响应,我们需要识别出这种异常,就需要用到timeout参数。

如果不指定timeout参数,会使用全局默认时间。它支持HTTP、HTTPS、FTP请求。

通过代码示例理解:

import 

1158d4910f34d31871a499e59a6e8c37.png

这里我们把timeout参数设成0.01秒,网页反应时间是没这么快的,所以一定会报错,我们来看一下报错的信息:

139d3597a691cc2654fad589dafb8ac8.png

直接看结尾红框部分,显示异常属于urllib.error模块,错误原因是超时。

在实际爬虫中,我们可以用过设置这个超时时间来控制一个网页在长时间未响应时,就跳过它的抓取。这可以利用try except 语句来实现。

代码示例:

import 

30a8d25ce593edd3a40f31bf18b4870c.png

在代码中加入try except 语句后,如果响应超时,便会跳过抓取,我们捕获了URLError异常后,接着判断异常是socket.timeout类型(意思就是超时异常),于是打印出了time out !

输出结果如下:

1973be5bf7ba88f1bc1a4348d35e5d14.png

其他参数(少用)

context参数:它必须是ssl.SSLContext类型,用来指定SSL设置,实现SSL加密传输

cafile、capath:分别指定CA证书和它的路径,用于实现可信任的CA证书的HTTP请求。

cadefault:已经弃用,默认False。

2.Requset

上文已经讲解了如何利用urlopen()方法实现最基本的请求发起。但这几个简单的参数并不足以构建一个完整的请求(过于简单的请求会被浏览器识别为爬虫而拒绝响应)。如果请求中需要加入Headers等信息,就需要用到Requset类来构建。

同样通过实例展示Request用法:

import 

13bbae9665d05b8d27c17686276d9f34.png

我们依然是用urlopen()方法来发送请求,只是这次的参数不再是url,而是一个Request类型对象。通过构造这个数据结构,我们可以将请求独立为一个对象,并且更灵活的配置参数。

Request的函数原型如下:

class urllib.request.Request(url,data = None,headers ={ },origin_req_host =None,unverifiable = False,method = None)

下面来看它的具体参数:

url:用于请求URL,这是必传参数,其他都是可选参数。

data:必须是bytes类型,如果它是字典,可以先用urllib.parse模块里的urlencode方法编码。(用于POST请求)

headers:是一个字典,它就是请求头,我们可以在构造请求时,通过headers参数直接构造,也可以通过调用请求示例的add_header()方法添加。

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

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

method:是一个字符串,用来指示请求使用方法,如GET、POST、PUT等。

下面我们给Request传入多个参数构建请求为例进行理解:

import 

34f544f55f150e32cf8d1b6d60d1045a.png

在这个示例中,我们通过4个参数构造了一个请求,我们加入了url、data、headers、method,其中最重要的是把头信息(包含User-Agent和Host)写入了Request,让请求变得更完整。

运行结果如下:

b1e9ed338e95dc9473496b978d59eae6.png

可以看到,我们成功通过新建的参数,设置了data、headers 和 method。

另外之前提到的headers也可以用add_header()方法添加,示例代码如下:

req 

3.高级用法

在上面的过程中,我们虽然可以构造请求,但是对于一些更高级的操作,比如Cookie处理、代理设置等,我们还需要借助Handler工具。

本部分内容相对硬核,初学者可以跳过,笔者后续有使用到再更新。

本文总结参考《Python3网络爬虫开发实战》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值