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 + -
显示快捷键?