Python urllib、urllib2、urllib3用法及区别

2022-06-25 11:26:57

简介1

在可供使用的网络库中,urlliburllib2可能是投入产出比最高的两个,是Python中操作url的官方标准库。它们让你能够通过网络访问文件,就像这些文件位于你的计算机中一样。只需一个简单的函数调用,就几乎可将统一资源定位符(URL)可指向的任何动作作为程序的输入。结合re模块使用将发挥强大威力!

一个简单的例子:

req= urllib2.Request(
	url=url,
	data=postdata,
	headers=headers)
result= urllib2.urlopen(req)

模块urlliburllib2的功能差不多,简单来说urllib2urllib的增强——urllib2更好一些,但是urllib中有urllib2中所没有的函数。对于简单的下载,urllib绰绰有余。 如果需要实现HTTP身份验证Cookie亦或编写扩展来处理自己的协议,urllib2可能是更好的选择。在Python2.x中主要为urlliburllib2,这两个标准库是不可相互替代的。但是在Python3.x中将urllib2合并到了urllib,这一点值得注意。

  • urllib支持设置编码的函数urllib.urlencode,在模拟登陆的时候经常需要传递经过post编码之后的参数,如果不想使用第三方库完成模拟登录,就必须使用到标准库中的urlliburllib提供一些比较原始基础的方法而urllib2并没有,比如urllib中的urlencode方法用来GET查询字符串的产生。

  • urllib2比较有优势的地方在于urllib2.openurl中可以接受一个Request类的实例来设置Request参数,来修改/设置Header头从而达到控制HTTP Request的header部分的目的,也可以修改用户代理,设置cookie等,但urllib仅可以接受URL。这就意味着,如果你访问一个网站想更改User Agent(可以伪装你的浏览器),你就需要使用urllib2urllib2模块没有加入urllib.urlretrieve函数以及urllib.quote等一系列quote和unquote功能,这个时候就需要urllib的辅助。

因此Python2.x中,urlliburllib2两者搭配使用。

1、打开远程文件

几乎可以像打开本地文件一样打开远程文件,差别是只能使用读取模式,以及使用模块urllib.request中的函数urlopen,而不是open(或file)。

from urllib.requestimport urlopen
webpage= urlopen('http://www.python.org')

如果连接到了网络,变量webpage将包含一个类似于文件的对象,这个对象与网页http://www.python.org相关联。

注意:要在没有联网的情况下尝试使用模块urllib,可使用以file:打头的URL访问本地文件,如file:c:\text\somefile.txt(别忘了对反斜杠进行转义)。

urlopen返回的类似于文件的对象支持方法:close、 read、readline和readlines,还支持迭代等。

假设要提取刚才所打开网页中链接About的相对URL, 可使用正则表达式 。

>>>import re>>> text= webpage.read()# 注意:如果这个网页发生了变化,你可能需要修改使用的正则表达式。>>> m= re.search(b'<a href="([^"]+)" .*?>about</a>', text, re.IGNORECASE)>>> m.group(1)'about'
02、获取远程文件

函数urlopen返回一个类似于文件的对象,可从中读取数据。如果要让urllib替你下载文件并将其副本存储在一个本地文件中,可使用urlretrieve。这个函数不返回一个类似于文件的对象,而返回一个格式为(filename, headers)的元组,其中filename是本地文件的名称(由urllib自动创建),而headers包含一些有关远程文件的信息(这里不会介绍headers, 如果你想更深入地了解它,请在有关urllib的标准库文档中查找urlretrieve)。如果要给下载的副本指定文件名,可通过第二个参数来提供。

urlretrieve('http://www.python.org','C:\\python_webpage.html')

这将获取Python官网的主页,并将其存储到文件C:\python_webpage.html中。如果你没有指定文件名,下载的副本将放在某个临时位置,可使用函数open来打开。但使用完毕后,你可能想将其删除以免占用磁盘空间。要清空这样的临时文件,可调用函数urlcleanup且不提供任何参数,它将负责替你完成清空工作。

一些实用的函数

除了通过URL读取和下载文件外,urllib还提供了一些用于操作URL的函数,如下所示(这里假设你对URL和CGI略知一二)。

  • quote(string[, safe]) 返回一个字符串,其中所有的特殊字符(在URL中有特殊意义的字符)都已替换为对URL友好的版本(如将~替换为%7E),如果要将包含特殊字符的字符串用作URL很有用。参数safe是一个字符串(默认为'/'),包含不应像这样对其进行编码的字符。

  • quote_plus(string[, safe]) 类似于quote,但也将空格替换为加号。

  • unquote(string):与quote相反。

  • unquote_plus(string):与quote_plus相反。

  • urlencode(query[, doseq]) 将映射(如字典)或由包含两个元素的元组(形如(key, value))组成的序列转换为“使用URL编码的”字符串。这样的字符串可用于CGI查询中(详细信息请参阅Python文档)。


