21.6. urllib.request —— 用于打开URL的可扩展库

源代码: Lib / urllib / request.py

urllib.request 模块定义了在基本和摘要式身份验证、 重定向、 cookies等应用中打开 Url (主要是 HTTP) 的函数和类。

也可以看看

Requests 包 建议用作高级的非底层的 HTTP 客户端接口。

urllib.request 模块定义了以下函数︰

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

打开url参数传进来的网址,既可以是一个字符串,又可以是一个Request对象。

当你有额外的数据要发送到服务器,那data参数必须是一个有数据的bytes对象,否则为None其实data 也可以是一个可迭代的对象,若是,则headers中必须带 Content-Length 参数。若本次HTTP请求要用POST方法,data必须有数据;若为GET方法时, data写None就行。

data参数应该是一个标准的application/x-www-form-urlencoded 格式的缓冲区.urllib.parse.urlencode() 函数接受一个映射或者一个内含一个两元素元组的序列,并且返回一个该格式的ASCII字符串。data参数在使用之前应该被编码成bytes。

urllib.request 模块参照 HTTP/1.1 标准, 并且在HTTP请求中,头信息可以有Connection:close

timeout 参数是可选的。它指定一个超时时间。若超过该时间,任何操作都会被阻止,如链接超时(如果没有指定,则会默认值为socket._GLOBAL_DEFAULT_TIMEOUT)。其实这个参数仅仅对http、https和ftp连接有效。

如果指定了 context 参数,则它必须是一个描述了各种SSL选项的 ssl.SSLContext 实例。更详细内容,请点击 HTTPSConnection

cafilecapath 参数都是可选的。他们应该被指定一组“HTTPS请求”所需要的受信任的CA 证书。cafile 参数应该指向文件,该文件包含了一大堆CA证书,而capath 参数应该指向一个目录,该目录包含了散列过的证书。更多的信息,可以从 ssl.SSLContext.load_verify_locations() 里找到。

cadefault 参数不能用了,所以不用管它了,吼吼~~

