一.Urllib简介 Urllib是python自带的标准库,无须安装,直接引用即可。Urllib通常用于爬虫开发,API(应用程序编程接口)数据获取和测试。在python2和python3中,Urllib在不同版本中的语法有明显的改变
python2分为Urllib和Urllib2,Urllib2可以接收一个Request对象,并对此来设置一个URL的Headers,但是Urllib只接收一个URL,意味着不能伪装用户代理字符串等。Urllib模块可以提供进行Urlencode的方法,该方法用于GET查询字符串的生成,Urllib2不具有这样的功能。这也是Urllib与Urllib2经常在一起使用的原因
在python3中,Urllib模块是一堆可以处理URL的组件集合,就是将Urllib和Urllib2合并在一起使用,并且命名为Urllib
在python3中,Urllib是一个收集几个模块来使用URL的软件包,大致具备以下功能:
urllib.request:用于打开和读取URL urllib.error:包含提出的例外urllib.request urllib.parse:用于解析URL urllib.robotparser:用于解析robots.txt文件 二.发送请求 urllib.request.urlopen的语法如下:
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=False,context=None) 1 功能说明:Urllib是用于访问URL(请求链接)的唯一方法
[参数说明]
url:需要访问的网站的URL地址。url格式必须完整,如movie.douban.com/为完整的url,若url为movie.douban.com/,则程序运行时会提示无法识别url的错误 data:默认值为None,Urllib判断参数data是否为None从而区分请求方式。若参数data为None,则代表请求方式为Get;反之请求方式为Post,发送Post请求。参数data以字典形式存储数据,并将参数data由字典类型转换成字节类型才能完成Post请求 timeout:超时设置,指定阻塞操作(请求时间)的超时(如果未指定,就使用全局默认超时设置) cafile,capath,cadefault:使用参数指定一组HTTPS请求的可信CA证书。cafile应指向包含一组CA证书的单个文件;capath应指向证书文件的目录;cadefault通常使用默认值即可 context:描述各种SSL选项的实例 当对网站发送请求时,网站会返回相应的响应内容。urlopen对象提供获取网站响应内容的方法函数,分别介绍如下:
read(),readline(),readlines(),fileno()和close():对HTTPResponse类型数据操作 info():返回HTTPMessage对象,表示远程服务器返回的头信息 getcode():返回HTTP状态码 geturl():返回请求的URL 下面的例子用于实现Urllib模块对网站发送请求并将响应内容写入文本文档,代码如下:
# 导入urllib import urllib.request # 打开url response=urllib.request.urlopen("https://movie.douban.com/",None,2) # 读取返回的内容 html=response.read().decode("utf8") # 写入txt f=open("html.txt","w",encoding="utf8") f.write(html) f.close() 1 2 3 4 5 6 7 8 9 10 首先导入urllib.request模块,然后通过urlopen访问一个URL,请求方式是GET,所以参数设置为None;最后的参数用于设置超时时间,设置为3秒,如果超过2秒,网站还没返回响应数据,就会提示请求失败的错误信息
当得到服务器的响应后,通过response.read()获取其响应内容。read()方法返回的是一个bytes类型的数据,需要通过decode()来转换成str类型。最后将数据写入文本文档中,encoding用于设置文本文档的编码格式,数据编码必须与文本文档编码一致,否则会出现乱码
三.复杂的请求 urllib.request.Request的语法如下:
urllib.request.Request(url,data=None,headers={},method=None) 1 功能说明:声明一个request对象,该对象可自定义header(请求头)等请求信息
[参数解释]:
url:完整的url格式,与urllib.request.urlopen的参数url一致 data:请求参数,与urllib.request.urlopen的参数data一致 headers:设置request请求头信息 method:设定请求方式,主要是POST和GET方式 一个完整的HTTP请求必须要有请求头信息。而urllib.request.Request的作用是设置HTTP的请求头信息。使urllib.request.Request设置请求头,代码如下:
# 导入urllib import urllib.request url="https://movie.douban.com/" # 自定义请求头 headers={ 'User-Agent':'Mozilla/5.0(Windows NT 6.1;WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3', 'Referer':'https://movie.douban.com/', 'Connnection':'keep-alive' } # 设置request的请求头 req=urllib.request.Request(url,headers=headers) # 使用urlopen打开req html=urllib.request.urlopen(req).read().decode('utf-8') # 写入文件 f=open('html.txt','w',encoding='utf8') f.write(html) f.close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 四.代理IP 代理IP的原理:以本机先访问代理IP,再通过代理IP地址访问互联网,这样网站(服务器)接收到的访问IP就是代理IP地址
Urllib提供了urllib.request.ProxyHandler()方法可动态设置代理IP池,代理IP主要以字典格式写入方法。完成代理IP设置后,将设置好的代理IP写入urllib.request.bulid_opener()方法,生成对象opener,然后通过opener的open()方法向网站(服务器)发送请求
使用代理IP访问网站,代码如下:
import urllib.request url='https://movie.douban.com/' # 设置代理IP proxy_handler=urllib.request.ProxyHandler( { 'http':'218.56.132.157:8080', 'https':'183.30.197.29:9797' } ) # 必须使用bulid_opener()函数来创建带有代理IP功能的opener对象 opener=urllib.request.build_opener(proxy_handler) response=opener.open(url) html=response.read().decode("utf-8") f=open('html.txt','w',encoding='utf8') f.write(html) f.close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 注意,由于使用代理IP,因此连接IP的时候有可能出现超时而导致报错,遇到这种情况只要更换其他代理IP地址或者再次访问即可。以下是常见的报错信息:
ConnectionResetError:[WinError 10054]远程主机强迫关闭了一个现有的连接 urllib.error.URLError:urlopen error Remote end closed connection without response(结束没有响应的远程连接) urllib.error.URLError:urlopen error [WinError 10054]远程主机强迫关闭了一个现有的连接 TimeoutError:[WinError 10060]由于连接方在一段时间后没有正确答复或连接的主机没有反应,因此连接尝试失败 urllib.error.URLError:urlopen error[WinError 10061]由于目标计算机拒绝访问,因此无法连接 五.使用Cookies Cookies主要用于获取用户登录信息,比如通过提交数据实现用户登录之后,会产生带有登录状态的Cookies,这时可以将Cookies保存在本地文件中,下次程序运行的时候,可以直接读取Cookies文件来实现用户登录
Urllib提供HTTPCookieProcessor()对Cookies操作。但Cookies的读写是由MozillaCookieJar()完成的。下面的例子实现Cookies写入文件,代码如下:
import urllib.request from http import cookiejar filename='cookie.txt' # MozillaCookiesJar保存cookie cookie=cookiejar.MozillaCookieJar(filename) # HTTPCookieProcessor创建cookie处理器 handler=urllib.request.HTTPCookieProcessor(cookie) # 创建自定义opener opener=urllib.request.build_opener(handler) # open方法打开网页 response=opener.open('https://movie.douban.com') # 保存cookie文件 cookie.save() 1 2 3 4 5 6 7 8 9 10 11 12 13 代码中的cookiejar是自动处理HTTP Cookie的类,MozillaCookieJar()用于将Cookies内容写入文件。程序运行时先创建MozillaCookieJar()对象,然后将对象直接传入函数HTTPCookieProcessor(),生成opener对象;最后使用opener对象访问URL,访问过程所生成的Cookies就直接写入已创建的文本文档中
接着再看如何读取Cookies,代码如下:
import urllib.request from http import cookiejar filename='cookie.txt' # 创建MozillaCookieJar对象 cookie=cookiejar.MozillaCookieJar() # 读取cookie内容到变量 cookie.load(filename) # HTTPCookieProcessor创建cookie处理器 handler=urllib.request.HTTPCookieProcessor(cookie) # 创建opener opener=urllib.request.build_opener(handler) # opener打开网页 response=opener.open('https://movie.douban.com') # 输出结果 print(cookie) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 读取和写入的方法很相似,主要区别在于:两者对MozillaCookieJar()对象的操作不同,导致实现功能也不同
注意,为了方便测试,上述代码中使用的cookie.save()和cookie.load(filename)将Cookies内容显示在文本文档中。在实际开发中,为了提高安全性,可以在保存和读取Cookies时设置参数,使Cookies信息隐藏在文件中。方法如下
cookie.save(ignore_discard=True,ignore_expires=True) cookie.load(filename,ignore_discard=True,ignore_expires=True) 1 2 六.证书验证 当遇到一些特殊的网站时,在浏览器上会显示连接不是私密连接而导致无法浏览该网页
补充:
CA证书也叫SSL证书,是数字证书的一种,类似于驾驶证护照和营业执照的电子副本。因为配置在服务器上,也称为SSL服务器证书
SSL证书就是遵守SSL协议,由受信任的数字证书机构颁发CA,在验证服务器身份后颁发,具有服务器身份验证和数据传输加密功能
SSL证书在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure Socket Layer,SSL),安全协议是由Netscape Communication公司设计开发的
遇到这类验证证书的网站,最简单而暴力的方法是直接关闭证书验证,可以在代码中引入SSL模块,设置关闭证书验证即可。代码如下:
import urllib.request import ssl # 关闭证书验证 ssl._create_default_https_context=ssl._create_unverified_context url='https://kyfw.12306.cn/otn/leftTicket/init' response=urllib.request.urlopen(url) # 输出状态码 print(response.getcode()) 1 2 3 4 5 6 7 8 七.数据处理 我们知道urllib.request.urlopen()方法是不区分请求方式的,识别请求方式主要通过参数data是否为None。如果向服务器发送Post请求,那么参数data需要使用rullib.parse对参数内容进行处理
Urllib在请求访问服务器的时候,如果发生数据传递,就需要对内容进行编码处理,将包含str或bytes对象的两个元素元组序列转换为百分比编码的ASCII文本字符串。如果字符串要用作Post,那么它应该被编码为字节,否则会导致TypeError错误
Urllib发送Post请求的方法如下:
import urllib.request import urllib.parse url='https://movie.douban.com' data={ 'value':'true' } # 数据处理 data=urllib.parse.urlencode(data).encode('utf-8') req=urllib.request.urlopen(url,data=data) 1 2 3 4 5 6 7 8 9 代码中urllib.parse.urlencode(data)将数据转换成字节的数据类型,而encode(utf-8)设置字节的编码格式。urlencode()的作用只是对请求参数做数据格式转换处理
除此之外,Urllib还提供quote()和unquote()对URL编码处理,使用方法如下
import urllib.parse url='%2523%25E7%25BC%2596%25E7%25A8%258B%2523' # 第一次编码 first=urllib.parse.unquote(url) print(first) second=urllib.parse.unquote(first) print(second) 1 2 3 4 5 6 7 八.本章小结 在python2和python3中,Urllib语法有明显的改变。其常用的语法有以下几种:
urllib.request.urlopen:urllib最基本的使用功能,用于访问URL(请求链接)的唯一方法 urllib.request.Request:声明request对象,该对象可自定义请求头(header),请求方式等信息 urllib.request.ProxyHandler:动态设置代理IP池,可加载请求对象 urllib.request.HTTPCookieProcessor:设置Cookies对象,可加载请求对象 urllib.request.build_opener():创建请求对象,用于代理IP和Cookies对象加载 urllib.parse.urlencode(data).encode('utf-8'):请求数据格式转换 urllib.parse.quote(url):URL编码处理,主要对URL上的中文等特殊符号编码处理 rullib.parse.unquote(url):URL解码处理,将URL上的特殊符号还原 更多学习资料可关注:itheimaGZ获取 |
|