一、urllib

urllib作为Python的标准库,基本上涵盖了基础的网络请求功能。

1。urllib.request

urllib中,request这个模块主要负责构造和发起网络请求,并在其中加入Headers、Proxy等。

1. 发起GET请求

主要使用urlopen()方法来发起请求:

from urllibimport request

resp= request.urlopen('http://www.baidu.com')print(resp.read().decode())

urlopen()方法中传入字符串格式的url地址,则此方法会访问目标网址,然后返回访问的结果。

返回的结果会是一个http.client.HTTPResponse对象,使用此对象的read()方法可以获取访问网页获得的数据。但是要注意的是,获得的数据会是bytes的二进制格式,所以需要decode()一下,转换成字符串格式。

使用带参数的GET方法取回URL:

>>>import urllib>>> params= urllib.urlencode({'spam':1,'eggs':2,'bacon':0})>>> f= urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s"% params)>>>print f.read()
2. 发起POST请求

urlopen()默认的访问方式是GET,当在urlopen()方法中传入data参数时,则会发起POST请求。注意:传递的data数据需要为bytes格式。timeout参数还可以设置超时时间,如果请求时间超出,那么就会抛出异常。

from urllibimport request

resp= request.urlopen('http://httpbin.org/post', data=b'word=hello', timeout=10)print(resp.read().decode())

使用带参数的POST方法:

>>>import urllib>>> params= urllib.urlencode({'spam':1,'eggs':2,'bacon':0})>>> f= urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)>>>print f.read()
3. 添加Headers

通过urllib发起的请求会有默认的一个Headers:"User-Agent":"Python-urllib/3.6",指明请求是由urllib发送的。
所以遇到一些验证User-Agent的网站时,我们需要自定义Headers,而这需要借助于urllib.request中的Request对象。

from urllibimport request

url='http://httpbin.org/get'
headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}# 需要使用url和headers生成一个Request对象,然后将其传入urlopen方法中
req= request.Request(url, headers=headers)
resp= request.urlopen(req)print(resp.read().decode())
4. Request对象

如上所示,urlopen()方法中不止可以传入字符串格式的url,也可以传入一个Request对象来扩展功能,Request对象如下所示。

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

构造Request对象必须传入url参数,data数据和headers都是可选的。
最后,Request方法可以使用method参数来自由选择请求的方法,如PUT,DELETE等等,默认为GET。

5. 添加Cookie

为了在请求时能带上Cookie信息,我们需要重新构造一个opener。
使用request.build_opener方法来进行构造opener,将我们想要传递的cookie配置到opener中,然后使用这个opener的open方法来发起请求。

from httpimport cookiejarfrom urllibimport request

url='https://www.baidu.com'# 创建一个cookiejar对象
cookie= cookiejar.CookieJar()# 使用HTTPCookieProcessor创建cookie处理器
cookies= request.HTTPCookieProcessor(cookie)# 并以它为参数创建Opener对象
opener= request.build_opener(cookies)# 使用这个opener来发起请求
resp= opener.open(url)# 查看之前的cookie对象,则可以看到访问百度获得的cookiefor iin cookie:print(i)

或者也可以把这个生成的opener使用install_opener方法来设置为全局的,之后使用urlopen方法发起请求时,都会带上这个cookie:

# 将这个opener设置为全局的opener
request.install_opener(opener)
resp= request.urlopen(url)
6. 设置Proxy代理

使用爬虫来爬取数据的时候,常常需要使用代理来隐藏我们的真实IP。

from urllibimport request

url='http://httpbin.org/ip'
proxy={'http':'218.18.232.26:80','https':'218.18.232.26:80'}# 创建代理处理器
proxies= request.ProxyHandler(proxy)# 创建opener对象
opener= request.build_opener(proxies)

resp= opener.open(url)print(resp.read().decode())

urllib官方文档的例子:

# 使用HTTP代理,自动跟踪重定向>>>import urllib>>> proxies={'http':'http://proxy.example.com:8080/'}>>> opener= urllib.FancyURLopener(proxies)>>> f= opener.open("http://www.python.org")>>> f.read()# 不使用代理>>>import urllib>>> opener= urllib.FancyURLopener({})>>> f= opener.open("http://www.python.org/")>>> f.read()
7. 下载数据到本地

在我们进行网络请求时常常需要保存图片或音频等数据到本地,一种方法是使用python的文件操作,将read()获取的数据保存到文件中。
而urllib提供了一个urlretrieve()方法,可以简单的直接将请求获取的数据保存成文件。

from urllibimport request