这个urlopen函数总是返回一个对象,能被context manager(上下文管理器)的一些方法使用,如:

  • geturl() — 返回一个资源索引的URL,通常重定向后的URL照样能get到。
  • info() — 返回页面的元信息,如头信息。像 email.message_from_string() 实例的格式一样。(请看 Quick Reference to HTTP Headers
  • getcode() – 返回响应后,HTTP的状态码。

对于HTTP和HTTPS网址,此函数会返回稍微修改的http.client.HTTPResponse对象。除了上述的三种新方法外,还有一个叫msg的属性,包含着和reason属性一样的信息 — 原因短语从服务器上返回 — 代替了HTTPResponse文档里指定的那些响应头。

对于 FTP,文件,和数据的URL,都显式地由以前的 URLopenerFancyURLopener 类处理,处理它们的函数,返回一个 urllib.response.addinfourl 对象。

引发协议错误的URLError

注意:如果没有服务器来处理这个请求,那么可能会返回None 值。(尽管有默认被安装的全局 OpenerDirector 使用 UnknownHandler 来确保这种情况不发生)。

另外,当代理被检测到,(例如,当一个像http_proxy*_proxy 环境变量 被设置), ProxyHandler 会被默认安装以确保请求会通过代理来处理。

在python2.6或者更早版本中遗留的 urllib.urlopen函数已经被停用; urllib.request.urlopen() 函数和旧版本python中的urllib2.urlopen函数其实是相同的。通过向urllib.urlopen传递一个字典参数得到的Proxy handing,能够通过使用ProxyHandler 对象来获取。

在3.2版本中的更改:cafilecapath 被增加。

在版本3.2中已更改:现在支持HTTPS虚拟主机(如果可能(即,如果ssl.HAS_SNI为true)。

3.2版本中新增功能:data参数可以是一个iterable对象。

在3.3版本中的更改:cadefault 被增加。

在3.4.3版本中的更改:context 被增加。

urllib.request.install_opener(opener)

安装OpenerDirector实例作为默认全局启动器。安装启动器只有当你想要urlopen使用启动器;否则,只需调用OpenerDirector.open()而不是urlopen()代码不检查真实的OpenerDirector,任何具有适当接口的类都可以工作。

urllib.request.build_opener([handler, ...])

返回OpenerDirector实例,按所给定的顺序链接处理程序。handler可以是BaseHandler的实例或BaseHandler的子类(在这种情况下,必须可以调用没有任何参数的构造函数) 。以下类的实例将在handler前面,除非handler包含它们,它们的实例或它们的子类:ProxyHandler (如果检测到代理设置),UnknownHandlerHTTPHandlerHTTPDefaultErrorHandlerHTTPRedirectHandlerFTPHandler FileHandlerHTTPErrorProcessor

如果 Python 安装了 SSL 支持 (即,如果 ssl 模块可以导入),还将添加 HTTPSHandler

BaseHandler 子类也可能更改其 handler_order 属性来修改其处理程序列表中的位置。

urllib.request.pathname2url(path)

将路径名path从本地语法转换为URL的路径组件中使用的形式。这不会产生一个完整的URL。返回值已使用quote()函数引用。

urllib.request.url2pathname(path)

将路径组件路径从百分比编码的URL转换为路径的本地语法。这不接受完整的URL。此函数使用unquote()解码路径

urllib.request.getproxies()

这个帮助函数返回一个方案到代理服务器URL映射的字典。它首先针对所有操作系统,以不区分大小写的方式扫描环境中的名为<scheme>_proxy的变量,并且在找不到它时,从Mac OSX System Configuration for Mac中查找代理信息OS X和Windows系统注册表。如果小写和大写环境变量存在(且不同意),则首选小写。

Note

If the environment variable REQUEST_METHOD is set, which usually indicates your script is running in a CGI environment, the environment variable HTTP_PROXY (uppercase _PROXY) will be ignored. This is because that variable can be injected by a client using the “Proxy:” HTTP header. If you need to use an HTTP proxy in a CGI environment, either use ProxyHandler explicitly, or make sure the variable name is in lowercase (or at least the _proxy suffix).

提供以下类:

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

这个类是一个URL请求的抽象。

url应为包含有效网址的字符串。

data必须是指定要发送到服务器的附加数据的字节对象,如果不需要此类数据,则None目前只有POST请求将data作为参数,GET请求不能使用data作为参数进行HTTP请求。data应为标准application/x-www-form-urlencoded格式的缓冲区。urllib.parse.urlencode()函数接受2元组的映射或序列,并返回此格式的ASCII字符串。在用作data参数之前,应将其编码为字节。

headers应该是一个字典,并且将被视为add_header()以每个键和值作为参数被调用。这通常用于“欺骗”User-Agent标头值,浏览器使用它来标识自身 - 某些HTTP服务器只允许来自常见浏览器的请求,而不是脚本。例如,Mozilla Firefox可能将其标识为“Mozilla / 5.0 (X11; U; Linux i686) Gecko / 20071127 Firefox / 2.0.0.11“,而urllib代理字符串是“Python-urllib / 2.6”(在Python 2.6上)。

使用Content-Type头与数据参数的示例将发送像{“Content-Type”: “application / x-www-form-urlencoded”}

最后两个参数仅对正确处理第三方HTTP Cookie感兴趣:

origin_req_host应为 RFC 2965定义的原始事务的请求主机。它默认为http.cookiejar.request_host(self)这是用户发起的原始请求的主机名或IP地址。例如,如果请求是针对HTML文档中的图像,则这应该是对包含图像的页面的请求的请求主机。

无法验证应指示该请求是否是无法验证的,如RFC 2965所定义。它默认为False无法验证的请求是用户的网址无法批准的请求。例如,如果请求是针对HTML文档中的图像,并且用户没有批准自动提取图像的选项,则这应该是真的。

方法应为指示将使用的HTTP请求方法的字符串(例如,'HEAD')。如果提供,它的值存储在method属性中,并由get_method()使用。子类可以通过在类本身中设置method属性来指示默认方法。

在版本3.3中更改: Request.method参数添加到Request类。

在版本3.4中更改:默认Request.method可以在类级别指示。

class urllib.request.OpenerDirector

OpenerDirector类通过BaseHandler链接在一起打开网址。它管理处理程序的链接,并从错误中恢复。

class urllib.request.BaseHandler

这是所有注册处理程序的基类 - 并且只处理注册的简单机制。

class urllib.request.HTTPDefaultErrorHandler

定义HTTP错误响应的默认处理程序的类;所有响应将变为HTTPError异常。

class urllib.request.HTTPRedirectHandler

一个类来处理重定向。

class urllib.request.HTTPCookieProcessor(cookiejar=None)

一个处理HTTP Cookie的类。

class urllib.request.ProxyHandler(proxies=None)

导致请求通过代理。如果给定代理,它必须是将协议名称映射到代理URL的字典。默认值是从环境变量 <protocol>_proxy中读取代理列表。如果未设置代理环境变量,则在Windows环境中,从注册表的Internet设置部分获取代理设置,在Mac OS X环境中,将从OS X系统配置框架检索代理信息。

禁用自动检测代理传递一个空字典。

no_proxy环境变量可用于指定不应通过代理访问的主机;如果设置,它应该是以逗号分隔的主机名后缀列表,可选择添加:port,例如cern.ch,ncsa.uiuc.edu,some.host:8080

Note

HTTP_PROXY will be ignored if a variable REQUEST_METHOD is set; see the documentation on getproxies().

class urllib.request.HTTPPasswordMgr

保留(领域, uri) - > (用户, 映​​射。

class urllib.request.HTTPPasswordMgrWithDefaultRealm

保留(领域, uri) - > (用户, 映​​射。None的领域被认为是一个全部收集的领域,如果没有其他领域,则搜索。

class urllib.request.HTTPPasswordMgrWithPriorAuth

HTTPPasswordMgrWithDefaultRealm的变体,其还具有uri - > is_authenticated映射。可以由BasicAuth处理程序用于确定何时立即发送身份验证凭证,而不是先等待401响应。

版本3.5中的新功能。

class urllib.request.AbstractBasicAuthHandler(password_mgr=None)

这是一个mixin类,可以帮助远程主机和代理的HTTP身份验证。password_mgr(如果给定)应该是与HTTPPasswordMgr兼容的内容;有关必须支持的接口的信息,请参阅HTTPPasswordMgr对象一节。如果passwd_mgr还提供is_authenticatedupdate_authenticated方法(请参阅HTTPPasswordMgrWithPriorAuth Objects),那么处理程序将使用is_authenticated结果,以确定是否与请求一起发送认证凭证。如果is_authenticated为URI返回True,则会发送凭据。如果is_authenticatedFalse,则不发送凭证,然后如果接收到401响应,则使用认证凭证重新发送请求。如果验证成功,则调用update_authenticated以为URI设置is_authenticated True,以便对URI或其任何超级URI将自动包括身份验证凭据。

版本3.5中的新功能:添加了is_authenticated支持。

class urllib.request.HTTPBasicAuthHandler(password_mgr=None)

处理与远程主机的身份验证。password_mgr(如果给定)应该是与HTTPPasswordMgr兼容的内容;有关必须支持的接口的信息,请参阅HTTPPasswordMgr对象一节。当出现错误的认证方案时,HTTPBasicAuthHandler将引发ValueError

class urllib.request.ProxyBasicAuthHandler(password_mgr=None)

处理与代理的身份验证。password_mgr(如果给定)应该是与HTTPPasswordMgr兼容的内容;有关必须支持的接口的信息,请参阅HTTPPasswordMgr Objects一节。

class urllib.request.AbstractDigestAuthHandler(password_mgr=None)

这是一个mixin类,可以帮助远程主机和代理的HTTP身份验证。password_mgr(如果给定)应该是与HTTPPasswordMgr兼容的内容;有关必须支持的接口的信息,请参阅HTTPPasswordMgr Objects一节。

class urllib.request.HTTPDigestAuthHandler(password_mgr=None)

处理与远程主机的身份验证。password_mgr(如果给定)应该是与HTTPPasswordMgr兼容的内容;有关必须支持的接口的信息,请参阅HTTPPasswordMgr Objects一节。当添加摘要认证处理器和基本认证处理器时,总是首先尝试摘要认证。如果摘要认证再次返回40x响应,则将其发送到处理的基本认证处理器。当呈现与Digest或Basic之外的认证方案时,此处理器方法将引发ValueError

在不受支持的身份验证方案中更改了版本3.3:提升ValueError

class urllib.request.ProxyDigestAuthHandler(password_mgr=None)

处理与代理的身份验证。password_mgr(如果给定)应该是与HTTPPasswordMgr兼容的内容;有关必须支持的接口的信息,请参阅HTTPPasswordMgr Objects一节。

class urllib.request.HTTPHandler

用于处理HTTP URL打开的类。

class urllib.request.HTTPSHandler(debuglevel=0, context=None, check_hostname=None)

用于处理打开HTTPS URL的类。上下文check_hostname的含义与http.client.HTTPSConnection中的含义相同。

在版本3.2中更改: 上下文check_hostname已添加。

class urllib.request.FileHandler

打开本地文件。

class urllib.request.DataHandler

打开数据网址。

版本3.4中的新功能。

class urllib.request.FTPHandler

打开FTP URL。

class urllib.request.CacheFTPHandler

打开FTP URL,保持打开的FTP连接的缓存以最小化延迟。

class urllib.request.UnknownHandler

用于处理未知网址的全部类。

class urllib.request.HTTPErrorProcessor

处理HTTP错误响应。

21.6.1. 请求对象

以下方法描述Request的公共接口,因此均可能在子类中被覆盖。它还定义了几个公共属性,客户端可以使用这些属性来检查解析的请求。

Request.full_url

传递给构造函数的原始URL。

在版本3.4中更改。

Request.full_url是一个具有setter,getter和deleter的属性。获取full_url会返回包含片段的原始请求网址(如果存在)。

Request.type

URI方案。

Request.host

URI权限,通常是主机,但也可以包含由冒号分隔的端口。

Request.origin_req_host

原始主机的请求,没有端口。

Request.selector

URI路径。如果Request使用代理,则选择器将是传递到代理的完整URL。

Request.data

请求的实体主体,如果未指定,则为None。

在版本3.4中更改:更改Request.data的值现在会删除“Content-Length”标头(如果之前已设置或计算)。

Request.unverifiable

boolean,指示请求是否是RFC 2965定义的不可验证的。

Request.method

要使用的HTTP请求方法。默认情况下,其值为None,这意味着get_method()将对要使用的方法执行其正常计算。可以通过在请求子类中的类级别设置默认值来设置其值(从而覆盖get_method()中的默认计算)通过方法参数将值传递给Request构造函数。

版本3.3中的新功能。

在版本3.4中更改:现在可以在子类中设置默认值;以前它只能通过constructor参数设置。

Request.get_method()

返回一个表示HTTP请求方法的字符串。If Request.method is not None, return its value, otherwise return 'GET' if Request.data is None, or 'POST' if it’s not. 这只对HTTP请求有意义。

在版本3.3中更改: get_method现在查看Request.method的值。

Request.add_header(key, val)

向请求中添加另一个标头。除了HTTP处理程序之外,所有处理程序当前都会忽略标头,并将其添加到发送到服务器的标头列表中。注意,不能有多个具有相同名称的标题,并且在发生冲突的情况下,稍后的调用将覆盖以前的调用。目前,这不是HTTP功能的丢失,因为当使用多次时具有含义的所有head具有(head特定的)仅使用一个报头获得相同功能的方式。

Request.add_unredirected_header(key, header)

添加不会添加到重定向请求的标头。

Request.has_header(header)

返回实例是否具有命名头(检查常规和非重定向)。

Request.remove_header(header)

从请求实例(从常规和非重定向头部)删除命名头。

版本3.4中的新功能。

Request.get_full_url()

返回构造函数中给定的URL。

在版本3.4中更改。

返回Request.full_url

Request.set_proxy(host, type)

通过连接到代理服务器来准备请求。主机类型将替换实例的实例,实例的选择器将是构造函数中给定的原始URL。

Request.get_header(header_name, default=None)

返回给定头的值。如果头不存在,返回默认值。

Request.header_items()

返回请求头的元组列表(header_name,header_value)。

在版本3.4中已更改:从3.3删除后请求方法add_data,has_data,get_data,get_type,get_host,get_selector,get_origin_req_host和is_unverifiable已弃用。

21.6.2. OpenerDirector Objects

OpenerDirector实例具有以下方法:

OpenerDirector.add_handler(handler)

处理程序应为BaseHandler的实例。将搜索以下方法,并将其添加到可能的链中(请注意,HTTP错误是一种特殊情况)。

  • protocol_open() - 处理程序知道如何打开协议 URL的信号。
  • http_error_type() - 表示处理程序知道如何使用HTTP错误代码类型处理HTTP错误。
  • protocol_error() - 处理程序知道如何处理来自(非http协议的错误的信号。
  • protocol_request() - 处理器知道如何预处理协议请求的信号。
  • protocol_response() - 处理器知道如何后处理协议响应的信号。
OpenerDirector.open(url, data=None[, timeout])

打开给定的url(可以是请求对象或字符串),可选择传递给定的数据Arguments, return values and exceptions raised are the same as those of urlopen() (which simply calls the open() method on the currently installed global OpenerDirector). 可选的timeout参数指定阻塞操作(如连接尝试)的超时(以秒为单位)(如果未指定,将使用全局默认超时设置)。超时功能实际上只适用于HTTP,HTTPS和FTP连接)。

OpenerDirector.error(proto, *args)

处理给定协议的错误。这将调用具有给定参数(其是协议特定的)的给定协议的注册的错误处理程序。HTTP协议是一种特殊情况,它使用HTTP响应代码来确定特定的错误处理程序;请参阅处理程序类的http_error_*()方法。

返回值和异常与urlopen()的相同。

OpenerDirector对象在三个阶段对象打开URL:

在每个阶段中调用这些方法的顺序通过对处理程序实例进行排序来确定。

  1. 具有名为protocol_request()的方法的每个处理程序都具有调用以预处理请求的方法。

  2. 调用具有名为protocol_open()的方法的处理程序来处理请求。当处理程序返回非None值(即。响应),或引发异常(通常URLError)。允许异常传播。

    事实上,上述算法首先尝试用于名为default_open()的方法。如果所有这些方法返回None,则对名为像protocol_open()的方法重复该算法。如果所有这些方法返回None,则对名为unknown_open()的方法重复该算法。

    请注意,这些方法的实现可能涉及父OpenerDirector实例open()error()方法的调用。

  3. 具有名为protocol_response()的方法的每个处理程序都有调用以对响应进行后处理的方法。

21.6.3. BaseHandler Objects

BaseHandler对象提供了几个直接有用的方法,以及其他一些旨在被派生类使用的方法。这些是直接使用:

BaseHandler.add_parent(director)

添加导演为父级。

BaseHandler.close()

删除任何父母。

以下属性和方法只能由从BaseHandler派生的类使用。

注意

定义protocol_request()protocol_response()方法的子类名为*Processor所有其他都命名为*Handler

BaseHandler.parent

有效的OpenerDirector,可用于使用不同的协议打开或处理错误。

BaseHandler.default_open(req)

此方法在BaseHandler中定义,但是子类应该定义它是否要捕获所有URL。

此方法(如果实现)将由父OpenerDirector调用。它应该返回像OpenerDirectorNoneopen()的返回值中描述的类文件对象。除非发生真正的异常事件(例如,MemoryError不应映射到URLError),否则应引用URLError

此方法将在任何协议特定的打开方法之前调用。

BaseHandler。 protocol_open req

此方法在BaseHandler中定义不是,但是子类应该定义它是否要处理具有给定协议的URL。

如果定义此方法,则将由父OpenerDirector调用。返回值应与default_open()相同。

BaseHandler.unknown_open(req)

此方法在BaseHandler中定义,但子类应定义它是否捕获所有没有特定注册处理程序的URL以打开它。

此方法(如果实现)将由parent OpenerDirector调用。返回值应与default_open()相同。

BaseHandler.http_error_default(req, fp, code, msg, hdrs)

此方法不是BaseHandler中定义,但是子类应该覆盖它,如果他们打算提供一个catch-all为未处理的HTTP错误。它将由OpenerDirector自动调用获取错误,并且通常不应在其他情况下调用。

req将是Request对象,fp将是具有HTTP错误主体,代码将是错误的三位数代码,msg将是用户可见的代码解释,hdrs将是具有错误标题的映射对象。

返回值和异常应与urlopen()的相同。

BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)

nnn应为三位数的HTTP错误代码。此方法也未在BaseHandler中定义,但如果发生HTTP代码nnn的错误,则会调用子类的实例(如果存在)。

子类应该覆盖此方法以处理特定的HTTP错误。

引用的参数,返回值和异常应与http_error_default()相同。

BaseHandler。 protocol_request req

此方法在BaseHandler中定义,但如果子类想要预处理给定协议的请求,则应定义它。

如果定义此方法,则将由父OpenerDirector调用。req将是Request对象。返回值应为Request对象。

BaseHandler。 protocol_response reqresponse

此方法在BaseHandler中定义,但如果子类想要对给定协议的响应进行后处理,则应定义它。

如果定义此方法,则将由父OpenerDirector调用。req将是Request对象。response will be an object implementing the same interface as the return value of urlopen(). 返回值应该实现与urlopen()的返回值相同的接口。

21.6.4. HTTPRedirectHandler Objects

注意

某些HTTP重定向需要来自此模块的客户端代码的操作。如果是这种情况,则会引发HTTPError有关各种重定向代码的精确含义的详细信息,请参见 RFC 2616

如果HTTPRedirectHandler显示的重定向网址不是HTTP,HTTPS或FTP网址,则会出现作为安全注意事项的HTTPError异常。

HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)

返回RequestNone以响应重定向。当从服务器接收到重定向时,这由http_error_30*()方法的默认实现调用。如果发生重定向,请返回新的Request以允许http_error_30*()执行重定向到newurl否则,如果没有其他处理程序尝试处理此URL,则引发HTTPError,或者如果您不能使用另一个处理程序,则返回None

注意

此方法的默认实现不严格遵循 RFC 2616,它说明对POST请求的301和302响应不能自动重定向用户确认。实际上,浏览器允许自动重定向这些响应,将POST更改为GET,默认实现再现此行为。

HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)

重定向到Location:URI: URL。当获取HTTP“永久移动”响应时,此方法由父OpenerDirector调用。

HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)

