下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922
论坛 >编程语言 >如何使用 urllib 包获取网络资源(2)

如何使用 urllib 包获取网络资源(2)

希尔瓦娜斯发布于 2018-02-26 09:21查看:943回复:1

小结

如果你想为HttpError 或 URLError作好准备,这里有两个方法。我个人推荐第二个。

第一个

image.png

注意: except HttpError 一定要放在前面, 不然except URLError 会获取HttpError

第二个

image.png

info and geturl

urlopen (或HttpError 实例)返回的响应有两个有用的方法, info() 和geturl() ,定义在urllib.response模块中.

geturl – 它返回获取的页面的真实URL。在urlopen (或使用的opener对象) 可能带有一个重定向时,它很有帮助。 获取的页面的URL不一定跟请求的URL相同。

info – 它返回一个字典-就像一个对象,用于描述获取的页面,特别是服务器发送的header。它是一个http.client.HttpMessage 实例。常见的header有‘Content-length’, ‘Content-type’等等。点击Quick Reference to Http Headers 查看Http header列表,内含各个header的简单介绍和用法。

Openers and Handlers

当你需要获取一个URL时,你需要一个opener(一个看起来不太容易理解的对象urllib.request.OpenerDirector的实例)。一般情况下我们都会通过urlopen来使用默认的opener,但是你可以自己创建不同的opener。Opener会使用handler。所有的“重活”由handler去承担。每个handler知道如何去以某个特定的URL模式(http,ftp等等)打开URL,或是如何处理URL启动的某个方面,比如Http重定向或Http cookie。

如果你想用某个已建立的handler去获取URL,你需要创建opener,例如一个处理cookie的opener,或是一个不处理重定向的opener。

要创建一个opener,你需要初始化一个OpenerDirector,然后重复调用.add_handler(some_handler_instance)。或者,你可以使用build_opener,一个便利的创建opener的函数,只需调用一次该函数便可创建opener。build_opener默认添加了一些handler,但是提供了便捷的途径去添加和/或重写默认的handler。

如果你想知道的话,还有其他种类的handler可以适用于代理,验证以及其他常见但又有些特殊的情形。

install_opener 可以用来创建一个opener对象,即(全局)默认opener。这意味着urlopen将会使用你创建的opener。

Opener对象有一个open方法,可以直接用来像urlopen一样去获取URL:除非更方便,否则没必要调用install_opener

基本验证

为了演示一个handler的创建和设置,我们将用到HttpBasicAuthHandler。想了解更多关于这方面的细节——包括基本验证是如何运行的——请看Basic Authentication Tutorial。当需要验证时,服务器会发送一个header(同时还有401错误码)来请求验证。这将会指定验证方案以及一个“realm”。Header看起来是这样的。

image.png

客户端接着应该用正确的用户名和密码进行重新请求(请求的header中包含realm)。这就是“基本验证”。为了简化这个过程,我们可以创建一个HttpBasicAuthHandler实例和一个使用该handler的opener。

HttpBasicAuthHandler使用一个叫password manager的对象去处理URL和realm,密码和用户名之间的映射。如果你知道realm是什么(根据服务器发来的验证header),那么你就可以使用HttpPasswordMgr。通常人们不会关心realm是什么。在这种情况下,使用HttpPasswordMgrWithDefaultRealm会很方便。它允许你指定一个URL默认的用户名和密码。它会在你没有给某个realm提供用户名和密码的时候起到作用。实现这种情况,我们需要将add_password 方法的realm参数设置为None

最上层的URL是第一个要求验证的URL。只要是比你传给.add_password()的URL“更深”的URL都可以匹配上。

image.png

注意在上面的例子中,我们只提供HttpBasicAuthHandler给build_opener。默认的情况下,opener有处理普通情况的handler —— ProxyHandler(如果代理的环境变量如http_proxy已经设置的话),UnknownHandlerHttpHandlerHttpDefaultErrorHandler,HttpRedirectHandlerFTPHandlerFileHandler, DataHandlerHttpErrorProcessor。

toplevel_url实际上要么是一个完整的URL(包括“Http:”模式部分以及主机名和可选的端口号)比如“http://example.com/” ,要么是一个“主体”(即主机名和可选的端口号)例如“example.com”或“example.com:8080”(后者包含了端口号)。该主体如果出现的话,不能包含“用户信息”部分——如“joe@password:example.com”就是不对的。

代理

urllib 将会自动检测你的代理设置并使用它们。这是通过ProxyHandler来实现的,当代理设置被检测到时,它是普通handler链的一部分。通常来说这是好事,但是它不一定会带来帮助[5]。一个不用定义代理的实现方式是创建我们自己的ProxyHandler。这个实现方法类似于创建一个基本认证handler:

image.png

请注意目前urllib.request不支持通过代理获取https位置。然而,这可以通过扩展urllib.request来实现,见[6]。

Sockets and Layers

Python支持从多层级网页中获取资源。urllib使用http.client库,而该库使用了socket库。在Python2.3中,你可以指定一个socket等待响应的时间。这对于需要获取网页的一些应用来说很有用。默认情况下,scoket模块没有超时时间的设定而是一直挂着。目前socket超时在http.clienturllib.request层是隐藏的。然后你可以将所有socket的默认超时设置成全局的,方法是:

image.png

更多套餐


2018软考网络工程师顺利通关套餐(最新、最全)

http://www.kokojia.com/package-1.html

2018软考网络规划设计师顺利通关套餐(最新、最全)

http://www.kokojia.com/package-11.html

2018软考信息安全工程师顺利通关套餐(最新、最全)

http://www.kokojia.com/package-41.html

2018软考系统集成项目管理工程师顺利通关套餐(最新、最全)

http://www.kokojia.com/package-76.html

2018软考信息安全工程师学习套餐(最新、最全)

http://www.kokojia.com/package-40.html

2018软考软件设计师顺利通关套餐(最新、最全)

http://www.kokojia.com/package-91.html



2017年Python从入门到企业实战

http://www.kokojia.com/package-59.html

java软件工程师(零基础自学全套课程)主讲人:任亮

http://www.kokojia.com/package-39.html

Linux运维全套视频火爆来袭

http://www.kokojia.com/package-27.html

Oracle数据库内功修炼实战视频教程

http://www.kokojia.com/package-47.html

Oracle OCP认证课程全套视频

http://www.kokojia.com/package-33.html

大数据从入门到精通(徐培成亲授)视频教程,赠Python课程套餐

http://www.kokojia.com/package-64.html

Python数据分析与机器学习实战系列课程

http://www.kokojia.com/package-66.html


收藏(0)0
查看评分情况

全部评分

此主贴暂时没有点赞评分

总计:0

回复分享

版主推荐

    共有1条评论

    • IT宅男
    • mr jack
    • Mr ken
    • Mright
    • cappuccino
    • YUI
    • 课课家运营团队
    • 课课家技术团队1
    • 酸酸~甜甜
    • 选择版块:

    • 标题:

    • 内容

    • 验证码:

    • 标题:

    • 内容

    • 选择版块:

    移动帖子x

    移动到: