Python3 urlopen

#以下介绍是基于Python3.6.4

一. 简介

urllib.request.urlopen()函数用于实现对目标url的访问。
函数定义如下:

def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
            *, cafile=None, capath=None, cadefault=False, context=None):
    global _opener
    if cafile or capath or cadefault:
        if context is not None:
            raise ValueError(
                "You can't pass both context and any of cafile, capath, and "
                "cadefault"
            )
        if not _have_ssl:
            raise ValueError('SSL support not available')
        context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
                                             cafile=cafile,
                                             capath=capath)
        https_handler = HTTPSHandler(context=context)
        opener = build_opener(https_handler)
    elif context:
        https_handler = HTTPSHandler(context=context)
        opener = build_opener(https_handler)
    elif _opener is None:
        _opener = opener = build_opener()
    else:
        opener = _opener
    return opener.open(url, data, timeout)

二. 函数参数介绍

<1>url 参数:目标资源在网路中的位置。可以是一个表示URL的字符串(如:http://www.xxxx.com/);也可以是一个urllib.request对象,详细介绍请跳转

<2>data参数:data用来指明发往服务器请求中的额外的信息(如:在线翻译,在线答题等提交的内容)。HTTP是python中实现的众多网络通信http、https、ftp等协议中,唯一一个 使用data 参数的,也就是说只有打开的是http网址的时候,自定义data参数才会有作用。另外,官方API手册介绍指出:

<2.1> data必须是一个字节数据对象(Python的bytes object)

<2.2>data必须符合标准the standard application/x-www-form-urlencoded format,怎么得到这种标准结构的data呢?使用urllib.parse.urlencode()将自定义的data转换成

标准格式,而这个函数所能接收的参数类型是pyhon中的mapping object(键/值对,如dict) or a sequence of two-element tuples(元素是tuple的列表)。

<2.3>data也可以是一个可迭代的对象,这种情况下就需要配置response对象中的Conten-length,指明data的大小。

<2.4>data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为POST方式发送请求。

<3>cafile、capath、cadefault 参数:用于实现可信任的CA证书的HTTP请求。(基本上很少用)

<4>context参数:实现SSL加密传输。(基本上很少用)

三. 举个栗子

下面这个程序,实现了urlopen()函数的大部分功能,特别是data参数。data自定义,data格式转换,数据的编码encode()和解码decode()。

''' 利用有道翻译进行在线翻译 '''
import urllib.request import urllib.parse import json def traslate(words): #目标URL
targetURL = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null"

#用户自定义表单,words表示的是用户要翻译的内容。这里使用的是dict类型,也可以使用元组列表(已经试过的)。
#coding=utf-8
#Python3.6.4  
'''
利用有道翻译进行在线翻译

'''
import urllib.request
import urllib.parse
import json

def traslate(words):
    #目标URL
    targetURL = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null"

    #用户自定义表单,words表示的是用户要翻译的内容。这里使用的是dict类型,也可以使用元组列表(已经试过的)。
    data = {}
    data['type'] = 'AUTO'
    data['i'] = words
    data['doctype'] = 'json'
    data['xmlVersion'] = '1.8'
    data['keyfrom'] = 'fanyi.web'
    data['ue'] = 'UTF-8'
    data['action'] = 'FY_BY_CLICKBUTTON'
    data['typoResult'] = 'true'

    #将自定义data转换成标准格式
    data = urllib.parse.urlencode(data).encode('utf-8')

    #发送用户请求
    html = urllib.request.urlopen(targetURL, data)

    #读取并解码内容
    rst = html.read().decode("utf-8")
    rst_dict = json.loads(rst)

    return rst_dict['translateResult'][0][0]['tgt']

if __name__ == "__main__":
    print("输入字母q表示退出")
    while True:
        words = input("请输入要查询的单词或句子:\n")
        if words == 'q':
            break
        result = traslate(words)
        print("翻译结果是:%s"%result)