urlib库

  urllib库是python中最基本的网络请求库,可以模拟浏览器的行为,向指定的服务器发送请求,并可以保存服务器返回的数据。

urlopen():

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

这里以Python官网为例,我们来把这个网页抓下来

from urllib import request

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

运行结果如下

 

  这里我们只用了两行代码,便完成了Python官网的抓取,输出了网页的源代码。得到源代码之后呢?我们想要的链接、图片地址、文本信息不就可以提取出来了吗?

  接下来,看下它返回的到底是什么。利用type()方法输出响应的类型:

from urllib import request

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

  输出的结果如下:

<class 'http.client.HTTPResponse'>

  可以发现,它是一个HTTPResponse类型的对象,主要包含read()、 readinto()、 getheader(name)、 getheaders()、 fileno()等方法, 以及msg、version、status、reason、debuglevel、colsed等属性。

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

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

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

  如果想给链接传递一些参数,该怎么实现呢?首先看一下urlopen()函数的API:

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

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

  下面我们详细说明这几个参数的用法。

  • data参数

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

  下面用实例来看一下:

import urllib.parse
import urllib.request

data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
response = urllib.request.urlopen('http://httpbin.org/post', data=data)
print(response.read().decode('utf8'))

  这里我们传递了一个参数word, 值是hello。它需要被转码成bytes类型。其中转字节流采用了bytes()方法,该方法的第一个参数需要str(字符串)类型,需要用urllib.parse模块里的urlencode()方法来将参数字典转化为字符串;第二个参数指定编码格式,这里指定为utf8。

  这里请求的站点是httpbin.org,它可以提供HTTP请求测试。本次我们请求的URL为http://httpbin.org/post,这个链接可以用来测试POST请求,它可以输出请求的一些信息,其中包含我们传递的data参数。

  运行结果如下:

{
  "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.7"
  }, 
  "json": null, 
  "origin": "220.170.50.160, 220.170.50.160", 
  "url": "https://httpbin.org/post"
}

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

  • timeout参数

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

import urllib.request

response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
print(response.read())

  运行结果如下:

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

  • 其他参数

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

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

Request

  我们利用urlopen()方法可以显示最基本请求的发起,但这几个简单的参数 并不足以构建一个完整的请求。如果请求需要加入Headers等信息,就可以利用更 强大的Request类来构建。

  首先,我们用实例来感受一下Request的用法:

import urllib.request

request = urllib.request.Request('http://python.org')
response = urllib.request.urlopen(request)
print(response.read().decode('utf8'))

  可以发现,我们依然利用urlopen()方法来发送这个请求,只不过这个该方法不再是URL,而是一个Requeset类型的对象。通过构造这个数据结构,一方面我们可以将请求独立成一个对象,另一方面可更加丰富和灵活地配置参数。

  它的构造方法如下:

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

  • 第一个参数url用于请求URL,这是必传参数,其他都是可选参数。
  • 第二个参数data如果要传,必须传bytes(字节流)类型的,如果它是字典,可以先用urllib.parse模块里的urlencode()编码。
  • 第三个参数是一个字典,它就是请求头,我们可以在构造请求时通过headers参数直接构造,也可以通过调用请求实例的add_header()方法添加。添加请求头常用的用法就是通过修改User-Agent来伪装浏览器,默认的User-Agent是Python-urllib,我们可以通过修改它来伪装浏览器。
  • 第四个参数origin_req_host指的是请求方的host名称或者IP地址。
  • 第五个参数unverifiable表示这个请求是否是无法验证的,默认是False,意思就是说 用户没有足够的 权限来选择接受这个请求的结果。例如我们请求一个HTML文档的图片,但是我们没有权限自动抓取图像的权限,这时unverifiable的值就是True。
  • 第六个参数method是一个字符串,用来指示请求使用的方法。比如GET、POST和PUT等。

  

猜你喜欢

转载自www.cnblogs.com/jeavy/p/11521151.html