用Python制作mini翻译器的实现示例
作者:Amo Xiang 发布时间:2021-07-26 02:48:09
1. 实例描述
在平时编程的过程中,会经常在网上翻译一些单词,本文使用Python制作一款翻译小工具,不仅可以自己用,还可以嵌入到程序当中。运行程序,效果如下图所示,在文本框输入英文或中文,单击 翻译
按钮即可翻译,并将翻译内容显示在下面的文本框中。单击 保存
按钮将输入内容和翻译内容保存到文本文件中以便日后复习。单击 清空
按钮,将清除文本框中的内容。
2. 技术要点
利用 requests
模块获取 有道词典web
页面的 post
信息,获取需要的内容,通过 tkinter
模块生成窗口界面,使用文件读写方法将内容保存到文本文件中。
2.1 有道词典这样的 JS 混淆加密应该怎么破
嘿嘿嘿,本文需要说说一些爬虫过程中需要斗智斗勇的事情了,这次咱们就来说说关于一些 JS
混淆加密的事。所谓 JS
,就是 JavaScript
,一种前端的脚本语言,一般情况下每个网站都需要 JS
来做一些数据交互,页面渲染等一些异步操作。当然,对于反爬的人来说,JS
的用处还可以用来对一些数据进行加密。
今天咱们就以有道词典这个在线翻译的网站为例,看看他们是如何加密请求数据的,以及笔者是如何通过 Python
模拟请求从而获得关键数据的。
点击 此处 打开有道翻译的网站:
输入中文然后点击翻译按钮就会翻译出来英文,比如:
接着我们打开开发者工具,按下 F12
来抓一下数据,当我们点击翻译的时候,可以看到有了一个请求:
点进去看可以发现,POST
请求的地址是:
http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
我们再来看一下请求过去携带的参数是啥:
可以看到,还是需要挺多参数的,其中的 i
就是我们要翻译的内容,那简单啊~想要得到翻译后的数据,那么我们直接把请求头和所需参数的值复制一下,然后用 requests
请求一波不就搞定了?运行一波,返回的是错误码。
我们再点多几次翻译按钮,然后就可以看到有多次请求。
可以发现,每一次的请求中的 salt
、sign
、lts
、bv
参数是会一直变化的。
我们回到NetWork
,我们看到 Initiator
这一栏,可以看到它请求到了 fanyi.min.js:1
这个 js 文件。
我们就点 fanyi.min.js:1
进去看看,牛的一比,直接看不懂…还好,左下角有一个 {}
,可以点一下,发现有惊喜,直接帮我们把压缩的 js
代码格式化。
牛逼不,行号都给我们显示出来了,不过到了这里,依然懵逼,我们还是不知道怎么拿到 salt
、sign
、lts
、bv
这些参数的值…咋办?恩,Chrome
浏览器的打断点功能在这个时候就要派上用场。那么如何使用断点功能呢,我们看到 Chrome
的右边是这样的:
看到这个 XHR/fetch BreakPoints
没,在这里我们可以添加 url
,根据请求这个 url
打断点。而我们要打的断点就是一开始获取到的请求 url
:
http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
点击 XHR/fetch BreakPoints
右边的 +
号,然后把链接复制进去:
这时候再点击翻译按钮,突然,你的屏幕一灰,表示好事将近,我们成功打上了断点,也就是说,现在我们可以在请求之前做一些骚操作。
这时候我们将右边的 Call Stack
展开,点 t.translate
进去:
这些,就是我们在点击翻译按钮之后,会调用到 js
里面的方法,从这里下手,来寻找参数是被如何加密的,
3. 代码实现
用Python制作mini翻译器的具体步骤如下:
首先安装 requests
模块。使用 pip
命令安装,命令如下:
pip install --user -i http://pypi.douban.com/simple --trusted-host pypi.douban.com requests
导入相关模块,代码如下。
import tkinter as tk
import requests
import time
import hashlib
import random
定义翻译函数,代码如下。
def get_ts():
"""
获取时间戳
:return: 时间
"""
return str(int(time.time() * 1000))
def get_bv():
"""
获取app版本 并通过md5加密
:return: 加密后的字符串
"""
navigator_appVersion = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3' \
'904.108 Safari/537.36'
m = hashlib.md5()
m.update(navigator_appVersion.encode('utf-8'))
return m.hexdigest()
def get_salt(ts):
return str(ts) + str(int(random.random() * 10))
def get_sign(salt):
str1 = text1.get() # 定义一个变量,用来接收输入文本框的值
str_data = 'fanyideskweb' + str1 + salt + ']BjuETDhU)zqSxf-=B#7m'
m = hashlib.md5()
m.update(str_data.encode('utf-8'))
return m.hexdigest()
def get_form_data():
str1 = text1.get() # 定义一个变量,用来接收输入文本框的值
ts = get_ts()
salt = get_salt(ts)
form_data = {
'i': str1,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': str(salt),
'sign': get_sign(salt),
'ts': ts,
'bv': get_bv(),
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_CLICKBUTTION',
}
return form_data
# 定义翻译函数
def translate():
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Referer': 'http://fanyi.youdao.com/',
'Cookie': 'OUTFOX_SEARCH_USER_ID_NCOO=173326173.72226533; OUTFOX_SEARCH_USER_ID="-1202396372@10.108.160.18"; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abcAjF-mxbKFQ_48uyLpx; __guid=204659719.1682486053682624500.1597281254731.5474; monitor_count=2; ___rl__test__cookies=1597285713766'
}
response = requests.post(url=url, data=get_form_data(), headers=headers)
if response.status_code == 200:
result = response.json()
translate_result = result['translateResult'][0][0]['tgt']
text2.delete(1.0, "end") # 清空输出文本框
text2.insert('end', translate_result) # 将翻译结果添加到输出文本框中
定义写入文本 txt
的函数,代码如下。
# 定义写入文本txt的函数
def write():
f1 = open('translate.txt', 'a+')
f1.write(text1.get() + ',' + text2.get(0.0, tk.END))
定义清空文本框的函数,代码如下。
# 定义清空文本框的函数
def delete():
text1.delete(0, "end") # 从第一行清除到最后一行
text2.delete(1.0, "end")
窗口界面设计,代码如下。
if __name__ == '__main__':
window = tk.Tk() # 创建window窗口
window.wm_attributes("-topmost", 1) # 置顶
window.title("AmoXiang mini翻译器") # 定义窗口名称
window.resizable(width=False, height=False) # 决定框体大小是否能够调整
text1 = tk.Entry(window, width=80, bg='whitesmoke') # 在窗体上添加一个输入文本框,并设置尺寸和颜色
text2 = tk.Text(window, height=18, bg='lightgrey') # 在窗体上添加一个输出文本框,并设置尺寸和颜色
text1.grid(row=0, sticky="W", padx=1)
text2.grid(row=1)
# 添加一个按钮,用于触发翻译功能
t_button = tk.Button(window, text='翻译', relief=tk.RAISED, width=8, height=1, font='宋体', bg='red', fg='white',
command=translate)
# 添加一个按钮,用于触发清空输入文本框
button1 = tk.Button(window, text='保存', font='宋体', relief=tk.RAISED, width=8, height=1, command=write)
# 添加一个按钮,用于触发清空输出文本框
button2 = tk.Button(window, text='清空', font='宋体', relief=tk.RAISED, width=8, height=1, command=delete)
# 添加背景图片
image_file = tk.PhotoImage(file='amo.gif')
label = tk.Label(window, image=image_file)
# 完成界面布局,设置各个控件的位置
t_button.grid(row=0, column=1, padx=2)
button1.grid(row=0, column=2, padx=2)
button2.grid(row=0, column=3, padx=2)
label.grid(row=1, column=1, columnspan=3)
tk.mainloop()
来源:https://blog.csdn.net/xw1680/article/details/107972732
猜你喜欢
- 前言虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Req
- 功能介绍 (需要版本5.0.45)大数据操作ORM性能瓶颈在实体转换上面,并且不能使用常规的Sql去实现当列越多转换越慢,SqlSugar将
- 语法: text-overflow : clip | ellipsis 参数: clip : 不显示省略标记(...),而是简单的裁切 el
- 这是我在做的一个游戏的半成品,整理了一下发出来.原理:通过更新变换矩阵来记录转动(函数remx()).利用矩阵计算出转动后的正方体顶点坐标,
- 我就废话不多说,直接上代码吧!# -*- coding: utf-8 -*-import cv2import numpy as npfrom
- 在 MySQL 中,EXPLAIN 命令是一种非常重要的查询优化工具,它可以帮助我们分析 SQL 查询语句的执行计划,以及如何优化它们。在使
- 支持聚合函数的方法:提到聚合函数,首先我们要知道的就是这些聚合函数是不能在django中单独使用的,要想在django中使用这些聚合函数,就
- 本文实例讲述了python中反射用法。分享给大家供大家参考。具体如下:import sys, types,newdef _get_mod(m
- JavaScript Date.toDateString()方法返回一个Date对象的人类可读形式的日期部分。语法Date.to
- 首先,项目结构如下:想要让导航栏、侧边栏变为公共页面,则要在App.vue页面中加入。假设已经有了Header.vue和Left.vue,这
- 1.命令介绍最近学习并使用了一个python的内置函数dir,首先help一下:>>> help(dir)Help on
- 前言最近有网友私信我,问如何把多张图片合成一张马赛克图片的样子说是女儿从出生到现在,所有的照片,大概有上百张,所以想使用这些照片合成一张,当
- 第一步 去高德地图开放平台申请密钥 高德地图开放平台第二部 在vue-cli项目目录结构 里面多了config文件夹和
- 概要在前面章节我们为主页定义了一个简单的模板,部分尚未实现的模块如用户或帖子等使用模拟的对象作为临时占位。本章我们将看到如何利用
- 锚点是“top”,可以放在页面的任何位置,一般是页首。程序就是对锚点出现的判断,我设置的数值是4,意思是出现4个动态数据就出现一个锚点,少于
- 运行时请在其目录下添加user.txt passwd.txt两文件。否则会报错。程序没有加异常处理。代码比较挫.....#coding:ut
- 环境cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@l
- 一、自定义数据集现有数据如下:5个文件夹,每个文件夹是神奇宝贝的一种。每个图片形状、大小、格式不一。我们训练CNN的时候需要的是tensor
- 说明MySql社区版从5.7.11开始支持基于表的数据加密方案,模块名为keyring_file,支持加密整张表。这种是加密方式其实是基于文
- 通过python的os模块获取windows或者linux主机名的通用函数。#!/usr/bin/env python #cod