使用了免费的百度翻译已经很久了,最近突然发现使用出错,怀疑百度又增加了反爬虫机智,于是花了一点时间整理出最新破解方法。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.zoneyet.util.common.HttpUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
/**
*
* 爬虫技术模拟百度用户,免费百度翻译
*
* <pre>
* Description: 抓包免费百度翻译 (描述类的主要功能)
* </pre>
*
* @author Administrator Created at 2019年3月25日 上午9:55:11
* @version 1.0
*/
public class BaiduTranslateFree {
private static final String URL = "https://fanyi.baidu.com/v2transapi";
private static final Logger log = LoggerFactory.getLogger(BaiduTranslateFree.class);
/**
* 英文:en
* 中文:zh
* 繁体:cht
* 日文:jp
* 德语:de
* 俄语:ru
* 西班牙语:spa
* 韩语:kor
*
* 功能:翻译接口
* @author huang fengge
* @param
* query翻译内容
* from 源语言
* to 目标语言
* @return
* DATA: 2019年3月25日
*/
public static String translate(String query,String from,String to) throws Exception {
String trsResult = "";
String transtype= "translang";
String simple_means_flag = "3";
String sign = "";
String token = "b490060ca5e86c956de1921597c4721f";
try {
ScriptEngineManager m = new ScriptEngineManager();
// 获取JavaScript执行引擎
ScriptEngine engine = m.getEngineByName("JavaScript");
// 执行JavaScript代码
engine.eval(readJSFile());
Invocable inv = (Invocable) engine;
sign = inv.invokeFunction("e", query).toString();
query = query.replaceAll("'", "");
String param =String.format("from=%s&to=%s&query=%s&transtype=%s&simple_means_flag=%s&sign=%s&token=%s", from,to,query,transtype,simple_means_flag,sign,token);
String result = HttpUtil.sendPost(URL, param);
// 结果解码
// result = UnicodeUtils.decoUnicode(result);
log.info(result);
JSONObject jsonObject = JSONObject.fromObject(result);
JSONObject jsonObject2 = JSONObject.fromObject(jsonObject.get("trans_result"));
JSONArray jsonArray = jsonObject2.getJSONArray("data");
JSONObject jsonObject3= jsonArray.getJSONObject(0);
trsResult = jsonObject3.get("dst").toString();
log.info("翻译结果:【"+trsResult+"】");
} catch (Exception e) {
log.info("免费翻译接口异常");
}
return trsResult;
}
/**
* 英文:en
* 中文:zh
* 繁体:cht
* 日文:jp
* 德语:de
* 俄语:ru
* 西班牙语:spa
* 韩语:kor
*/
public static void main(String[] args) {
try {
// ScriptEngineManager m = new ScriptEngineManager();
// // 获取JavaScript执行引擎
// ScriptEngine engine = m.getEngineByName("JavaScript");
// // 执行JavaScript代码
// System.out.println( engine.eval(readJSFile()));
// Invocable inv = (Invocable) engine;
// Object result = inv.invokeFunction("e", "今天天气不错");
// System.err.println(result);
System.err.println(translate("Hello Today is sunny", "auto", "zh"));
} catch (Exception e) {
e.printStackTrace();
}
}
private static String readJSFile() throws Exception {
StringBuffer script = new StringBuffer();
File file = new File("WebRoot\\fanyi\\sign.js");
FileReader filereader = new FileReader(file);
BufferedReader bufferreader = new BufferedReader(filereader);
String tempString = null;
while ((tempString = bufferreader.readLine()) != null) {
script.append(tempString).append("\n");
}
bufferreader.close();
filereader.close();
return script.toString();
}
}
百度在你翻译的任何一个字符都对应了一个Sign,还有对应的token 。这几个值必须是抓包获取的才可以使用,并不是uuid随便生成。
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("User-Agent",getUserAgent());
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
conn.setRequestProperty("Cookie", "BAIDUID=:FG=1; BIDUPSID=98BF6237DC3EB4869DFAB6DA98994033; PSTM=1557041047; MCITY=-268%3A; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BCLID=8568628033192269887; BDSFRCVID=r28OJeC62RlQzjv9dRSVb7HrQ2VmVY6TH6ao0_udLsJWGse1f6cDEG0Pex8g0KubbDIeogKKBeOTHn0F_2uxOjjg8UtVJeC6EG0P3J; H_BDCLCKID_SF=tJIDoIL2JC_3qn5zqROHhRIJhpo-KnLXKKOLV-np3q7keq8CD6r85b-thGrb2xC8KJv7QfD-J4oDqp72y5jH3xFX5fcnBf50-JnKQMJCbfOpsIJMbtDWbT8U5fKL2lOzaKviahoHBMb1DCJDBT5h2M4qMxtOLR3pWDTm_q5TtUt5OCFRj5AaD6JQepJf-K6f5C6q04_8Kb7VKROkeUrHBU4pbt-qJtrvKCjHQDTeLfOaHC3SKlLKQt4YhaonBT5KaK5P-xtKK-J8KqklDxrTXh-kQN3T0PKO5bRiL66DtDTxDn3oyU5qXp0nhG3ly5jtMgOBBJ0yQ4b4OR5JjxonDhOyyGCHtTKtJJCfoKveK5roDR5Rq4QEenjXe-nZKxtqtHrQb4c_bDTfVxOK-6J1KloX3xcpX65nWncKWKJ7bRbdqpc5QnbqDt5B-PO405OT56-O0KJcbRoDshTNhPJvyUD8XnO72jOlXbrtXp7_2J0WStbKy4oTjxL1Db0eBjT2-DA__KI5tfK; delPer=0; PSINO=5; H_PS_PSSID=1459_21113_28518_28768_28722_28964_28835_28585_26350_22159; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; locale=zh; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1557757158,1557793965,1557801060,1557814747; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1557814747; to_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D; from_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");
conn.setRequestProperty("Host", "fanyi.baidu.com");
conn.setRequestProperty("Origin", "https://fanyi.baidu.com");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
最后就可以尽情的使用了,为了防止反爬,可以采取多个账号。
对应的js
function a(r) {
if (Array.isArray(r)) {
for (var o = 0, t = Array(r.length); o < r.length; o++)
t[o] = r[o];
return t
}
return Array.from(r)
}
function n(r, o) {
for (var t = 0; t < o.length - 2; t += 3) {
var a = o.charAt(t + 2);
a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a),
a = '+' === o.charAt(t + 1) ? r >>> a : r << a,
r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a
}
return r
}
var i = null;
function e(r) {
var t = r.length;
t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10))
var u = void 0, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107);
u = null !== i ? i : (i = '320305.131321201' || "") || "";
for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) {
var A = r.charCodeAt(v);
128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)),
S[c++] = A >> 18 | 240,
S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224,
S[c++] = A >> 6 & 63 | 128),
S[c++] = 63 & A | 128)
}
for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++)
p += S[b],
p = n(p, F);
return p = n(p, D),
p ^= s,
0 > p && (p = (2147483647 & p) + 2147483648),
p %= 1e6,
p.toString() + "." + (p ^ m)
}