urllib库的urlopen详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/85931725

一 爬虫基本库

Python提供了功能齐全的类库来帮助我们完成网络请求。最基础的HTTP库有urllib、httplib2、requests、treq等。

urllib库,只需要关心请求的链接是什么,需要传的参数是什么以及可选的请求头设置就好了,不用深入到底层去了解它到底是怎样传输和通信的。有了它,两行代码就可以完成一个请求和响应的处理过程,得到网页内容。

二 urllib介绍

在Python 2中,有urllib和urllib2两个库来实现请求的发送。而在Python 3中,已经不存在urllib2这个库了,统一为urllib,其官方文档链接为:https://docs.python.org/3/library/urllib.html

urllib库:Python内置的HTTP请求库,也就是说不需要额外安装即可使用。

它包含如下4个模块。

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

三 urllib库的urlopen介绍

1 urlopen()

1.1 点睛

urllib.request模块提供了最基本的构造HTTP请求的方法,利用它可以模拟浏览器的一个请求发起过程,同时它还带有处理授权验证(authenticaton)、重定向(redirection)、浏览器Cookies以及其他内容。

1.2 代码

import urllib.request

response = urllib.request.urlopen('https://www.python.org')
print(response.read().decode('utf-8'))

1.3 结果

2  结果类型分析

2.1 点睛

urlopen返回的是HTTPResposne类型的对象。

它主要包含read()、readinto()、getheader(name)、getheaders()、fileno()等方法,以及msg、version、status、reason、debuglevel、closed等属性。

得到这个对象之后,我们把它赋值为response变量,然后就可以调用这些方法和属性,得到返回结果的一系列信息了。

例如,调用read()方法可以得到返回的网页内容,调用status属性可以得到返回结果的状态码,如200代表请求成功,404代表网页未找到等。

2.2 代码

import urllib.request

response = urllib.request.urlopen('https://www.python.org')
print(type(response))

2.3 结果

E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/3_1_1.py

<class 'http.client.HTTPResponse'>

3 HTTPResposne的属性和方法。

3.1 代码

import urllib.request

response = urllib.request.urlopen('https://www.python.org')
# 前两个输出分别输出了响应的状态码和响应的头信息,
# 最后一个输出通过调用getheader()方法并传递一个参数Server获取了响应头中的Server值,
# 结果是nginx,意思是服务器是用Nginx搭建的。
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))

3.2 结果

E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/3_1_1.py

200

[('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'SAMEORIGIN'), ('x-xss-protection', '1; mode=block'), ('X-Clacks-Overhead', 'GNU Terry Pratchett'), ('Via', '1.1 varnish'), ('Content-Length', '48960'), ('Accept-Ranges', 'bytes'), ('Date', 'Sun, 06 Jan 2019 07:07:47 GMT'), ('Via', '1.1 varnish'), ('Age', '2563'), ('Connection', 'close'), ('X-Served-By', 'cache-iad2151-IAD, cache-hnd18733-HND'), ('X-Cache', 'HIT, HIT'), ('X-Cache-Hits', '1, 1970'), ('X-Timer', 'S1546758468.685275,VS0,VE0'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')]

nginx

4 urlopen函数data参数分析

4.1 函数原型

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

4.2 data参数

data参数是可选的。如果要添加该参数,并且如果它是字节流编码格式的内容,即bytes类型,则需要通过bytes()方法转化。另外,如果传递了这个参数,则它的请求方式就不再是GET方式,而是POST方式。

4.3 代码

import urllib.parse
import urllib.request
# 这里我们传递了一个参数word,值是hello。它需要被转码成bytes(字节流)类型。
# 其中转字节流采用了bytes()方法,该方法的第一个参数需要是str(字符串)类型,
# 需要用urllib.parse模块里的urlencode()方法来将参数字典转化为字符串;
# 第二个参数指定编码格式,这里指定为utf8
data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
# 这里请求的站点是httpbin.org,它可以提供HTTP请求测试。
# 本次我们请求的URL为http://httpbin.org/post,这个链接可以用来测试POST请求,
# 它可以输出请求的一些信息,其中包含我们传递的data参数。
response = urllib.request.urlopen('http://httpbin.org/post', data=data)
print(response.read())

4.4 结果

{
     "args": {},
     "data": "",
     "files": {},
     "form": {
         "word": "hello"
     },
     "headers": {
         "Accept-Encoding": "identity",
         "Content-Length": "10",
         "Content-Type": "application/x-www-form-urlencoded",
         "Host": "httpbin.org",
         "User-Agent": "Python-urllib/3.5"
     },
     "json": null,
     "origin": "123.124.23.253",
     "url": "http://httpbin.org/post"
}

4.5 说明

我们传递的参数出现在了form字段中,这表明是模拟了表单提交的方式,以POST方式传输数据。

5 urlopen函数timeout参数分析

5.1 点睛

timeout参数用于设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,就会使用全局默认时间。它支持HTTP、HTTPS、FTP请求。

5.2 实例

import urllib.request
# 这里我们设置超时时间是0.1秒
response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
print(response.read())

5.3 结果

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/var/py/python/urllibtest.py", line 4, in <module> response = urllib.request.urlopen('http://httpbin.org/get', timeout=1)

...

urllib.error.URLError: <urlopen error timed out>

5.4 结果说明

这里我们设置超时时间是0.1秒。程序0.1秒过后,服务器依然没有响应,于是抛出了URLError异常。该异常属于urllib.error模块,错误原因是超时。

5.5 捕获异常实战

import socket
import urllib.request
import urllib.error
# 这里我们请求了http://httpbin.org/get测试链接,
# 设置超时时间是0.1秒,然后捕获了URLError异常,
# 接着判断异常是socket.timeout类型(意思就是超时异常),
# 从而得出它确实是因为超时而报错,打印输出了TIME OUT
try:
    response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
except urllib.error.URLError as e:
    if isinstance(e.reason, socket.timeout):
        print('TIME OUT')

5.6  结果

E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/3_1_1.py

TIME OUT

6 其他参数

除了data参数和timeout参数外,还有context参数,它必须是ssl.SSLContext类型,用来指定SSL设置。

此外,cafile和capath这两个参数分别指定CA证书和它的路径,这个在请求HTTPS链接时会有用。

cadefault参数现在已经弃用了,其默认值为False。

urlopen()可以完成简单的请求和网页抓取。

若需更加详细的信息,可以参见官方文档:https://docs.python.org/3/library/urllib.request.html

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/85931725