• urllib2的一些简单介绍

    urlopen()的源码比较
    服务器君一共花费 10.601 ms 进行了 3 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    先来一点题外话。看看下面一段代码:

    main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
    

    这一行代码是1987年由贝尔实验室的 David Korn 提交的获奖作品,为什么我想起这茬儿呢?还不是因为urllib和urllib2,“大师把代码写成上面那样可以获奖,你要把代码写成那样,就是垃圾”,这不是我的话,不过是有他的意思的。

    我看到了 urllib 和 urllib2 在设计和代码构造上很多不同,想到,或者是猜测 python 发展过程中,guido 越来越看不惯 urllib 的混乱结构了,但是很多人已经习惯 import urllib 了,并且用的还可以,所以 urllib 不管代码里多么混乱,但他能运行。很好,于是 guido 只能在urllib 外在开发了 urllib2,来满足一个有“洁癖”的程序员的心理需求。所以,当看到 urllib2 的代码结构的时候,明显比 urllib 清晰了很多,明确了很多,心情好多了。介绍的时候我会对比 urllib2 怎么做的,而 urllib 又是怎么做的。

    大概了解

    urlib2 是使用各种协议完成打开 url 的一个扩展包。最简单的使用方式是调用 urlopen() 方法,比如:

    import urllib2
    content_stream = urllib2.urlopen('http://www.google.com/')
    content = content_stream.read()
    print content
    

    即可以接受一个字符串型的 url 地址或者一个 Request 对象。将打开这个 url 并返回结果为一个像文件对象一样的对象。

    接下来是 OpenerDirector 操作类。这是一个管理很多处理类(Handler)的类。而所有这些 Handler 类都对应处理相应的协议,或者特殊功能。分别有下面的处理类:

    • BaseHandler
    • HTTPErrorProcessor
    • HTTPDefaultErrorHandler
    • HTTPRedirectHandler
    • ProxyHandler
    • AbstractBasicAuthHandler
    • HTTPBasicAuthHandler
    • ProxyBasicAuthHandler
    • AbstractDigestAuthHandler
    • ProxyDigestAuthHandler
    • AbstractHTTPHandler
    • HTTPHandler
    • HTTPCookieProcessor
    • UnknownHandler
    • FileHandler
    • FTPHandler
    • CacheFTPHandler

    是不是很多?是不是和我说的结构简单不一致?不是的,他们都是遵循相应的规则,需求创建的类,甚至是相似的。你何必一口想吃成个胖子,全部都要会,先只管最最基本的需求吧,http 协议的处理类。

    刚才我们说的最简单的 urlib2 的使用,也就是源码中给出的使用方式:

    #file: urllib2.py
    _opener = None
    def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
        global _opener
        if _opener is None:
            _opener = build_opener()
        return _opener.open(url, data, timeout)
    

    对比给出 urllib 的最基本的使用方式:

    _urlopener = None
    def urlopen(url, data=None, proxies=None):
        """Create a file-like object for the specified URL to read from."""
        from warnings import warnpy3k
        warnpy3k("urllib.urlopen() has been removed in Python 3.0 in "
                 "favor of urllib2.urlopen()", stacklevel=2)
     
        global _urlopener
        if proxies is not None:
            opener = FancyURLopener(proxies=proxies)
        elif not _urlopener:
            opener = FancyURLopener()
            _urlopener = opener
        else:
            opener = _urlopener
        if data is None:
            return opener.open(url)
        else:
            return opener.open(url, data)
    

    很明显,urlib2 里 urlopen() 的实现方式更加优雅。

    有个小警告: warnpy3k("urllib.urlopen() has been removed in Python 3.0 in " "favor of urllib2.urlopen()", stacklevel=2),说在 py3k 中已经移除了 urllib.urlopen,更加偏爱 urllib2.urlopen(),我想或多或少证明了我前面的一点猜测,guido 看不惯 urllib 里的一些代码,在 python2.6 里先给你些小提示。

    在下一篇会深入探讨下两者 urlopen() 的实现方式的细节比较。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [Python程序设计] 从PHP到Python 3 个条目
  2. [智力开发与知识管理] 整体性学习步骤 9 个条目
  3. [数据库技术] 数据库范式篇 5 个条目
  4. [移动开发] 简单了解Android Fragment 3 个条目
  5. [PHP程序设计] PHP里的引用 5 个条目
  6. [Python程序设计] Tornado 服务器环境配置 3 个条目
  7. [PHP程序设计] fsockopen,curl与file_get_contents 12 个条目
  8. [Python程序设计] Django与表单 4 个条目
  9. [软件工程与项目管理] 开始了解Git 5 个条目
  10. [移动开发] Activity 初步知识 2 个条目
  11. [Python程序设计] Tornado表单处理 3 个条目
  12. [JavaScript程序设计] Web实时通信技术名词解析 5 个条目
窗口 -- [资讯]