url='http://python.org/'# urlretrieve()方法传入的第二个参数为文件保存的位置,以及文件名。
request.urlretrieve(url,'python.html')

urlretrieve()方法是Python2.x直接移植过来的方法,以后有可能在某个版本中弃用。

2。urllib.response

在使用urlopen()方法或者opener的open()方法发起请求后,获得的结果是一个response对象。这个对象有一些方法和属性,可以让我们对请求返回的结果进行一些处理。

read():获取响应返回的数据,只能使用一次。

getcode():获取服务器返回的状态码。

getheaders():获取返回响应的响应报头。

geturl():获取访问的url。

3。urllib.parse

urllib.parseurllib中用来解析各种数据格式的模块。

1. urllib.parse.quote

在url中,是只能使用ASCII中包含的字符的,也就是说,ASCII不包含的特殊字符,以及中文等字符都是不可以在url中使用的。而我们有时候又有将中文字符加入到url中的需求,例如百度的搜索地址:https://www.baidu.com/s?wd=南北?之后的wd参数,则是我们搜索的关键词。那么我们实现的方法就是将特殊字符进行url编码,转换成可以url可以传输的格式,urllib中可以使用quote()方法来实现这个功能。

>>>from urllibimport parse>>> keyword='南北'>>> parse.quote(keyword)'%E5%8D%97%E5%8C%97'

如果需要将编码后的数据转换回来,可以使用unquote()方法。

>>> parse.unquote('%E5%8D%97%E5%8C%97')'南北'
2.urllib.parse.urlencode

在访问url时,我们常常需要传递很多的url参数,而如果用字符串的方法去拼接url的话,会比较麻烦,所以urllib中提供了urlencode这个方法来拼接url参数。

>>>from urllibimport parse>>> params={'wd':'南北','code':'1','height':'188'}>>> parse.urlencode(params)'wd=%E5%8D%97%E5%8C%97&code=1&height=188'

4。urllib.error

在urllib中主要设置了两个异常,一个是URLError,一个是HTTPErrorHTTPErrorURLError的子类。

HTTPError还包含了三个属性:

  • code:请求的状态码
  • reason:错误的原因
  • headers:响应的报头

例子:

In[1]:from urllib.errorimport HTTPError

In[2]:try:...:     request.urlopen('https://www.jianshu.com')...:except HTTPErroras e:...:print(e.code)403

二、urllib2

Python2.x的一个例子:

import urllib2# 设置浏览器请求头
ua_headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0"}#建立请求内容
request=urllib2.Request("http://baidu.com/",headers=ua_headers)#获取响应
response=urllib2.urlopen(request)#页面内容
html=response.read()print htmlprint response.getcode()#返回响应码print response.geturl()#返回实际urlprint response.info()#返回服务器响应的报头

Python3.x(整合之后的urllib)的一个例子:

from urllibimport request

url= r'https://www.baidu.com/'
headers={'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3','Referer': r'http://www.lagou.com/zhaopin/Python/?labelWords=label','Connection':'keep-alive'}
req= request.Request(url, headers=headers)
html= request.urlopen(req).read()# 处理编码
html= html.decode('utf-8')print(html)

来自urllib2官方文档的几个例子:

GET一个URL:
>>>import urllib2>>> f= urllib2.urlopen('http://www.python.org/')>>>print f.read()
使用基本的HTTP认证:
import urllib2
auth_handler= urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='PDQ Application',
                          uri='https://mahler:8092/site-updates.py',
                          user='klem',
                          passwd='kadidd!ehopper')
opener= urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
urllib2.urlopen('http://www.example.com/login.html')

注:build_opener()默认提供很多处理程序,包括代理处理程序,代理默认会被设置为环境变量所提供的。

一个使用代理的例子:
proxy_handler= urllib2.ProxyHandler({'http':'http://www.example.com:3128/'})
proxy_auth_handler= urllib2.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm','host','username','password')

opener= urllib2.build_opener(proxy_handler, proxy_auth_handler)
opener.open('http://www.example.com/login.html')
添加HTTP请求头部:
import urllib2
req= urllib2.Request('http://www.example.com/')
req.add_header('Referer','http://www.python.org/')
r= urllib2.urlopen(req)
更改User-agent:
import urllib2
opener= urllib2.build_opener()
opener.addheaders=[('User-agent','Mozilla/5.0')]
opener.open('http://www.example.com/')

注:httplibhttplib2httplib是http客户端协议的实现,通常不直接使用,urllib是以httplib为基础,httplib2是第三方库,比httplib有更多特性。httplib比较底层,一般使用的话用urlliburllib2即可。

三、Python3.X中使用整合后的urllib

Python2.x 有这些库名可用:urlliburllib2urllib3httplibhttplib2requests
Python3.x 有这些库名可用:urlliburllib3httplib2requests


