def urlopen(url, headers={}, data=None, retries=RETRIES, timeout=TIMEOUT):
headers_merged = default_headers.copy()<EOL>for key in headers.keys():<EOL><INDENT>headers_merged[key] = headers[key]<EOL><DEDENT>opener = urllib.request.build_opener(ForbiddenHandler)<EOL>opener.addheaders = [(k, v) for k,v in headers_merged.items()]<EOL>for i in range(retries):<EOL><INDENT>try:<EOL><INDENT>req = opener.open(url, data=data, timeout=timeout)<EOL>encoding = req.headers.get('<STR_LIT>')<EOL>req.data = req.read()<EOL>if encoding == '<STR_LIT>':<EOL><INDENT>req.data = gzip.decompress(req.data)<EOL><DEDENT>elif encoding == '<STR_LIT>':<EOL><INDENT>req.data = zlib.decompress(req.data, -zlib.MAX_WBITS)<EOL><DEDENT>return req<EOL><DEDENT>except OSError:<EOL><INDENT>logger.error(traceback.format_exc())<EOL><DEDENT>except:<EOL><INDENT>logger.error(traceback.format_exc())<EOL><DEDENT><DEDENT>return None<EOL>
打开一个http连接, 并返回Request.

    headers 是一个dict. 默认提供了一些项目, 比如User-Agent, Referer等, 就
    不需要重复加入了.

    这个函数只能用于http请求, 不可以用于下载大文件.
    如果服务器支持gzip压缩的话, 就会使用gzip对数据进行压缩, 然后在本地自动
    解压.
    req.data 里面放着的是最终的http数据内容, 通常都是UTF-8编码的文本.