http_error_301()相同,但调用“found”响应。

HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)

http_error_301()相同,但调用“看到其他”响应。

HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)

http_error_301()相同,但称为“临时重定向”响应。

21.6.5. HTTPCookieProcessor Objects

HTTPCookieProcessor实例具有一个属性:

HTTPCookieProcessor.cookiejar

存储Cookie的http.cookiejar.CookieJar

21.6.6. ProxyHandler Objects

ProxyHandler. protocol_open 请求

对于每个协议ProxyHandler都有一个protocol_open()方法,该协议在代理构造函数。该方法将通过调用request.set_proxy()来修改通过代理的请求,并调用链中的下一个处理程序来实际执行协议。

21.6.7. HTTPPasswordMgr Objects

这些方法适用于HTTPPasswordMgrHTTPPasswordMgrWithDefaultRealm对象。

HTTPPasswordMgr.add_password(realm, uri, user, passwd)

uri可以是单个URI,也可以是一系列URI。realm用户passwd必须是字符串。这会导致realm的认证时使用(user, passwd) 给定任何给定的URI。

HTTPPasswordMgr.find_user_password(realm, authuri)

获取给定域和URI(如果有)的用户/密码。如果没有匹配的用户/密码,此方法将返回(无, 无)

对于HTTPPasswordMgrWithDefaultRealm对象,如果给定的领域没有匹配的用户/密码,将搜索领域None

