Urllib2总结

Urllib2总结

2023年6月25日发(作者:)

Urllib2总结Urllib2 总结介绍Urllib2是⽤于获取URLs(统⼀资源定位符)的⼀个Python模块。它以urlopen函数的形式提供了⾮常简单的接⼝。能够使⽤各种不同的协议来获取⽹址。它还提供⼀个稍微复杂的接⼝⽤于处理常见的情况:如基本⾝份验证、cookies、proxies(代理)等。这Urllib2使⽤相关的⽹络协议(FTP,http),⽀持多种获取URLs的⽅案(以URL前⾯的”: ”定义,如:ftp://),这⾥主要讲最常见的http。⼀般情况下,使⽤urllib2是⾮常简单的。当打开⽹页遇到错误或异常时,你需要理解HTTP(超⽂本传输协议),最全⾯最权威HTTP协议可参考RFC2616。本⽂旨在说明使⽤urllib2。获取URLs简单的使⽤urllib2如下: import urllib2 response = n('') html = () print html可以看到请求的⽹页已经被打印出来了。使⽤urllib2就是如此简单。(可使⽤'ftp:'、'file'代替'http:')HTTP是基于请求和响应---客户端发出请求和服务器端发送响应。Urllib2 对应Request对象表⽰你做出HTTP请求,最简单的形式,创建⼀个指定要获取的⽹址的Request对象。这个Request对象调⽤urlopen,返回URL请求的Response对象。Respons import urllib2 req = t('') response = n(req) the_page = () print the_pageurlib2可以使⽤相同Request接⼝来处理所有URL⽅案,例如,你可以创建⼀个FTP请求: req = t('ftp:///')在HTTP协议中,Request对象有两个额外的事情可以做,第⼀,你可以通过将数据发送到服务器;第⼆,你可以通过数据的额外的信息(metadata)或请求到服务器本⾝,这个信息是发送HTTP'headers'。Data有时你想发送⼀个数据到URL(通常这个URL指向到CGI(公共⽹关接⼝)脚本或其他Web应⽤程序)。在HTTP中,经常使⽤POST请求。这个通常是浏览器做的,当你在你填写的⽹站上提交HTML表单。不是所有的POSTs都使⽤表单的形式:你可以使⽤POST传输任意数据到⾃⼰的应⽤中。在通常的HTML表单中,这些数据需要以标准的形式进⾏编码,然后传递到Request对象作为data参数。编码是通过使⽤urllib库⽽不是urllib2库。 import urllib import urllib2 url = '/cgi-bin/' values = {} values['name'] = 'Michael Foord' values['location'] = 'Northampton' values['language'] = 'Python' data = ode(values) #数据进⾏编码 req = t(url,data) #作为data参数传递到Request对象中 response = n(req) the_page = () print the_page如果你不传递data参数,urllib2使⽤GET请求。GET和POST请求不同的是,POST请求经常有副作⽤:它们在某种程度上改变系统的状态。尽管HTTP标准有明确的说明POSTs总是引起副作⽤,⽽GET请求从不会引起副作⽤,没有什么可以防⽌GET请求没有副作⽤,POST请求有副作⽤。数据也可以通过在URL本⾝中HTTP GET请求来编码。 >>> import urllib2 >>> import urllib >>> data = {} >>> data['name'] = 'Somebody Here' >>> data['location'] = 'Northampton' >>> data['language'] = 'Python' >>> url_values = ode(data) >>> print url_values name=Somebody+Here&language=Python&location=Northampton >>> url = '/' >>> full_url = url + '?' + url_values >>> data = n(full_url) #这个完整的URL是添加⼀个?到URL中,其次是编码的值。Headers在这⾥讨论⼀个特定的HTTP头,说明如何添加头到你的HTTP请求。⼀些⽹站(google)不喜欢由程序来访问或不同的浏览器发送不同的版本,默认情况下,urllib2标识⾃⼰为python urllib / x.y(x.y是Python版本号eg : 2.7),这个可能会混淆⽹站,或只是简单的不⼯作。浏览器标识⾃⼰的⽅式是通过⽤户代理(User-Agent)头。当创建⼀个Request对象时,你可以通过⼀个Headers的字典。下⾯的例⼦使相同的请求,但将其标识为⼀个版本的Internet Explorer。 import urllib import urllib2 url = '/cgi-bin/' user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' values = {} values['name'] = 'Michael Foord' values['location'] = 'Northampton' values['language'] = 'Python' headers = { 'User-Agent' : user_agent } data = ode(values) req = t(url,data,headers) response = n(req) the_page = () print the_pageresponse还有两个常⽤的⽅法(info、geturl)。Handling Exceptions当urlopen⽆法处理响应时将引起URLError(尽管像往常⼀样使⽤Python APIs,内建的异常如ValueError、TypeError等也可以引起),在特定的HTTP URLs情况下,HTTPError 是URLError的⼦类。URLError 通常,⽹络没有连接或没有路由到指定的服务器或指定的服务器不存在将引起URLError.在这种情形下,异常引发将有个reason属性,这是⼀个包含错误代码和⼀个⽂本错误信息的元组。 import urllib2 req = t('d_') try: n(req) except or,e: print [Errno 11004] getaddrinfo failed

HTTPError 每个HTTP响应从服务器包含⼀个数字状态码”,有时,这个状态码表明服务器⽆法满⾜请求。默认处理程序将处理⼀些响应(例如:如果响应是⼀个“重定向”,则要求客户端从不同的⽹址提取⽂档,urllib2将⾃⾏处理);对于那些它不能处理的,urlope HTTPError 实例提出的将⼀个整型的’code ‘属性,对应服务器发出的错误Error Codes。因为默认处理程序处理重定向(代码在300范围内),代码在100-299表明成功,你通常会看到在400-599范围错误代码。 ses是⼀个有⽤的字典响应码,显⽰所有的的响应码由RFC2616的应⽤。 # Table mapping response codes to messages; entries have the # form {code: (shortmessage, longmessage)}.

responses = { 100: ('Continue', 'Request received, please continue'), 101: ('Switching Protocols', 'Switching to new protocol; obey Upgrade header'), 200: ('OK', 'Request fulfilled, document follows'), 201: ('Created', 'Document created, URL follows'), 202: ('Accepted', 'Request accepted, processing continues off-line'), 203: ('Non-Authoritative Information', 'Request fulfilled from cache'), 204: ('No Content', 'Request fulfilled, nothing follows'), 205: ('Reset Content', 'Clear input form for further input.'), 206: ('Partial Content', 'Partial content follows.'), 300: ('Multiple Choices', 'Object has several resources -- see URI list'), 301: ('Moved Permanently', 'Object moved permanently -- see URI list'), 302: ('Found', 'Object moved temporarily -- see URI list'), 303: ('See Other', 'Object moved -- see Method and URL list'), 304: ('Not Modified', 'Document has not changed since given time'), 305: ('Use Proxy', 'You must use proxy specified in Location to access this ' 'resource.'), 307: ('Temporary Redirect', 'Object moved temporarily -- see URI list'), 400: ('Bad Request', 'Bad request syntax or unsupported method'), 401: ('Unauthorized', 'No permission -- see authorization schemes'), 402: ('Payment Required', 'No payment -- see charging schemes'), 403: ('Forbidden', 'Request forbidden -- authorization will not help'), 404: ('Not Found', 'Nothing matches the given URI'), 405: ('Method Not Allowed', 'Specified method is invalid for this server.'), 406: ('Not Acceptable', 'URI not available in preferred format.'), 407: ('Proxy Authentication Required', 'You must authenticate with ' 'this proxy before proceeding.'), 408: ('Request Timeout', 'Request timed out; try again later.'), 409: ('Conflict', 'Request conflict.'), 410: ('Gone', 'URI no longer exists and has been permanently removed.'), 411: ('Length Required', 'Client must specify Content-Length.'), 412: ('Precondition Failed', 'Precondition in headers is false.'), 413: ('Request Entity Too Large', 'Entity is too large.'), 414: ('Request-URI Too Long', 'URI is too long.'), 415: ('Unsupported Media Type', 'Entity body in unsupported format.'), 416: ('Requested Range Not Satisfiable', 'Cannot satisfy request range.'), 417: ('Expectation Failed', 'Expect condition could not be satisfied.'), 500: ('Internal Server Error', 'Server got itself in trouble'), 501: ('Not Implemented', 'Server does not support this operation'), 502: ('Bad Gateway', 'Invalid responses from another server/proxy.'), 503: ('Service Unavailable', 'The server cannot process the request due to a high load'), 504: ('Gateway Timeout', 'The gateway server did not receive a timely response'), 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'), }服务器响应引起的错误通过返回⼀个HTTP错误代码和错误页⾯,可以使⽤HTTPError实例为页⾯上的响应中返回。这个也有code属性,也有read、geturl、info⽅法。 import urllib2 req = t('/') try: n(req) except or,e: print print () print () print ()Wrapping it up(包装)如果你想编写HTTPError或URLError有两个基本⽅法。(更喜欢第⼆种⽅法)Number1同时处理HTTPError和URLError,应该把HTTPError放在URLError前⾯。由于HTTPError是URLError的⼦类,否则URLError也会捕获⼀个HTTPError错误。 from urllib2 import Request,urlopen,URLError,HTTPError req = Request('/') try: response = urlopen(req) except HTTPError,e: print 'The server couldn't fulfill the request' print 'Error code:', except URLError,e: print 'We failed to reache a server.' print 'Reason:', else: #everything is fine e()Number 2由于HTTPError是URLError的⼦类,可以避免导⼊HTTPError.改进如下: from urllib2 import Request,urlopen,URLError req = Request('/') try: response = urlopen(req) except URLError,e: if hasattr(e,'reason'): print 'We failed to reach a server.' print 'Reason:', elif hasattr(e,'code'): print 'The server couldn't fulfill the request' print 'Error code:', else: #everything is fine e()注意,URLError是内置异常IOError的⼦类,同样也可避免导⼊URLError.在某些情况下,urllib2也可能会引起。 from urllib2 import Request,urlopen req = Request('/') try: response = urlopen(req) except IOError,e: if hasattr(e,'reason'): print 'We failed to reach a server.' print 'Reason:', elif hasattr(e,'code'): print 'The server couldn't fulfill the request' print 'Error code:', else: #everything is fine e()BadStatusLine and HttpException

由⼀两种情况例外,不继承IOError引起的异常,⼀种是由httplib模块定义的BadStatusLine异常,当请求的页页⾯是空⽩时会引起这个异常。它没有继承IOError,⽽是从HttpException继承(在httplib中重新定义,直接从Exception中继承),可能还有info and geturl以urlopen返回的响应(或HTTPError实例)有两个有⽤的信息info和⽅法geturl。geturl --- 返回抓取页⾯的真正的URL。这是⾮常有⽤的,因为urlopen可能跟着⼀个重定向。获取的页⾯的⽹址可能与请求的地址不相同。info --- 返回⼀个描述页⾯抓取的字典对象,特别是服务器发送的头⽂件。这是当前的⼀个ssage实例。典型的heade包括'Content-length', 'Content-type'等。Openers and Handlers如果你想获取安装了特定处理程序的⽹址,需要创建openers。例如,获得opener处理cookies,或者获得opener不处理重定向。当使⽤opener(也许是director的命名实例)获取⼀个⽹页时,通常我们通过urlopen已经使⽤默认的opener, 但是我们可以创建⾃定义openers。openers使⽤处理程序。所有的“重起”是由处理程序完成的。每个处理程序知道如何为⼀个特创建⼀个opener,实例化⼀个openerdirector,然后反复调⽤.add_handle(some_handler_instance)。或者,你可以使⽤build_opener,这是⼀个⽅便的功能,⽤于创建具有⼀个单⼀的函数调⽤opener对象,.build_opener默认情况下增加了⼏个程序其他类型的处理程序,你可能希望可以处理proxies(代理)、authenticarion(⾝份验证)和其他常见情况。install_opener默认情况下可以打开⼀个opener对象(全局),这意味着调⽤urlopen将使⽤已安装的opener对象。Opener对象有⼀个open⽅法,使⽤urlopen函数直接抓取urls,不需要调⽤install_opener,除⾮为了⽅便。Basic Authentication说明如何创建和安装处理程序,我们将使⽤httpbasicauthhandler。对于这个问题的更详细的讨论,包括对基本认证如何⼯作的解释,看看 Basic Authentication Tutorial.当需要⾝份验证时,服务器发送⼀个头(以及401个错误代码)请求⾝份验证。这指定的⾝份验证scheme(⽅案)和'realm'(“领域”)。header是这样的:WWW-Authenticate:SCHEME realm=“REALM”。e.g. Www-authenticate: Basic realm="cPanel Users"然后,客户端应以适当的名称和密码重试请求,以在请求中包含作为header的域中的适当name和password。这是“基本的⾝份验证”为了简化这⼀过程,我们可以创建⼀个httpbasicauthhandler实例和opener使⽤此处理程序。httpbasicauthhandler使⽤对象称为⼀个密码管理器,来处理URL和服务器密码⽤户名映射,如果你知道这个领域是什么(从服务器发送的⾝份验证头),你可以使⽤HTTPPasswordMgr。通常不关⼼的领域是什么。在这种情况下,它使⽤很⽅便httppasswordmgrwithdefaultrealm。这允许您指定⼀个默认的⽤户名和密码的⽹址。我们表明这个提供None作为 add_password⽅法的域参数。顶级的⽹址是第⼀个需要认证的⽹址。⽹址“deeper”和URL传递给.add_password()也将匹配。 # create a password manager password_mgr = sswordMgrWithDefaultRealm() # Add the username and password. # If we knew the realm, we could use it instead of ``None``. top_level_url = "/foo/" password__password(None,top_level_url,username,password) handler = sicAuthHandler(password_mgr) # create "opener" (OpenerDirector instance) opener = _opener(handler) # use the opener to fetch a URL (a_url) # Install the opener. # Now all calls to n use our opener. l_opener(opener)注意:在上⾯的例⼦中,我们只提供给我们的httpbasicauthhandler build_opener。默认情况下,openers有正常情况下的处理程序--ProxyHandler,UnknownHandler,HTTPHandler, HTTPDefaultErrorHandler,HTTPRedirectHandler,FTPHandler,FileHandler,HTtop_level_url实际上是⼀个完整的URL(包括“http”计划的组成部分和主机名和可选的端⼝号)e.g. "/" 或者 ⼀个"authority"(i.e.主机名,包括主机名)e.g. "" or ":8080"(后者的例⼦包括⼀个端⼝号)这个 au如果存在,⼀定不能包含“userinfo”部分--例如:joe@password:不正确proxiesurllib2⾃动检测代理服务器设置和使⽤.这是通过proxyhandler是正常的处理程序链的⼀部分.通常情况下,这是⼀件好事,但也有⼀些时候,它可能不会有帮助。⼀个办法是建⽴我们⾃⼰的proxyhandler,没有代理的定义。这是使⽤类似的步骤来设置⼀ proxy_support = andler({}) opener = _opener(proxy_support) l_open(opener)注意: 当前的urllib2不⽀持通过proxy抓取https,这个可能是个问题.Sockets and LayersPython从⽹络获取资源⽀持分层,urllib2使⽤httplib的库,从⽽使⽤Socket库。在Python2.3你可以指定多少socket,应该等待超时前的反应。这可能是有⽤的应⽤程序,必须获取⽹页。默认情况下,socket模块没有超时和可以挂起。⽬前,socket超时不暴露httplib或者urllib2。然⽽,你可以在全局范围内为所有的socket设置默认超时使⽤。 import socket import urllib2 # timeout in seconds timeout = 10 ault timeout(timeout) #this call to n now uses the default timeout # we have set in the socket module req = t('') response = n(req)

发布者:admin,转转请注明出处:http://www.yc00.com/web/1687678803a30880.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信