urllib的build_opener

2019年翻新:

大家不要看opener啦,看requests吧opener有点过时了。

 

目录

一、openers和handlers的关系

二、对build_opener的源码分析

1、build_opener 的作用

2、使用默认的handlers应该怎么写?


一、openers和handlers的关系

(1)openers:opener可以想象成一瓶水的瓶盖,但是真正处理信息的是handler(水)

(2)handlers:解决问题,工作都由它完成。不同的handlers可以类比成用什么协议打开什么url。

二、对build_opener的源码分析

def build_opener(*handlers):
    """Create an opener object from a list of handlers.

    The opener will use several default handlers, including support
    for HTTP, FTP and when applicable HTTPS.

    If any of the handlers passed as arguments are subclasses of the
    default handlers, the default handlers will not be used.
    """
    opener = OpenerDirector()
    default_classes = [ProxyHandler, UnknownHandler, HTTPHandler,
                       HTTPDefaultErrorHandler, HTTPRedirectHandler,
                       FTPHandler, FileHandler, HTTPErrorProcessor,
                       DataHandler]
    if hasattr(http.client, "HTTPSConnection"):
        default_classes.append(HTTPSHandler)
    skip = set()
    for klass in default_classes:
        for check in handlers:
            if isinstance(check, type):
                if issubclass(check, klass):
                    skip.add(klass)
            elif isinstance(check, klass):
                skip.add(klass)
    for klass in skip:
        default_classes.remove(klass)

    for klass in default_classes:
        opener.add_handler(klass())

    for h in handlers:
        if isinstance(h, type):
            h = h()
        opener.add_handler(h)
    return opener

剔除使用默认即default_class的情况。当我们把handlers作为参数传进来,我们称之为handler_can,原来的默认的叫handler_yuan,当handler_can传进来我们首先判断它是不是一个对象(type看起来很陌生?你可以笼统的想象成是object,反正它们俩就是一个是鸡一个是蛋,先有鸡还是先有蛋?)然后再判断是不是default_class的子类假如是的话就把它放到default_class里面把父类剔除,就跟开头注释所说的一样“如果作为参数传递的任何处理程序都是默认处理的子类,则不会使用默认类处理程序”

 

1、build_opener 的作用

要爬取的各种各样的网页,它们有一部填写需要验证码,有的需要cookie,还有更多许多高级的功能,它们会阻碍你爬,而我对于openurl单纯地理解就是打开网页。openurl打开一个网址,它可以是一个字符串或者是一个request对象。而build_opener就是多了handler,处理问题更专业,更个性化。

2、使用默认的handlers应该怎么写?

例子1:

request = urllib.request.Request(url,data, headers or {})
opener = self.opener or urllib.request.build_opener(urllib.request.ProxyHandler)

例子2:

opener1 = urllib.request.install_opener(opener)

 

你可能感兴趣的:(爬虫)