21.6.8. HTTPPasswordMgrWithPriorAuth Objects

此密码管理器扩展了HTTPPasswordMgrWithDefaultRealm以支持始终发送验证凭据的跟踪URI。

HTTPPasswordMgrWithPriorAuth.add_password(realm, uri, user, passwd, is_authenticated=False)

realm, uri, user, passwd are as for HTTPPasswordMgr.add_password(). is_authenticated设置给定URI或URI列表的is_authenticated标志的初始值。如果is_authenticated被指定为True,则会忽略realm

HTTPPasswordMgr。 find_user_password realmauthuri

HTTPPasswordMgrWithDefaultRealm对象相同

HTTPPasswordMgrWithPriorAuth.update_authenticated(self, uri, is_authenticated=False)

更新给定uri或URI列表的is_authenticated标志。

HTTPPasswordMgrWithPriorAuth.is_authenticated(self, authuri)

返回给定URI的is_authenticated标志的当前状态。

21.6.9. AbstractBasicAuthHandler Objects

AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)

通过获取用户/密码对来处理身份验证请求,然后重新尝试请求。authreq应为请求中包含有关领域的信息的标头名称,host指定要认证的URL和路径,req 应为(失败)Request对象,应为错误标头。

主机是授权(例如"python.org")或包含权威组件的网址(例如"http://python.org/")。在任何一种情况下,权限都不能包含userinfo组件(因此,"python.org""python.org:80"很好,"joe:[email protected]"不是)。

