urllib库的使用(一)-----python3

你 urlib库为python3的HTTP内置请求库
urilib的四个模块:

  • urllib.request:它是最基本的HTTP请求模块,可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程了。
  • urllib.error:异常处理模块,用于处理异常的模块
  • urllib.parse:用于解析url,一个工具模块,提供了许多URL处理方法,比如拆分、解析、合并等。
  • urllib.robotparse:用于解析robots.txt,主要用于看哪些网站不能进行爬取,不过少用
    urllib的用法
    urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
urllib.request.urlopen(url, data=None, timeout=<object object at 0x000002407EBBC770>, *, cafile=None, capath=None, cadefault=False, context=None)
  • url:为请求网址
  • data:请求时需要发送的参数
  • timeout:超时设置,在该时间范围内返回请求内容就不会报错

发送请求

urlopen()它可以模拟浏览器的一个请求发起过程,同时它还带有处理授权验证(authenticaton)、重定向(redirection)、浏览器Cookies以及其他内容

import urllib.request  # 导入urllib.request模块,提供了最基本的构造HTTP请求的方法
response = urllib.request.urlopen('http://www.baidu.com')  # 以python官网为例,把这个页面爬取下来
print(response.read().decode('utf-8'))    # read()方法得到返回的网页内容

运行结果:输出的是网页的源代码。得到代码后,我们想要的链接、图片地址、文本信息就都可以提取出来。
在这里插入图片描述在这里插入图片描述

print(type(response)) # 输出响应类型
print(',,,,,,,,,,,,')
print(response.status) # 返回结果的状态码
print(',,,,,,,,,,,,')
print(response.getheaders())   # 响应的头信息
print(',,,,,,,,,,,,')
print(response.getheader('Server')) # 响应头中的Server值,nginx意思是服务器用nginx搭建的
  • HTTPResponse类型对象,主要包含:read()、readinto()、getheader(name)、getheaders()、fileno()等方法,以及msg、version、status、debuglevel、closed等属性,得到这个对象之后,我们把它赋值为response变量,然后就可以调用这些方法和属性,得到返回结果的一系列信息了。
  • 调用read()方法可以得到返回的网页内容,调用status属性可以得到返回结果的状态码,如:200代表请求成功,404代表网页未找到等。
  • 前两个输出分别输出了响应的状态码和响应的头信息,最后一个输出通过调用getheader()方法并传递一个参数Server获取了响应头中的Server值,结果是nginx,意思是服务器是用Nginx搭建的。利用最基本的urlopen()方法,可以完成最基本的简单网页的GET请求抓取。
    在这里插入图片描述
  • data参数

请求时加载数据
data参数是可选的,参数需是bytes类型,如果不是,则需要通过bytes()方法转化,另外传递了 这个参数,则它的请求方式就不再是GET方式,而是POST方式

import urllib.parse
import urllib.request
data = bytes(urllib.parse.urlencode({'word':'hello'}), encoding = 'utf8')  # 传递一个参数word,值为hello,需要被转码为bytes类型
response = urllib.request.urlopen('http://httpbin.org/post',data=data)
print(response.read())
  • timeout参数

timeout参数,如果不指定,就会使用全局默认时间,超时设置,在该时间范围内返回请求内容就不会报错,单位为秒,超过设置的时间,还没有得到响应,就会抛出异常,该异常属于urllib.error模块,错误原因是超时。
判断超时请求,一个网页如果长时间未响应,就跳过它的抓取。

import socket
import urllib.error
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')

运行结果:TIME OUT

按照常理来说,0.1秒内基本不可能得到服务器响应,通过设置timeout这个参数来实现超时处理,因此输出了TIMEOUT的提示

context参数,它必须是ssl.SSLContext类型,用来指定SSL设置
caflie和capath这两个参数分别指定CA证书和它的路径,这个在请求HTTPS链接时会有用
cadefault已经弃用,默认为False

如果希望返回与当前环境有关的信息,我们可以使用info()返回,比如可以执行

>>>response.info()
<http.client.HTTPMessage object at 0x0000000003623D68>
  • 可以看到,输出了对应的info,调用格式则为:“爬取的网页.info()”,我们之前爬取到的网页赋给了变量response,所以此时通过response调用。
  • 如果想要获取当前所爬取的URL地址,我们可以使用geturl()来实现
>>>response.geturl()
'http://www.baidu.com'

一般来说,URL标准中只会允许一部分ASCII字符比如数字、字母、部分符号等,而其他的一些字符,比如汉字等,是不符合URL标准的。此时,我们需要编码。
如果要进行编码,我们可以使用urllib.request.quote()进行,对编码的网址进行解码urllib.request.unquote

#对百度网址进行编码
>>>urllib.request.quote('http://www.baidu.com') 
'http%3A//www.baidu.com'
#对编码的网址进行解码
>>>urllib.request.unquote('http%3A//www.baidu.com')
'http://www.baidu.com'

