C++ QT有道翻译 爬虫 分析 破解

"本文介绍了如何使用Firefox浏览器的开发者工具抓包有道翻译的请求,并通过C++QT模拟POST请求进行翻译。在分析过程中,发现了salt和sign参数的变化规律,通过MD5加密生成这两个参数。代码示例展示了如何构造请求数据并发送,但注意到去掉URL的"_o"后,翻译结果可能不准确。此外,即使salt和sign为0也能获取翻译结果,但质量下降。"
摘要由CSDN通过智能技术生成

编程工具:C++ QT

浏览器+分析工具:Firefox

打开有道翻译首页,任意输入一句中文,按F12进入DEBUG模式,点击翻译按钮后按以下截图步骤操作

 得到提交的表单数据

再重复点击几次翻译按钮,可以发现表单数据的salt、sign、lts这几个参数是变化的

点击”调试器“按钮,来到调试页面,按CTRL+SHIFT+F,输入”sign“进行搜索

 

 发现一个sign 的md5值,如果不知道是哪个,可以一个个点击进去查看,必要的时候下断点,再点击翻译试试看是否会被断下,可以断下的话就很大可能是要找的sign值了。

 以下是截取的部分JS代码:

var r = function (e) {
    var t = n.md5(navigator.appVersion),        //获取浏览器版本,转换为MD5
    r = '' + (new Date).getTime(),              //获取当前时间
    i = r + parseInt(10 * Math.random(), 10);    //当前时间尾部加上随机数
    return {
      ts: r,                    //当前时间
      bv: t,                    //版本信息MD5值
      salt: i,                  //加上随机数后的时间
      sign: n.md5('fanyideskweb' + e + i + 'Y2FYu%TNSbMCxc3t2u^XT')      //sign值
    }
  };

用C++ QT代码实现,其中原网址应为 “https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule” ,需去掉” translate_o “后面的”_o“,否则会出错,具体代码如下:

void Test::YouDaoFanYi()
{
        myurl = "https://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"; 
	QDateTime time = QDateTime::currentDateTime();  //获取当前时间 
	qint64 t= time.toMSecsSinceEpoch(); 
	string lts= QString::number(t).toStdString();  
	qsrand(t);  //置随机种子
	string salt = lts + QString::number(qrand() % 10).toStdString(); //当前时间+随机数
	QString s,str;
	str = "根据调查,超过90%的同学表示在假期中自身存在拖延";
	s.clear();
s.append("fanyideskweb").append(str).append(QString::fromStdString(salt)).append("Y2FYu%TNSbMCxc3t2u^XT");
        
        //计算sign 的 MD5值
	MD5 md5 = MD5(s.toStdString());
	string youdao_sign = md5.outstr(32).c_str();
	//string youdao_sign = md5Str.toStdString();
	//qDebug() << md5Str;
	//qDebug() << QString::fromStdString(youdao_sign);
	data.clear();
	data.append("i=");
	data.append(MyURLencode(str));
	data.append("&from=");
	data.append("AUTO");
	data.append("&to=");
	data.append("AUTO");
	data.append("&smartresult=dict&client=fanyideskweb&salt=");

	data.append(salt);
	data.append("&sign=");

	data.append(youdao_sign);
	data.append("&lts=");  
	data.append(lts);  
	data.append("&bv=e2a78ed30c66e16a857c5b6486a1d326&doctype=json&version=2.1&keyfrom=fanyi.web&action=FY_BY_CLICKBUTTION");
}

需加入 “Content_Type” 、 “Cookie” 、 “User_Agent” 这几个请求头信息。

void YoudaoTranslation::on_pushButton_2_clicked()
{
    Test test;
    test.YouDaoFanYi();

    QNetworkRequest request;
    request.setUrl(QUrl(QString::fromStdString(test.myurl)));

    request.setRawHeader("Content_Type", "application/x-www-form-urlencoded; charset=UTF-8");
    request.setRawHeader("Cookie", "YOUDAO_MOBILE_ACCESS_TYPE=1; OUTFOX_SEARCH_USER_ID=-435057197@10.169.0.102; OUTFOX_SEARCH_USER_ID_NCOO=825663831.7448548; fanyi-ad-id=113723; fanyi-ad-closed=1; YOUDAO_FANYI_SELECTOR=ON; JSESSIONID=aaaIQOEW249b2frXGYgSx; ___rl__test__cookies=1627909716667; SESSION_FROM_COOKIE=fanyiweb");
    request.setRawHeader("Sec-Fetch-Mode","cors");
    request.setRawHeader("User_Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0");

    //2. 创建一个管理器
    QNetworkAccessManager* manager = new QNetworkAccessManager(this);
    //3. 连接请求结束信号
    QEventLoop* loop = new QEventLoop;
    QTimer timer;
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(youdaoreply(QNetworkReply*)));
    connect(manager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
    connect(&timer, SIGNAL(timeout()), loop, SLOT(quit()));

    //4. 发送post请求
    manager->post(request, QString::fromStdString(test.data).toLatin1());

    timer.start(5000);
    loop->exec();

    if (timer.isActive())
    {
        timer.stop();
        //qDebug() << "连接成功!";
    }
    else
    {
        QMessageBox::warning(NULL, QObject::tr("错误"), QObject::tr("网络链接超时!"));
        //qDebug() << "网络链接超时!";

    }

    delete loop;
    delete manager;
    ui.textdisplay->setText(return_str);
}

以下槽函数,处理返回的数据

void YoudaoTranslation::youdaoreply(QNetworkReply* reply)
{
    if (reply->error() == QNetworkReply::NoError) {   //判断是否请求成功
        QString all = reply->readAll();   //读出返回数据
        //qDebug() << all;  
        QString res = youdaoregex(all);   //解析出翻译结果
        
        return_str = res;
        //qDebug() << return_str;
        reply->deleteLater();
    }
    else {
        //qDebug() << reply->errorString() << " error " << reply->error();
        QMessageBox::warning(NULL, QObject::tr("错误"), reply->errorString() + "\r\n" + "error code: " + QString::number(reply->error()));
    }
}

正则解析函数,获取需要的内容:

QString YoudaoTranslation::youdaoregex(const QString& qstr) {   //正则解析函数
    string ans;
    string str = qstr.toStdString();
    string pattern = "\"tgt\":\"(.+?)\"\\}";
    regex e("\\[\\[(.*)\\]\\]");
    regex r(pattern);
    smatch m;
    regex_search(str, m, e);

    string temp = m[1];
    auto res = vector<string>(9);
    sregex_iterator pos(temp.cbegin(), temp.cend(), r), end;
    for (; pos != end; ++pos) {
        res.push_back(pos->str(1));
    }

    for (int i = 9; i < res.size(); i++)
    {
        ans = ans + res[i] ;
    }

    return QString::fromStdString(ans);
}

经验证,对比官方网页翻译结果会有差异,官方网页翻译结果更准确,可能是由于网址 “https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule” ,去掉”_o“后,缺失了相关功能。

以及可以发现 表单数据中的salt和sign值即使为0也可以获得翻译结果,只是翻译结果不是很理想。

这些差异原因有待后续分析。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xpz84

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值