基于urllib网页爬取的翻译小程序

中英互译

python的urllib可谓http操作的神器,可以模仿浏览器的行为提交请求并收到返回的数据。笔者在此利用urllib向百度翻译发送翻译请求并获取翻译结果,演示一下该库的简单用法,小脚本封装后可以在命令行下运行,非常适用于linux。

功能分析

  1. 输入中文或英文,返回翻译结果。

代码实现

  1. urllib发送请求的方法
#!/usr/bin/env python3
from urllib import request, parse
import json
import sys

# 新建请求
requ = request.Request('http://...') # 输入请求的目标网址
# 以post方式提交数据需要对数据转码打包
post_data = parse.urlencode({
    "key": "val",
    # ...
})
# 添加请求头request-header
requ.add_header(key, val) # 请求头可以从浏览器控制台获取,可以多次调用
# 发送请求获取响应数据
with request.urlopen(requ, post_data.encode('utf-8')) as resp
    resp_data = resp.read() # 字节数据,可根据需要解码为字符

以上就是urllib发送请求并获取相应数据的一般方法,下面根据上面的模板向百度翻译发送翻译请求。

  1. 翻译小程序
#!/usr/bin/env python3

from urllib import request, parse
import json
import sys

def show_help():
    print('help...')

def main():
    if len(sys.argv) < 2:
        show_help()
        return
    words = sys.argv[1]
    # post数据结构,query为待查询词汇
    post_data = parse.urlencode({
        "from":"zh",
        "to":"en",
        "query":words,
        # "query":"键盘",
        "transtype":"translang",
        "simple_means_flag":"3"
        })
    requ = request.Request('http://fanyi.baidu.com/v2transapi')
    requ.add_header('Host', 'fanyi.baidu.com')
    requ.add_header('User-Agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) \
        Gecko/20100101 Firefox/50.0')
    requ.add_header('Accept', '*/*')
    requ.add_header('Accept-Language', 'en-US,en;q=0.5')
    requ.add_header('Accept-Encoding', 'en-US,en;q=0.5')
    requ.add_header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
    requ.add_header('X-Requested-With', 'XMLHttpRequest')
    requ.add_header('Referer', r'http://fanyi.baidu.com/translate?aldtype=16047&query=\
        %E5%B8%AE%E5%8A%A9&keyfrom=baidu&smartresult=dict&lang=auto2zh')
    requ.add_header('Content-Length', '78')
    requ.add_header('Cookie', r'BAIDUID=F49EF7F92D1F9D27EBC7CFB34A5EB604:FG=1; BIDUPSID\
        =EB895CEBA4E3BAD19DC355A2ED379DED; PSTM=1481521457; H_PS_PSSID=21764_1456_21085\
        _17001_21554_20928; PSINO=1; locale=zh; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574\
        =1481991435,1481991979; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1481991979; MA\
        NUBANNER=1; from_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E\
        2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D\
        %5D; to_lang_often=%5B%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%\
        22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D; REAL\
        TIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; sideAdClose=17152')
    requ.add_header('Connection', 'keep-alive')
    resp = request.urlopen(requ, post_data.encode('utf-8'))
    print(json.loads(resp.read().decode('utf-8')).get('liju_result').get('tag'))

if __name__ == "__main__":
    main()

此处请求头来源于谷歌浏览器的控制台,并不是所有的都是必须的,读者可自行测试,另外,也可以写一个函数来直接对请求头文本进行自动分割,不需要手动分割。

附录

1. 请求头获取方法

  • 从菜单打开开发者工具(或者直接F12打开)


    打开控制台
  • 打开Network选项


    打开Network
  • 尝试翻译,查看请求头和数据格式


    查看请求头
  • 查看响应数据格式


    查看相应数据结构

    利用json模块可以解析json数据。

2. 请求头文本自动分割方法

def parse_to_array(data_text):
    """Parse header text to tuple array."""
    lines = data_text.splitlines()
    data_array = []
    for l in lines:
        data_array.append(tuple(l.split(':',1)))
    return data_array

def add_request_headers(reqs, headers):
    """Add request header according of headers text."""

    dict_data = parse_to_array(headers)
    for k, v in dict_data:
        reqs.add_header(k, v)

# 用法展示
headers = """
Accept: */*
...
"""
add_request_headers(reqs, headers)

总结

利用该方法可以满足一般的爬取需求,笔者还实现过校园网wifi网页认证的便捷登陆以及校园网流量监控系统,后者还需要结合邮件发送模块实现定期自动发送邮件提醒,有时间写出来交流交流。

你可能感兴趣的:(基于urllib网页爬取的翻译小程序)