Request方法

urlopen()方法可以实现最基本的发送,但如果想要构建一个完整的请求,在请求中需要加入Headers等信息,就可以利用更强大的Request类来构建
使用Request来请求网页,将请求独立成一个对象

扫描二维码关注公众号,回复: 8925542 查看本文章
import urllib.request
request = urllib.request.Request('https://python.org')
response = urllib.request.urlopen(request)#还用urlopen()方法来发送请求,只不过这次该方法的参数不再是URL,而是一个Request类型的对象
print(response.read().decode('utf-8'))

Request基本格式:

urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
  • url:用于请求URL,必传参数
  • data:如果要传,必须传bytes类型,如果它是字典,可以先用urllib.parse模块里的urlencode()编码
  • headers:请求头,我们可以在构造请求时通过headers参数值构造,也可以通过调用请求实例的add_header()方法添加,常用于通过修改User-Agent来伪装浏览器
  • origin_req_host:指的是请求方的host名称或者IP地址
  • unverifiable:这个请求是否是无法验证,默认False,即用户没用足够权限来选取接受这个请求的结果
  • method:是一个字符串,用来只是请求的方法,比如:GET、POST、PUT等
    浏览器的模拟—Headers属性
    任意打开一个网页,比如打开http://httpbin.org/post。然后按F12(或者Fn+F12),会出现一个窗口。切换到Network(网络)标签页:
    然后让网页发生一个动作。
    我们可以观察到右边的窗口出现了一些数据。将界面右上方的标签切换到“Headers”(标头)中,即可以看到了对应的头信息,此时往下拖动,在请求标头中的最后一行,就可以找到User-Agent字样的一串信息。这一串信息即是我们下面模拟浏览器所需要用到的信息。我们将其复制出来。
    在这里插入图片描述
 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763
#通过Request请求参数来请求网页
from urllib import request,parse
url = 'http://httpbin.org/post'   # 请求URL
headers = {   # headers指定User-Agent,Host
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
    'Host':'httpbin.org'
}
dict = {
    'name':'Germey'
}
data = bytes(parse.urlencode(dict), encoding='utf8')  # 参数转化为字节流
req = request.Request(url=url, data=data, headers=headers, method='POST')  # 指定请求方式为POST
response = request.urlopen(req)
print(response.read().decode('utf-8'))
#通过Request.add_header方法来请求网页
from urllib import request,parse
url = 'http://httpbin.org/post'   # 请求URL
dict= {
    'name':'Germey'
}
data = bytes(parse.urlencode(dict), encoding='utf8')  # 参数转化为字节流
req = request.Request(url = url, data = data, method='POST')
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36')
response = request.urlopen(req)
print(response.read().decode('utf-8'))

运行结果:
在这里插入图片描述
首先,导入urllib中的request,parse,设置要爬取的网址,然后调用request.Request()函数创建一个req对象,该函数第一个参数传入url,第二个参数可以传入数据,默认是传入0数据,第三个参数是传入头部,该参数也是有默认值的,默认是不传任何头部。
我们需要创建一个dict,将头部信息以键值对的形式存入到dict对象中,然后将该dict对象传入request.Request()函数第二个参数。
此时,已经成功设置好报头,然后我们使用urlopen()打开该Request对象即可打开对应的网址。

高级用法:
对于一些更高级的操作(比如Cookies处理、代理设置等),就需要更强大的工具Handler,urllib.request模块里的BaseHandler类,是所有其他Handler的父类,它提供了最基本的方法:

如:default_open()、protocol_request()等

以下为各种Handler子类继承了这个BaseHandler类:

  • HTTPDefaultErrorHandler:用于处理HTTP响应错误,错误都会抛出HTTPError类型的异常
  • HTTPRedirectHandler:用于处理重定向
  • HTTPCookieProcessor:用于处理Cookies
  • ProxyHandler:用于设置代理,默认代理为空
  • HTTPPasswordMgr:用于管理密码,它维护了用户名和密码的表
  • HTTPBasicAuthHandler:用于管理认证,如果一个链接打开需要认证,那么可以用它来解决认证问题
  • 还有其他的Handler类,详情可以参考官方文档。
    另一个比较重要的类就是OpenerDirector,我们可以称为Opener。我们之前用过urlopen()这个方法,实际上它就是urlib为我们提供的一个Opener。引入Opener是因为需要实现更高级的功能。的Request和urlopen()相当于类库为你封装好了极其常用的请求方法,可以完成基本的请求,但要实现更高级的功能,所以需要深入一层进行配置,使用更底层的实例来完成操作,所以这里就用到了Opener。Opener可以使用open()方法,返回的类型和urlopen()如出一辙,它实际上是利用Handler来构建Opener。
发布了30 篇原创文章 · 获赞 8 · 访问量 1811

猜你喜欢

转载自blog.csdn.net/ingenuou_/article/details/104040074