21.6.10. HTTPBasicAuthHandler Objects

HTTPBasicAuthHandler.http_error_401(req, fp, code, msg, hdrs)

使用验证信息重试请求(如果可用)。

21.6.11. ProxyBasicAuthHandler Objects

ProxyBasicAuthHandler.http_error_407(req, fp, code, msg, hdrs)

使用验证信息重试请求(如果可用)。

21.6.12. AbstractDigestAuthHandler Objects

AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)

authreq应为请求中包含有关领域信息的标头名称,主机应为要认证的主机,req t2 >应该是(失败)Request对象,并且应该是错误标头。

21.6.13. HTTPDigestAuthHandler Objects

HTTPDigestAuthHandler.http_error_401(req, fp, code, msg, hdrs)

使用验证信息重试请求(如果可用)。

21.6.14. ProxyDigestAuthHandler Objects

ProxyDigestAuthHandler.http_error_407(req, fp, code, msg, hdrs)

使用验证信息重试请求(如果可用)。

21.6.15. HTTPHandler Objects

HTTPHandler.http_open(req)

发送HTTP请求,可以是GET或POST,具体取决于req.has_data()

21.6.16. HTTPSHandler Objects

HTTPSHandler.https_open(req)

发送HTTPS请求,可以是GET或POST,具体取决于req.has_data()

