标签:
对下面这段代码做分析
import urllib params = urllib.urlencode({‘wd‘: ‘python‘}) f = urllib.urlopen("http://www.baidu.com/s?%s" % params) print f.read()
这是一段简单读取url内容的代码
此处最关键的是urlopen,通过查看,可以看到urlopen的代码如下
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)
通过一个FancyURLopener的opener实例,因为这里没有proxies参数,所以调用到opener = FancyURLopener()这一句。
然后返回opener.open(url),绑定到f实例上。在这里,有两个关键,一个是opener实例,一个是open方法。
def open(self, fullurl, data=None): """Use URLopener().open(file) instead of open(file, ‘r‘).""" fullurl = unwrap(toBytes(fullurl)) # percent encode url, fixing lame server errors for e.g, like space # within url paths. fullurl = quote(fullurl, safe="%/:=&?~#+!$,;‘@()*[]|") if self.tempcache and fullurl in self.tempcache: filename, headers = self.tempcache[fullurl] fp = open(filename, ‘rb‘) return addinfourl(fp, headers, fullurl) urltype, url = splittype(fullurl) if not urltype: urltype = ‘file‘ if urltype in self.proxies: proxy = self.proxies[urltype] urltype, proxyhost = splittype(proxy) host, selector = splithost(proxyhost) url = (host, fullurl) # Signal special case to open_*() else: proxy = None name = ‘open_‘ + urltype self.type = urltype name = name.replace(‘-‘, ‘_‘) if not hasattr(self, name): if proxy: return self.open_unknown_proxy(proxy, fullurl, data) else: return self.open_unknown(fullurl, data) try: if data is None: return getattr(self, name)(url) else: return getattr(self, name)(url, data) except socket.error, msg: raise IOError, (‘socket error‘, msg), sys.exc_info()[2]
open通过处理url,将name拼接成name = ‘open_‘ + urltype的格式,也就是说,如果是http请求,则name为open_http。在上文那段代码里,最后调用返回的是getattr(self, name)(url),而由于name变成了open_http,则继续调用open_http方法。在这里可以看出,urllib根据你的type来给出不同的方法作处理。
那么又要看看open_http干了什么
标签:
原文地址:http://www.cnblogs.com/alexkn/p/4822707.html