若只使用Python3.x,记住有个urllib的库就行了。Pyhton2.x和Python3.x都有urllib3requests, 它们不是标准库。urllib3提供线程安全连接池和文件post等支持,与urlliburllib2的关系不大。requests 自称HTTP for Humans,使用更简洁方便。

Python3.x中将urllib2合并到了urllib,之后此包分成了以下几个模块:

  • urllib.request 用于打开和读取URL

  • urllib.error 用于处理前面request引起的异常

  • urllib.parse 用于解析URL

  • urllib.robotparser用于解析robots.txt文件

Python3.x中,随着urllib2合入urllib,一些常用的方法也发生了变化:2

  1. 在Python2.x中使用import urlparse——在Python3.x中会使用import urllib.parse

  2. 在Python2.x中使用urllib2.urlopenurllib.urlopen(已弃用)——在Python3.x中会使用urllib.request.urlopen

  3. 在Python2.x中使用urllib2.Request——在Python3.x中会使用urllib.request.Request

  4. 在Python2.x中使用urllib.quote——在Python3.x中会使用urllib.request.quote

  5. 在Python2.x中使用urllib.urlencode——在Python3.x中会使用urllib.parse.urlencode

  6. 在Python2.x中使用cookielib.CookieJar——在Python3.x中会使用http.CookieJar

  7. 异常处理:在Python2.x中使用urllib2.URLError,urllib2.HTTPError——在Python3.x中会使用urllib.error.URLError,urllib.error.HTTPError

:在Python3.3后urllib2已经不能再用,所有urllib2全部用urllib.request来代替。


urlliburllib2在Python2.x以及Python3.x的区别:

Python2.x中:
import urllibimport urllib2

1、共同点:都可以直接用urlopen(‘url’)请求页面

2、不同点:urlliburlencode(dict)unquote()进行编码和解码

3、对于error:

try:
	response= urllib2.urlopen("http://pythonsite.com/111341.html")except urllib2.HTTPErroras e:print(e.reason)print(e.code)print(e.headers)except urllib2.URLErroras e:print(e.reason)else:print("reqeust successfully")
Python3.x中:

1、请求页面:urllib.request.urlopen(‘url’)

2、对于error:

from urllibimport request,errortry:
	response= request.urlopen("http://pythonsite.com/113211.html")except error.HTTPErroras e:print(e.reason)print(e.code)print(e.headers)except error.URLErroras e:print(e.reason)else:print("reqeust successfully")

几个官方例子:

GET一个URL:
>>>import urllib.request>>>with urllib.request.urlopen('http://www.python.org/')as f:...print(f.read(300))
PUT一个请求:
import urllib.request
DATA=b'some data'
req= urllib.request.Request(url='http://localhost:8080', data=DATA, method='PUT')with urllib.request.urlopen(req)as f:passprint(f.status)print(f.reason)
基本的HTTP认证:
import urllib.request
auth_handler= urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm='PDQ Application',
                          uri='https://mahler:8092/site-updates.py',
                          user='klem',
                          passwd='kadidd!ehopper')
opener= urllib.request.build_opener(auth_handler)
urllib.request.install_opener(opener)
urllib.request.urlopen('http://www.example.com/login.html')
使用proxy:
proxy_handler= urllib.request.ProxyHandler({'http':'http://www.example.com:3128/'})
proxy_auth_handler= urllib.request.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm','host','username','password')

opener= urllib.request.build_opener(proxy_handler, proxy_auth_handler)
opener.open('http://www.example.com/login.html')
添加头部:
import urllib.request
req= urllib.request.Request('http://www.example.com/')
req.add_header('Referer','http://www.python.org/')
r= urllib.request.urlopen(req)
更改User-agent:
import urllib.request
opener= urllib.request.build_opener()
opener.addheaders=[('User-agent','Mozilla/5.0')]
opener.open('http://www.example.com/')
使用GET时设置URL的参数:
>>>import urllib.request>>>import urllib.parse>>> params= urllib.parse.urlencode({'spam':1,'eggs':2,'bacon':0})>>> url="http://www.musi-cal.com/cgi-bin/query?%s"% params>>>with urllib.request.urlopen(url)as f:...print(f.read().decode('utf-8'))...
使用POST时设置参数:
>>>import urllib.request>>>import urllib.parse>>> data= urllib.parse.urlencode({'spam':1,'eggs':2,'bacon':0})>>> data= data.encode('ascii')>>>with urllib.request.urlopen("http://requestb.in/xrbl82xr", data)as f:...print(f.read().decode('utf-8'))...</
  • 作者:weixin_30952535
  • 原文链接:https://blog.csdn.net/weixin_30952535/article/details/97339923
    更新时间:2022-06-25 11:26:57