21.6.17. FileHandler Objects

FileHandler.file_open(req)

如果没有主机名,或者主机名为'localhost',请在本地打开文件。

在版本3.2中更改:此方法仅适用于本地主机名。当给出远程主机名时,会出现URLError

21.6.18. DataHandler Objects

DataHandler.data_open(req)

读取数据网址。这种类型的URL包含在URL本身中编码的内容。数据URL语法在 RFC 2397中指定。此实现忽略base64编码数据URL中的空格,因此URL可能会包含在任何源文件中。但是即使有些浏览器不介意在base64编码数据网址末尾缺少填充,这种实现会在这种情况下引入ValueError

21.6.19. FTPHandler Objects

FTPHandler.ftp_open(req)

打开req指示的FTP文件。登录始终使用空用户名和密码。

21.6.20. CacheFTPHandler Objects

CacheFTPHandler对象是FTPHandler对象,具有以下其他方法:

CacheFTPHandler.setTimeout(t)

将连接超时设置为t秒。

CacheFTPHandler.setMaxConns(m)

将高速缓存连接的最大数设置为m

21.6.21. UnknownHandler Objects

UnknownHandler.unknown_open()

引发URLError异常。

21.6.22. HTTPErrorProcessor Objects

HTTPErrorProcessor.http_response()

处理HTTP错误响应。

对于200个错误代码,将立即返回响应对象。

对于非200错误代码,这只是通过OpenerDirector.error()将作业传递到protocol_error_code()处理程序方法。最终,如果没有其他处理程序处理错误,HTTPDefaultErrorHandler将引发HTTPError

HTTPErrorProcessor.https_response()

处理HTTPS错误响应。

该行为与http_response()相同。

21.6.23. 示例

下面的示例中,更多的例子在 如何获取互联网资源使用 urllib 软件包中列出。

此示例获取 python.org 主页面,并显示它的开头的 300 个字节。

>>> import urllib.request
>>> with urllib.request.urlopen('http://www.python.org/') as f:
...     print(f.read(300))
...
b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n
<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n
<title>Python Programming '

请注意,urlopen返回一个字节的对象。这是因为urlopen自动确定从 HTTP 服务器接收的字节流的编码。一般情况下,程序将解码为字符串返回的字节对象一次确定或猜测的适当的编码。

下面的 W3C 文档中,https://www.w3.org/International/O-charset,列出在其中 (X) HTML 或 XML 文档可能已指定其编码信息的各种方式。

Python.org 网站使用 utf-8 编码作为其的 meta 标记中指定,我们将使用相同的解码的字节的对象。

>>> with urllib.request.urlopen('http://www.python.org/') as f:
...     print(f.read(100).decode('utf-8'))
...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtm

它也是可能而无需使用 上下文管理器 方法实现相同的结果。

>>> import urllib.request
>>> f = urllib.request.urlopen('http://www.python.org/')
>>> print(f.read(100).decode('utf-8'))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtm

在以下示例中,我们正在向 CGI 的 stdin 发送的数据流和它读取数据返回给我们。请注意,此示例将只当 Python 安装支持 SSL。

>>> import urllib.request
>>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',
...                       data=b'This data is passed to stdin of the CGI')
>>> with urllib.request.urlopen(req) as f:
...     print(f.read().decode('utf-8'))
...
Got Data: "This data is passed to stdin of the CGI"

