请问 PHP 采集 Discuz!论坛的帖子,可是论坛开启了 javascript 的防采集功能,怎么办?

2017-03-10 16:39:53 +08:00
 gdtv

问题有点长,希望大家有耐心看。

采集帖子页面的时候,对方服务器会随机返回类似如下的 javascript 代码,这个代码的功能是给当前 url 加上_dsign 参数然后跳转。

<script type="text/javascript">_x0cyY = 'href';function yG(yG_){function _y(yG_){function i(){return getName();}function yG_(){}return i();return yG_}; return _y(yG_);}function getName(){var caller=getName.caller;if(caller.name){return caller.name} var str=caller.toString().replace(/[\s]*/g,"");var name=str.match(/^function([^\(]+?)\(/);if(name && name[1]){return name[1];} else {return '';}}mI='2';W0=function(){'return W0';return 'd';};O8='i';L1=function(){'return L1';return 'e';};_rZ29z = 'assign';function lV(){'lV';function _l(){return '='}; return _l();}function A59(){'A59';function _A(){return '=3'}; return _A();}va8D='n=3';bV=function(){'bV';var _b=function(){return '.'}; return _b();};c0=function(){'c0';var _c=function(){return 'd'}; return _c();};_kbOOO = 'replace';mg=function(){'mg';var _m=function(){return 'm'}; return _m();};dy='d';function uI(){'uI';function _u(){return '6'}; return _u();}_f5116 = window;PM=function(){'return PM';return 'u';};function f5bi(){'return f5bi';return 'd&t'}function G518(){'G518';function _G(){return '96&'}; return _G();}KW='w';OC='t';function iCA4(iCA4_){function sig(){return getName();};return sig();return 'iCA4'}_udLtF = location;function d6(){'return d6';return '_'}function g6(g6_){function b(){return getName();};return b();return 'g6'}k2=function(){'k2';var _k=function(){return 'h'}; return _k();};W74=function(W74_){'return W74';return W74_;};uC1a=function(){'return uC1a';return 'fb8';};_udLtF[_x0cyY]=(function(){'return pGmD';return '/fo'})()+(function(){'return Bz';return (function(){return 'r';})();})()+PM()+mg()+bV()+(function(){'return HaA5';return 'php'})()+(function(wwP_){return (function(wwP_){return wwP_;})(wwP_);})('?m')+(function(){'return Xz';return 'o'})()+dy+lV()+(function(){'return fU';return 'v'})()+O8+L1()+KW+OC+k2()+(function(){'return aV';return (function(){return 'r';})();})()+'ea'+f5bi()+yG('Mz')+c0()+A59()+mI+(function(){'return M33';return '7'})()+G518()+d6()+W0()+iCA4('qHs8')+va8D+g6('xf')+uI()+W74('e3')+uC1a();_f5116[_x0cyY]=(function(){'return pGmD';return '/fo'})()+(function(){'return Bz';return (function(){return 'r';})();})()+PM()+mg()+bV()+(function(){'return HaA5';return 'php'})()+(function(wwP_){return (function(wwP_){return wwP_;})(wwP_);})('?m')+(function(){'return Xz';return 'o'})();</script>

PS :不是我没格式化,是服务器返回就是这样的。
因为这段 js 代码很复杂,我无法用 php 来解析以便获取到帖子的新的 url 。所以只好借助 PhantomJS 。

目前我的解决方法是,用 PhantomJS 创建一个 webserver ,这个 webserver 运行这段 js 代码并获取跳转后的新 url 返回给 php 。 webserver 代码如下:

var page = require('webpage').create();
var server = require('webserver').create();
var service = server.listen('127.0.0.1:22222', function (request, response) {
    var expectedContent = request.post; //接收要解析的 js 代码
    var expectedLocation = 'http://www.test.com/';
    var t;

    //获取取跳转后的新地址
    page.onNavigationRequested = function(url, type, willNavigate, main) {
        if(url!=expectedLocation){
            response.statusCode = 200;
            response.headers = {
                'Cache': 'no-cache',
                'Content-Type': 'text/html;charset=utf-8'
            };
            response.write(url);
            response.close();
            clearTimeout(t);
        }

    };

    page.setContent(expectedContent, expectedLocation); //将接收到的 js 代码放到页面里执行
    
    //如果跳转失败,或者接收到的 js 代码没有跳转功能,等待 1 秒后强制关闭
    //问题出在这里,如果提交的 js 代码跳转不成功,这里会浪费 1 秒钟才会结束,有什么办法改善一下呢?
    t = setTimeout(function(){
        console.log('no redirect');
        response.statusCode = 200;
        response.headers = {
            'Cache': 'no-cache',
            'Content-Type': 'text/html;charset=utf-8'
        };
        response.write('');
        response.close();
    },1000);
});

如果 php 采集到的帖子是一段 js 跳转代码,就将这段代码 post 到 webserver 里,让 webserver 解析 js 然后返回跳转后的 url 。

问题:
如果提交的 js 代码跳转不成功,或者提交了错误的或者没有跳转功能的 js 代码, webserver 会浪费 1 秒钟才会返回响应,有什么办法改善一下呢?
或者有没有其他更好的方法可以获取到跳转后的新地址?

2293 次点击
所在节点    PHP
8 条回复
chairuosen
2017-03-10 16:55:45 +08:00
var str = `<script type="text/javascript">_x0cyY = 'href';function yG(yG_){function _y(yG_){function i(){return getName();}function yG_(){}return i();return yG_}; return _y(yG_);}function getName(){var caller=getName.caller;if(caller.name){return caller.name} var str=caller.toString().replace(/[\s]*/g,"");var name=str.match(/^function([^\(]+?)\(/);if(name && name[1]){return name[1];} else {return '';}}mI='2';W0=function(){'return W0';return 'd';};O8='i';L1=function(){'return L1';return 'e';};_rZ29z = 'assign';function lV(){'lV';function _l(){return '='}; return _l();}function A59(){'A59';function _A(){return '=3'}; return _A();}va8D='n=3';bV=function(){'bV';var _b=function(){return '.'}; return _b();};c0=function(){'c0';var _c=function(){return 'd'}; return _c();};_kbOOO = 'replace';mg=function(){'mg';var _m=function(){return 'm'}; return _m();};dy='d';function uI(){'uI';function _u(){return '6'}; return _u();}_f5116 = window;PM=function(){'return PM';return 'u';};function f5bi(){'return f5bi';return 'd&t'}function G518(){'G518';function _G(){return '96&'}; return _G();}KW='w';OC='t';function iCA4(iCA4_){function sig(){return getName();};return sig();return 'iCA4'}_udLtF = location;function d6(){'return d6';return '_'}function g6(g6_){function b(){return getName();};return b();return 'g6'}k2=function(){'k2';var _k=function(){return 'h'}; return _k();};W74=function(W74_){'return W74';return W74_;};uC1a=function(){'return uC1a';return 'fb8';};_udLtF[_x0cyY]=(function(){'return pGmD';return '/fo'})()+(function(){'return Bz';return (function(){return 'r';})();})()+PM()+mg()+bV()+(function(){'return HaA5';return 'php'})()+(function(wwP_){return (function(wwP_){return wwP_;})(wwP_);})('?m')+(function(){'return Xz';return 'o'})()+dy+lV()+(function(){'return fU';return 'v'})()+O8+L1()+KW+OC+k2()+(function(){'return aV';return (function(){return 'r';})();})()+'ea'+f5bi()+yG('Mz')+c0()+A59()+mI+(function(){'return M33';return '7'})()+G518()+d6()+W0()+iCA4('qHs8')+va8D+g6('xf')+uI()+W74('e3')+uC1a();_f5116[_x0cyY]=(function(){'return pGmD';return '/fo'})()+(function(){'return Bz';return (function(){return 'r';})();})()+PM()+mg()+bV()+(function(){'return HaA5';return 'php'})()+(function(wwP_){return (function(wwP_){return wwP_;})(wwP_);})('?m')+(function(){'return Xz';return 'o'})();</script>
`;
str = str.match(/<script[^>]*>(.*)<\/script>/)[1];
var window={};
var location = window.location = {href:""};
eval(str);
console.log(location.href);
gdtv
2017-03-10 17:47:56 +08:00
@chairuosen 谢谢,不过你的代码只能获取到跳转前的 url ,不能获取到跳转后的 url 。
chairuosen
2017-03-10 17:58:43 +08:00
@gdtv 这段代码只能获取这个 url ,另有跳转的事,就应该是请求这个 url 之后的事了,它也许 301 到别处了
chairuosen
2017-03-10 18:00:39 +08:00
@chairuosen 如果是 301 条的你就 curl -I this_url | grep Location
lecher
2017-03-10 18:04:19 +08:00
js 交给 V8 引擎去解析,拿到 js 再执行就是了。再怎么藏它都得返回给浏览器执行。

还可以上 GitHub 搜一搜,我之前在 GitHub 上面搜到过腾讯图源解密的 js 代码。
gdtv
2017-03-10 18:31:31 +08:00
@chairuosen 这个不是 301 的,如果是 301 就好办了,可惜这个是 js 跳转
ColinZeb
2017-03-10 18:43:20 +08:00
@chairuosen 一楼的代码就是获取跳转后的,你可以试试
gdtv
2017-03-10 18:50:22 +08:00
@chairuosen 不好意思刚才看错了,你的是对的,谢谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/346497

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX