urllib.py

来自「mallet是自然语言处理、机器学习领域的一个开源项目。」· Python 代码 · 共 1,466 行 · 第 1/4 页

PY
1,466
字号
    for i in range(len(res)):        c = res[i]        if not _fast_safe.has_key(c):            res[i] = '%%%02X' % ord(c)    return ''.join(res)def quote(s, safe = '/'):    """quote('abc def') -> 'abc%20def'    Each part of a URL, e.g. the path info, the query, etc., has a    different set of reserved characters that must be quoted.    RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists    the following reserved characters.    reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |                  "$" | ","    Each of these characters is reserved in some component of a URL,    but not necessarily in all of them.    By default, the quote function is intended for quoting the path    section of a URL.  Thus, it will not encode '/'.  This character    is reserved, but in typical usage the quote function is being    called on a path where the existing slash characters are used as    reserved characters.    """    safe = always_safe + safe    if _fast_safe_test == safe:        return _fast_quote(s)    res = list(s)    for i in range(len(res)):        c = res[i]        if c not in safe:            res[i] = '%%%02X' % ord(c)    return ''.join(res)def quote_plus(s, safe = ''):    """Quote the query fragment of a URL; replacing ' ' with '+'"""    if ' ' in s:        l = s.split(' ')        for i in range(len(l)):            l[i] = quote(l[i], safe)        return '+'.join(l)    else:        return quote(s, safe)def urlencode(query,doseq=0):    """Encode a sequence of two-element tuples or dictionary into a URL query string.    If any values in the query arg are sequences and doseq is true, each    sequence element is converted to a separate parameter.    If the query arg is a sequence of two-element tuples, the order of the    parameters in the output will match the order of parameters in the    input.    """    if hasattr(query,"items"):        # mapping objects        query = query.items()    else:        # it's a bother at times that strings and string-like objects are        # sequences...        try:            # non-sequence items should not work with len()            x = len(query)            # non-empty strings will fail this            if len(query) and type(query[0]) != types.TupleType:                raise TypeError            # zero-length sequences of all types will get here and succeed,            # but that's a minor nit - since the original implementation            # allowed empty dicts that type of behavior probably should be            # preserved for consistency        except TypeError:            ty,va,tb = sys.exc_info()            raise TypeError, "not a valid non-string sequence or mapping object", tb    l = []    if not doseq:        # preserve old behavior        for k, v in query:            k = quote_plus(str(k))            v = quote_plus(str(v))            l.append(k + '=' + v)    else:        for k, v in query:            k = quote_plus(str(k))            if type(v) == types.StringType:                v = quote_plus(v)                l.append(k + '=' + v)            elif type(v) == types.UnicodeType:                # is there a reasonable way to convert to ASCII?                # encode generates a string, but "replace" or "ignore"                # lose information and "strict" can raise UnicodeError                v = quote_plus(v.encode("ASCII","replace"))                l.append(k + '=' + v)            else:                try:                    # is this a sufficient test for sequence-ness?                    x = len(v)                except TypeError:                    # not a sequence                    v = quote_plus(str(v))                    l.append(k + '=' + v)                else:                    # loop over the sequence                    for elt in v:                        l.append(k + '=' + quote_plus(str(elt)))    return '&'.join(l)# Proxy handlingdef getproxies_environment():    """Return a dictionary of scheme -> proxy server URL mappings.    Scan the environment for variables named <scheme>_proxy;    this seems to be the standard convention.  If you need a    different way, you can pass a proxies dictionary to the    [Fancy]URLopener constructor.    """    proxies = {}    for name, value in os.environ.items():        name = name.lower()        if value and name[-6:] == '_proxy':            proxies[name[:-6]] = value    return proxiesif os.name == 'mac':    def getproxies():        """Return a dictionary of scheme -> proxy server URL mappings.        By convention the mac uses Internet Config to store        proxies.  An HTTP proxy, for instance, is stored under        the HttpProxy key.        """        try:            import ic        except ImportError:            return {}        try:            config = ic.IC()        except ic.error:            return {}        proxies = {}        # HTTP:        if config.has_key('UseHTTPProxy') and config['UseHTTPProxy']:            try:                value = config['HTTPProxyHost']            except ic.error:                pass            else:                proxies['http'] = 'http://%s' % value        # FTP: XXXX To be done.        # Gopher: XXXX To be done.        return proxies    def proxy_bypass(x):        return 0elif os.name == 'nt':    def getproxies_registry():        """Return a dictionary of scheme -> proxy server URL mappings.        Win32 uses the registry to store proxies.        """        proxies = {}        try:            import _winreg        except ImportError:            # Std module, so should be around - but you never know!            return proxies        try:            internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')            proxyEnable = _winreg.QueryValueEx(internetSettings,                                               'ProxyEnable')[0]            if proxyEnable:                # Returned as Unicode but problems if not converted to ASCII                proxyServer = str(_winreg.QueryValueEx(internetSettings,                                                       'ProxyServer')[0])                if '=' in proxyServer:                    # Per-protocol settings                    for p in proxyServer.split(';'):                        protocol, address = p.split('=', 1)                        # See if address has a type:// prefix                        import re                        if not re.match('^([^/:]+)://', address):                            address = '%s://%s' % (protocol, address)                        proxies[protocol] = address                else:                    # Use one setting for all protocols                    if proxyServer[:5] == 'http:':                        proxies['http'] = proxyServer                    else:                        proxies['http'] = 'http://%s' % proxyServer                        proxies['ftp'] = 'ftp://%s' % proxyServer            internetSettings.Close()        except (WindowsError, ValueError, TypeError):            # Either registry key not found etc, or the value in an            # unexpected format.            # proxies already set up to be empty so nothing to do            pass        return proxies    def getproxies():        """Return a dictionary of scheme -> proxy server URL mappings.        Returns settings gathered from the environment, if specified,        or the registry.        """        return getproxies_environment() or getproxies_registry()    def proxy_bypass(host):        try:            import _winreg            import re            import socket        except ImportError:            # Std modules, so should be around - but you never know!            return 0        try:            internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')            proxyEnable = _winreg.QueryValueEx(internetSettings,                                               'ProxyEnable')[0]            proxyOverride = str(_winreg.QueryValueEx(internetSettings,                                                     'ProxyOverride')[0])            # ^^^^ Returned as Unicode but problems if not converted to ASCII        except WindowsError:            return 0        if not proxyEnable or not proxyOverride:            return 0        # try to make a host list from name and IP address.        host = [host]        try:            addr = socket.gethostbyname(host[0])            if addr != host:                host.append(addr)        except socket.error:            pass        # make a check value list from the registry entry: replace the        # '<local>' string by the localhost entry and the corresponding        # canonical entry.        proxyOverride = proxyOverride.split(';')        i = 0        while i < len(proxyOverride):            if proxyOverride[i] == '<local>':                proxyOverride[i:i+1] = ['localhost',                                        '127.0.0.1',                                        socket.gethostname(),                                        socket.gethostbyname(                                            socket.gethostname())]            i += 1        # print proxyOverride        # now check if we match one of the registry values.        for test in proxyOverride:            test = test.replace(".", r"\.")     # mask dots            test = test.replace("*", r".*")     # change glob sequence            test = test.replace("?", r".")      # change glob char            for val in host:                # print "%s <--> %s" %( test, val )                if re.match(test, val, re.I):                    return 1        return 0else:    # By default use environment variables    getproxies = getproxies_environment    def proxy_bypass(host):        return 0# Test and time quote() and unquote()def test1():    import time    s = ''    for i in range(256): s = s + chr(i)    s = s*4    t0 = time.time()    qs = quote(s)    uqs = unquote(qs)    t1 = time.time()    if uqs != s:        print 'Wrong!'    print `s`    print `qs`    print `uqs`    print round(t1 - t0, 3), 'sec'def reporthook(blocknum, blocksize, totalsize):    # Report during remote transfers    print "Block number: %d, Block size: %d, Total size: %d" % (        blocknum, blocksize, totalsize)# Test programdef test(args=[]):    if not args:        args = [            '/etc/passwd',            'file:/etc/passwd',            'file://localhost/etc/passwd',            'ftp://ftp.python.org/pub/python/README',##          'gopher://gopher.micro.umn.edu/1/',            'http://www.python.org/index.html',            ]        if hasattr(URLopener, "open_https"):            args.append('https://synergy.as.cmu.edu/~geek/')    try:        for url in args:            print '-'*10, url, '-'*10            fn, h = urlretrieve(url, None, reporthook)            print fn            if h:                print '======'                for k in h.keys(): print k + ':', h[k]                print '======'            fp = open(fn, 'rb')            data = fp.read()            del fp            if '\r' in data:                table = string.maketrans("", "")                data = data.translate(table, "\r")            print data            fn, h = None, None        print '-'*40    finally:        urlcleanup()def main():    import getopt, sys    try:        opts, args = getopt.getopt(sys.argv[1:], "th")    except getopt.error, msg:        print msg        print "Use -h for help"        return    t = 0    for o, a in opts:        if o == '-t':            t = t + 1        if o == '-h':            print "Usage: python urllib.py [-t] [url ...]"            print "-t runs self-test;",            print "otherwise, contents of urls are printed"            return    if t:        if t > 1:            test1()        test(args)    else:        if not args:            print "Use -h for help"        for url in args:            print urlopen(url).read(),# Run test program when run as a scriptif __name__ == '__main__':    main()

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?