CGI 在上面的示例中使用的示例的代码是︰

#!/usr/bin/env python
import sys
data = sys.stdin.read()
print('Content-type: text/plain\n\nGot Data: "%s"' % data)

以下是使用请求执行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:
    pass
print(f.status)
print(f.reason)

使用基本HTTP身份验证:

import urllib.request
# Create an OpenerDirector with support for Basic HTTP Authentication...
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)
# ...and install it globally so it can be used with urlopen.
urllib.request.install_opener(opener)
urllib.request.urlopen('http://www.example.com/login.html')

build_opener()默认提供了许多处理程序,包括ProxyHandler默认情况下,ProxyHandler使用名为<scheme>_proxy的环境变量,其中<scheme>是所涉及的URL方案。例如,读取 http_proxy

此示例将使用通过程序提供的代理URL替换默认ProxyHandler,并使用ProxyBasicAuthHandler添加代理授权支持。

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)
# This time, rather than install the OpenerDirector, we use it directly:
opener.open('http://www.example.com/login.html')

添加HTTP标头:

使用请求构造函数的参数,或:

import urllib.request
req = urllib.request.Request('http://www.example.com/')
req.add_header('Referer', 'http://www.python.org/')
# Customize the default User-Agent header value:
req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)')
r = urllib.request.urlopen(req)

OpenerDirector会自动为每个Request添加User-Agent标头。更改如下:

import urllib.request
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('http://www.example.com/')

Also, remember that a few standard headers (Content-Length, Content-Type and Host) are added when the Request is passed to urlopen() (or OpenerDirector.open()).

以下是使用GET方法检索包含参数的网址的示例会话:

>>> 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方法。注意,从urlencode输出的params在被发送到urlopen之前被编码为字节数据:

>>> 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'))
...

以下示例使用显式指定的HTTP代理,覆盖环境设置:

>>> import urllib.request
>>> proxies = {'http': 'http://proxy.example.com:8080/'}
>>> opener = urllib.request.FancyURLopener(proxies)
>>> with opener.open("http://www.python.org") as f:
...     f.read().decode('utf-8')
...

以下示例根本不使用代理,覆盖环境设置:

>>> import urllib.request
>>> opener = urllib.request.FancyURLopener({})
>>> with opener.open("http://www.python.org/") as f:
...     f.read().decode('utf-8')
...

21.6.24. Legacy interface

以下函数和类从Python 2模块urllib(而不是urllib2)移植。他们可能在将来的某个时候被弃用。

urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)

将由URL表示的网络对象复制到本地文件。如果URL指向本地文件,则除非提供文件名,否则不会复制对象。返回元组(filename, headers)其中filename是可以找到对象的本地文件名和头文件是由urlopen()返回的对象(对于远程对象)返回的对象的info()方法。异常与urlopen()相同。

第二个参数(如果存在)指定要复制到的文件位置(如果不存在,则该位置将是具有生成的名称的临时文件)。第三个参数,如果存在,是一个钩子函数,将在网络连接建立时调用一次,并在此后读取每个块后调用一次。钩子将传递三个参数;到目前为止传输的块的计数,以字节为单位的块大小,以及文件的总大小。第三个参数可以是旧的FTP服务器上的-1,它们不响应检索请求返回文件大小。

以下示例说明最常见的使用方案:

>>> import urllib.request
>>> local_filename, headers = urllib.request.urlretrieve('http://python.org/')
>>> html = open(local_filename)
>>> html.close()

如果url使用http:方案标识符,则可以指定可选的数据参数以指定POST请求(通常请求类型为GET)。数据参数必须是标准应用程序/ x-www-form-urlencoded格式中的字节对象;请参阅urllib.parse.urlencode()函数。

urlretrieve()会在发现ContentTooShortError时检测到可用数据量小于预期数量(即Content-Length header)。这可能发生在例如下载被中断时。

Content-Length被视为一个下限:如果有更多的数据要读取,urlretrieve会读取更多的数据,但如果没有可用的数据,它会引发异常。

在这种情况下,您仍然可以检索下载的数据,它存储在异常实例的content属性中。

如果没有提供Content-Length头,则urlretrieve不能检查已下载的数据的大小,并且只返回它。在这种情况下,您只需假设下载成功。

urllib.request.urlcleanup()

清除先前调用urlretrieve()可能留下的临时文件。

class urllib.request.URLopener(proxies=None, **x509)

自版本3.3起已弃用。

打开和读取URL的基类。除非需要使用http:ftp:file:之外的方案打开对象,否则可能需要使用FancyURLopener

By default, the URLopener class sends a User-Agent header of urllib/VVV, where VVV is the urllib version number. Applications can define their own User-Agent header by subclassing URLopener or FancyURLopener and setting the class attribute version to an appropriate string value in the subclass definition.

可选的代理参数应该是将方案名称映射到代理URL的字典,其中空字典完全关闭代理。其默认值为None,在这种情况下,将使用环境代理设置(如果存在),如上面的urlopen()定义中所讨论的。

