目标网站:https://fanyi.baidu.com/
需求:实现英汉互译
案例分析
1、分析网站加载方式
动态加载,目标 url:https://fanyi.baidu.com/v2transapi?from=en&to=zh
2、分析请求方式
post(携带 data 参数)
// 英译汉还是汉译英
from: en
to: zh
query: hello // 查询的内容,变化的,可以决定
transtype: realtime // 没有变化
simple_means_flag: 3 // 没有变化
sign: 54706.276099 // 会变化,⼀个单词⼀个数据
token: e1aca5af9de730135e0dba1cea1af143 // 没有变化
domain: common // 没有变化
ts: 1687238388787 // 时间戳
多抓几个包看数据变化
会产生变化并且必不可少的参数:sign 加密字段
3、根据加密字段找和它相关的 js 文件
按 F12 打开开发者工具,找到 Search,点击
4、在搜索框输入加密参数后,按回车
5、寻找与加密参数相关的 js 文件
6、给所有看起来和加密参数相关的都打上断点
7、加好所有断点后,重新输入内容进行翻译,查看跳转位置的代码是否是需要的代码
8、找到了 post 需要携带的相关参数后,新建一个 Js 文件,将找到的数据复制进去
// baidu.js
// 定义了一个函数,传递的参数是需要翻译的内容
function b(e){
// 返回数据
return {
from: b.fromLang,
to: b.toLang,
query: e,
transtype: i,
simple_means_flag: 3,
sign: w(e),
token: window.common.token,
domain: x.getCurDomain(),
ts: +new Date
}
}
console.log(b('hello'))
9、运行后报错
transtype: i,
^
ReferenceError: i is not defined
10、找到浏览器中传递的数据,根据第2步的分析,调整代码
11、调整后的代码
// baidu.js
// 定义了一个函数,传递的参数是需要翻译的内容
function b(e){
// 返回数据
return {
from: 'en',
to: 'zh',
query: e,
transtype: 'realtime',
simple_means_flag: 3,
sign: w(e),
token: 'e1aca5af9de730135e0dba1cea1af143',
domain: 'common',
ts: +new Date
}
}
console.log(b('hello'))
12、运行后报错
sign: w(e),
^
ReferenceError: w is not defined
13、需要到浏览器中寻找 w 函数
14、将跳转后的函数代码复制下来
15、将复制的代码粘贴到 Js 文件中,给函数添加上函数名称
// baidu.js
function w(t) {
var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
if (null === i) {
var a = t.length;
a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))
} else {
for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, l = s.length, u = []; c < l; c++)
"" !== s[c] && u.push.apply(u, function(t) {
if (Array.isArray(t))
return e(t)
}(o = s[c].split("")) || function(t) {
if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])
return Array.from(t)
}(o) || function(t, n) {
if (t) {
if ("string" == typeof t)
return e(t, n);
var r = Object.prototype.toString.call(t).slice(8, -1);
return "Object" === r && t.constructor && (r = t.constructor.name),
"Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0
}
}(o) || function() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}()),
c !== l - 1 && u.push(i[c]);
var p = u.length;
p > 30 && (t = u.slice(0, 10).join("") + u.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + u.slice(-10).join(""))
}
for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = window[d] || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
var _ = t.charCodeAt(v);
_ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),
g[y++] = _ >> 18 | 240,
g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,
g[y++] = _ >> 6 & 63 | 128),
g[y++] = 63 & _ | 128)
}
for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)
b = n(b += g[x], w);
return b = n(b, k),
(b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
"".concat((b %= 1e6).toString(), ".").concat(b ^ f)
}
// 定义了一个函数,传递的参数是需要翻译的内容
function b(e){
// 返回数据
return {
from: 'en',
to: 'zh',
query: e,
transtype: 'realtime',
simple_means_flag: 3,
sign: w(e),
token: 'e1aca5af9de730135e0dba1cea1af143',
domain: 'common',
ts: +new Date
}
}
console.log(b('hello'))
16、运行后报错
for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = window[d] || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
^
ReferenceError: r is not defined
17、分析 r 为一个值,可以给 r 赋值为 null
// baidu.js
var r = null
18、运行后报错
for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = window[d] || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
^
ReferenceError: window is not defined
19、到浏览器中查看 window 是什么
20、获取到 window[d] 的值后,多次重新输入翻译内容,再运行确定值是否是固定的
方式一:
鼠标悬停显示
方式二:
在控制台打印
21、确定 window[d] 为固定值后,将 Js 代码中的 window[d] 直接替换为固定值
// baidu.js
var r = null
function w(t) {
var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
if (null === i) {
var a = t.length;
a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))
} else {
for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, l = s.length, u = []; c < l; c++)
"" !== s[c] && u.push.apply(u, function(t) {
if (Array.isArray(t))
return e(t)
}(o = s[c].split("")) || function(t) {
if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])
return Array.from(t)
}(o) || function(t, n) {
if (t) {
if ("string" == typeof t)
return e(t, n);
var r = Object.prototype.toString.call(t).slice(8, -1);
return "Object" === r && t.constructor && (r = t.constructor.name),
"Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0
}
}(o) || function() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}()),
c !== l - 1 && u.push(i[c]);
var p = u.length;
p > 30 && (t = u.slice(0, 10).join("") + u.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + u.slice(-10).join(""))
}
for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = '320305.131321201' || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
var _ = t.charCodeAt(v);
_ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),
g[y++] = _ >> 18 | 240,
g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,
g[y++] = _ >> 6 & 63 | 128),
g[y++] = 63 & _ | 128)
}
for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)
b = n(b += g[x], w);
return b = n(b, k),
(b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
"".concat((b %= 1e6).toString(), ".").concat(b ^ f)
}
// 定义了一个函数,传递的参数是需要翻译的内容
function b(e){
// 返回数据
return {
from: 'en',
to: 'zh',
query: e,
transtype: 'realtime',
simple_means_flag: 3,
sign: w(e),
token: 'e1aca5af9de730135e0dba1cea1af143',
domain: 'common',
ts: +new Date
}
}
console.log(b('hello'))
22、运行后报错
b = n(b += g[x], w);
^
ReferenceError: n is not defined
23、找到函数 n 的来源
24、复制函数 n 的代码
25、将复制的代码粘贴到 Js 文件中
// baidu.js
var r = null
function n(t, e) {
for (var n = 0; n < e.length - 2; n += 3) {
var r = e.charAt(n + 2);
r = "a" <= r ? r.charCodeAt(0) - 87 : Number(r),
r = "+" === e.charAt(n + 1) ? t >>> r : t << r,
t = "+" === e.charAt(n) ? t + r & 4294967295 : t ^ r
}
return t
}
function w(t) {
var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
if (null === i) {
var a = t.length;
a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))
} else {
for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, l = s.length, u = []; c < l; c++)
"" !== s[c] && u.push.apply(u, function(t) {
if (Array.isArray(t))
return e(t)
}(o = s[c].split("")) || function(t) {
if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])
return Array.from(t)
}(o) || function(t, n) {
if (t) {
if ("string" == typeof t)
return e(t, n);
var r = Object.prototype.toString.call(t).slice(8, -1);
return "Object" === r && t.constructor && (r = t.constructor.name),
"Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0
}
}(o) || function() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}()),
c !== l - 1 && u.push(i[c]);
var p = u.length;
p > 30 && (t = u.slice(0, 10).join("") + u.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + u.slice(-10).join(""))
}
for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = '320305.131321201' || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
var _ = t.charCodeAt(v);
_ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),
g[y++] = _ >> 18 | 240,
g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,
g[y++] = _ >> 6 & 63 | 128),
g[y++] = 63 & _ | 128)
}
for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)
b = n(b += g[x], w);
return b = n(b, k),
(b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
"".concat((b %= 1e6).toString(), ".").concat(b ^ f)
}
// 定义了一个函数,传递的参数是需要翻译的内容
function b(e){
// 返回数据
return {
from: 'en',
to: 'zh',
query: e,
transtype: 'realtime',
simple_means_flag: 3,
sign: w(e),
token: 'e1aca5af9de730135e0dba1cea1af143',
domain: 'common',
ts: +new Date
}
}
console.log(b('hello'))
26、运行后返回结果
{
from: 'en',
to: 'zh',
query: 'hello',
transtype: 'realtime',
simple_means_flag: 3,
sign: '54706.276099',
token: 'e1aca5af9de730135e0dba1cea1af143',
domain: 'common',
ts: 1687239404824
}
27、编写 Python 代码
# 百度翻译.py
# 导入 requests 库,用于发送 HTTP 请求和处理 HTTP 响应
import requests
# 导入自定义模块,用于获取 JavaScript 代码生成的字典
from JsReverse import get_js # JsReverse 为文件名,get_js 为函数名
# 输入需要翻译的内容
trs = input('请输入需要翻译的内容')
# 调用 get_js 函数,传入 JavaScript 文件名'baidu.js'、函数名'b'和翻译内容 trs,获取生成的字典
dic = get_js('baidu.js', 'b', trs)
# 判断输入的是中文还是英文
length = len(trs[0].encode('utf-8')) # 第一个字符长度,一个字母长度是为1,汉字是为3
# 英文
if length == 1:
dic['from'] = 'en'
dic['to'] = 'zh'
# 中文
elif length == 3:
dic['from'] = 'zh'
dic['to'] = 'en'
# 打印字典
# print(dic)
# 设置翻译请求的 url
url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'
# 请求头
headers = {
'Acs-Token': '1687238994011_1687238994248_sKfCKQnOqNJPstsgIsKUPaqAYGqQnIFYiRYGiFYQlIQ+uev26ckgDP84N0sc9iBWm9m8CkW2nyiEwf2Nkr+8bGpHXAxRIArLKohyWWLDQsf6T3mPhsnt8wAI2EGbiEU21zkMCz4WHc49JrKS39GQphWRFrR6Rxu32HgHkqnebW3T7XKVJoRr3x55dGur43olklcdMSq7TOpNx9FDNL4i4dYpDyyjBJohySeR1BWbSHqJWo+IdOOFpNNz2ICr2jA3ngsBPByzUlk0Nr2zDVRfGfGeiZaMPd6BQbMLHVrU0cs8PX452MbNggwOVkN8cYPHGaXQOokzUAy13RMZtRRSqREFq+6oAk0evXXiHPAiGRRADoUYiwpYfKmw5k2nTISu5EpqTXOw/RlicgaHqgP+ubTc8EJ4QzCnBLMWDop+04+P0Ntzy0ngGRfdibhJ3ChIHbQQx+Ner2JCsrTlglUYfIT2Cw4VMvdc2ItaV3MAC2dt0cn7NK2ZLK933nMOwspa',
'Cookie': 'BIDUPSID=B7CB7F26DDDA7D98FF29C3EEC2AFEE2E; PSTM=1682489485; BAIDUID=B7CB7F26DDDA7D988547B56FBC007491:FG=1; BAIDUID_BFESS=B7CB7F26DDDA7D988547B56FBC007491:FG=1; ZFY=YlAwfOaBfcP52N:AR2NYPavFtVsbTy8X5ubtZIMWNoqM:C; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1686816274,1686912230,1687238103; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1687238991; ab_sr=1.0.1_ZjFiNjI5YWYyMzkzMjkyNzA1YjkzY2Q0NDdjYjc5MGU3Mzg1NTExNzczODA1YzliOWJlMjhhMzE0NjM0MTY0YjVmNGMxOWM3MTRkYmRjMDBiZGFmZTgwNTNhZGI5OTdlNzFiN2M2ZWIxOTEyZWY2NWEwM2ZiZGE5NzA3YzVmOTYzYjZjNTc4ZWNhZGJmMTA0NDFlNjc5MTJiMzkxMTg0OQ==',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}
# 发送 post 请求,传递数据字典 dic
res = requests.post(url, data=dic, headers=headers)
# 输出结果
print(res.json()['trans_result']['data'][0]['dst'])
# JsReverse.py
# 安装方法:pip install PyExecJs -i https://pypi.tuna.tsinghua.edu.cn/simple
import execjs # 用于执行 JavaScript 代码的库
# 定义函数
def get_js(js_path, fuc_name, func_args):
'''
:param js_path: js代码的文件路径
:param fuc_name: 调用的js函数名称
:param func_args: 传入的参数
:return:
'''
# 1. 读取 js 代码
with open(js_path, 'r', encoding='utf-8') as f:
js_code = f.read()
# 2. 编译 js 代码
cjs = execjs.compile(js_code)
# 3. 执行 js 代码,函数后面跟上一个参数
# print(fuc_name, func_args)
return cjs.call(fuc_name, func_args)
注意
*func_args 和 func_args
*func_args:可变长度参数,接收的数据类型是元组,return cjs.call(fuc_name, func_args) 返回值时需要拆解,循环遍历取值
func_args:只有一个参数时不用加 *
// baidu.js
var r = null
function n(t, e) {
for (var n = 0; n < e.length - 2; n += 3) {
var r = e.charAt(n + 2);
r = "a" <= r ? r.charCodeAt(0) - 87 : Number(r),
r = "+" === e.charAt(n + 1) ? t >>> r : t << r,
t = "+" === e.charAt(n) ? t + r & 4294967295 : t ^ r
}
return t
}
function w(t) {
var o, i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
if (null === i) {
var a = t.length;
a > 30 && (t = "".concat(t.substr(0, 10)).concat(t.substr(Math.floor(a / 2) - 5, 10)).concat(t.substr(-10, 10)))
} else {
for (var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), c = 0, l = s.length, u = []; c < l; c++)
"" !== s[c] && u.push.apply(u, function(t) {
if (Array.isArray(t))
return e(t)
}(o = s[c].split("")) || function(t) {
if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"])
return Array.from(t)
}(o) || function(t, n) {
if (t) {
if ("string" == typeof t)
return e(t, n);
var r = Object.prototype.toString.call(t).slice(8, -1);
return "Object" === r && t.constructor && (r = t.constructor.name),
"Map" === r || "Set" === r ? Array.from(t) : "Arguments" === r || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) ? e(t, n) : void 0
}
}(o) || function() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}()),
c !== l - 1 && u.push(i[c]);
var p = u.length;
p > 30 && (t = u.slice(0, 10).join("") + u.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + u.slice(-10).join(""))
}
for (var d = "".concat(String.fromCharCode(103)).concat(String.fromCharCode(116)).concat(String.fromCharCode(107)), h = (null !== r ? r : (r = '320305.131321201' || "") || "").split("."), f = Number(h[0]) || 0, m = Number(h[1]) || 0, g = [], y = 0, v = 0; v < t.length; v++) {
var _ = t.charCodeAt(v);
_ < 128 ? g[y++] = _ : (_ < 2048 ? g[y++] = _ >> 6 | 192 : (55296 == (64512 & _) && v + 1 < t.length && 56320 == (64512 & t.charCodeAt(v + 1)) ? (_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v)),
g[y++] = _ >> 18 | 240,
g[y++] = _ >> 12 & 63 | 128) : g[y++] = _ >> 12 | 224,
g[y++] = _ >> 6 & 63 | 128),
g[y++] = 63 & _ | 128)
}
for (var b = f, w = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(97)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(54)), k = "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(51)) + "".concat(String.fromCharCode(94)).concat(String.fromCharCode(43)).concat(String.fromCharCode(98)) + "".concat(String.fromCharCode(43)).concat(String.fromCharCode(45)).concat(String.fromCharCode(102)), x = 0; x < g.length; x++)
b = n(b += g[x], w);
return b = n(b, k),
(b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)),
"".concat((b %= 1e6).toString(), ".").concat(b ^ f)
}
// 定义了一个函数,传递的参数是需要翻译的内容
function b(e){
// 返回数据
return {
from: 'en',
to: 'zh',
query: e,
transtype: 'realtime',
simple_means_flag: 3,
sign: w(e),
token: 'e1aca5af9de730135e0dba1cea1af143',
domain: 'common',
ts: +new Date
}
}
console.log(b('hello'))
28、通过 Python 调用 Js代码的结果时,会出现如下错误
解决方案
找到 Python 的安装目录下的 Lib 里的 subprocess.py 文件,将 encoding=None 改为 encoding=‘utf-8’
记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~