在使用https:方案时,可在x509中收集的其他关键字参数可用于客户端的身份验证。支持关键字key_filecert_file提供SSL密钥和证书;两者都需要支持客户端身份验证。

URLopener对象将引发OSError异常,如果服务器返回错误代码。

open(fullurl, data=None)

Open fullurl using the appropriate protocol. This method sets up cache and proxy information, then calls the appropriate open method with its input arguments. If the scheme is not recognized, open_unknown() is called. The data argument has the same meaning as the data argument of urlopen().

open_unknown(fullurl, data=None)

Overridable interface to open unknown URL types.

retrieve(url, filename=None, reporthook=None, data=None)

Retrieves the contents of url and places it in filename. The return value is a tuple consisting of a local filename and either an email.message.Message object containing the response headers (for remote URLs) or None (for local URLs). The caller must then open and read the contents of filename. If filename is not given and the URL refers to a local file, the input filename is returned. If the URL is non-local and filename is not given, the filename is the output of tempfile.mktemp() with a suffix that matches the suffix of the last path component of the input URL. If reporthook is given, it must be a function accepting three numeric parameters: A chunk number, the maximum size chunks are read in and the total size of the download (-1 if unknown). It will be called once at the start and after each chunk of data is read from the network. reporthook is ignored for local URLs.

If the url uses the http: scheme identifier, the optional data argument may be given to specify a POST request (normally the request type is GET). The data argument must in standard application/x-www-form-urlencoded format; see the urllib.parse.urlencode() function.

version

Variable that specifies the user agent of the opener object. To get urllib to tell servers that it is a particular user agent, set this in a subclass as a class variable or in the constructor before calling the base constructor.

class urllib.request.FancyURLopener(...)

自版本3.3起已弃用。

FancyURLopener子类URLopener为以下HTTP响应代码提供默认处理:301,302,303,307和401。对于上面列出的30x响应代码,位置标头用于获取实际的网址。对于401响应代码(需要认证),将执行基本的HTTP认证。对于30x响应代码,递归由maxtries属性的值限定,默认值为10。

对于所有其他响应代码,调用方法http_error_default(),您可以在子类中覆盖以正确处理错误。

注意

根据 RFC 2616的字母,301和302对POST请求的响应不能在未经用户确认的情况下自动重定向。实际上,浏览器允许自动重定向这些响应,将POST更改为GET,并且urllib再现此行为。

构造函数的参数与URLopener的参数相同。

注意

执行基本认证时,FancyURLopener实例调用其prompt_user_passwd()方法。默认实现向用户询问控制终端上所需的信息。如果需要,子类可以覆盖此方法以支持更适当的行为。

FancyURLopener类提供了一个额外的方法,应该重载它以提供适当的行为:

prompt_user_passwd(host, realm)

返回在指定安全领域中的给定主机上认证用户所需的信息。返回值应为元组(用户, 密码),可用于基本认证。

实现在终端上提示此信息;应用程序应该覆盖此方法以在本地环境中使用适当的交互模型。

21.6.25. urllib.request限制

  • 目前,只支持以下协议:HTTP(版本0.9和1.0),FTP,本地文件和数据URL。

    在版本3.4中进行了更改:添加了对数据网址的支持。

  • urlretrieve()的缓存功能已被禁用,直到有人发现时间来正确处理到期时间标头。

  • 应该有一个函数来查询特定的URL是否在缓存中。

  • 为了向后兼容,如果URL显示为指向本地文件,但该文件无法打开,则使用FTP协议重新解释URL。这有时会导致混乱的错误消息。

  • 在等待网络连接建立时,urlopen()urlretrieve()函数可能导致任意长的延迟。这意味着使用这些函数而不使用线程来构建交互式Web客户机是很困难的。

  • urlopen()urlretrieve()返回的数据是服务器返回的原始数据。这可以是二进制数据(例如图像),纯文本或(例如)HTML。HTTP协议在回复头中提供类型信息,可以通过查看Content-Type头来检查。如果返回的数据是HTML,您可以使用模块html.parser来解析它。

  • 处理FTP协议的代码无法区分文件和目录。当尝试读取指向不可访问的文件的URL时,可能会导致意外的行为。如果URL以/结尾,则假定引用目录并将相应地处理。但是如果尝试读取文件导致550错误(意味着无法找到URL或无法访问,通常出于权限原因),则该路径被视为目录,以便处理指定目录时的情况,但尾部/已关闭。这可能会导致误导结果,当您尝试获取一个文件的读取权限使其无法访问; FTP代码将尝试读取它,失败,出现550错误,然后为不可读文件执行目录列表。如果需要细粒度控制,请考虑使用ftplib模块,子类化FancyURLopener或更改_urlopener以满足您的需求。

21.7. urllib.response - urllib使用的响应类

urllib.response模块定义了定义类似接口的最小文件的函数和类,包括read()readline()典型的响应对象是addinfourl实例,它定义了一个info()方法并返回标题和一个返回url的geturl()方法。此模块定义的函数由urllib.request模块内部使用。