0

我正在尝试获取仅在单击侧菜单项后才显示的列表信息。侧边菜单项是一个列表项,当显示我需要的信息时,它的类会发生变化。列表项是:

<li class="treeItem" dataid="1" parentid="0" sportid="HOR"><div class="treeItemText">Horse Racing<div>

当用户单击左侧面板中包含此列表项的“赛马”时,“open”类被添加到该列表项中,然后列表项展开显示生成表格所需的代码

<li class="treeItem open" dataid="1" parentid="0" sportid="HOR" loaded="true"><div class="treeItemText">Horse Racing<div></div></div><div class="loader" style="display: none; "></div><ul class="level1" style="display: block; "><li class="treeItem" dataid="65365" parentid="1" sportid="HOR"><div class="treeItemText">Dundalk<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="79261" parentid="1" sportid="HOR"><div class="treeItemText">Exeter<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="71557" parentid="1" sportid="HOR"><div class="treeItemText">Fairview<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="65428" parentid="1" sportid="HOR"><div class="treeItemText">Happy Valley<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="65433" parentid="1" sportid="HOR"><div class="treeItemText">Kempton<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="71544" parentid="1" sportid="HOR"><div class="treeItemText">Kenilworth<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="68710" parentid="1" sportid="HOR"><div class="treeItemText">Lingfield<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="69378" parentid="1" sportid="HOR"><div class="treeItemText">Summer Cup - Antepost<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="65459" parentid="1" sportid="HOR"><div class="treeItemText">Turffontein Standside<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li><li class="treeItem" dataid="65463" parentid="1" sportid="HOR"><div class="treeItemText">Vaal Sand<div></div></div><div class="loader"></div><div class="checkbox">&nbsp;</div></li></ul></li>

我已经成功(9 小时,在找到基于属性的元素后我遇到了 addClass 的问题)设法使用以下 javascript 将“打开”添加到列表项类

var page = require('webpage').create();
page.open('http://www.bettingworld.co.za/', function (s) {

window.setTimeout(function () { 
    var sports = page.evaluate(function(){
        $( "li:eq(48)" ).addClass( "open" );

        console.log("YYYYYY");
     });

    page.render('page.png');
    console.log(page.content);
    phantom.exit();
}, 60000);

});

并在命令行运行 phantomjs jason:>./phantomjs javaRender.js > new.html(我的互联网连接是通过我的手机,所以我将超时设置为一分钟。)。尽管类已更改,但列表项未打开,并且在输出 (new.html) 中看不到所需的数据。我对 JavaScript 不太熟悉,但假设单击菜单中的项目会导致页面上的一些 JavaScript 执行。我浏览了页面上的javascripts,但有很多,变量名是单个字符(arg!)。我希望虽然没有渲染额外数据的原因是因为我在渲染页面方面做的事情显然是错误的。是这样吗,还是我需要找到单击列表项时执行的javascript?我在点击时看不到对 javascript 的调用“这是我所期望的。

4

1 回答 1

1

确实,onClick,“打开”类已添加到该 li 元素。但这不是唯一的事情!此外,还会进行异步网络请求 (AJAX),请求子菜单的 html/data;他们在加载时显示一个小的微调器 gif。

因此,要在 PhantomJS 中模拟这种行为,您必须实际重新创建该点击。这与您所拥有的相差不远!首先,不是将open类添加到该<li/>元素,而是这样做:

 $( "li:eq(48)" ).click();

这将启动 AJAX 请求以获取子菜单内容。从那里,您需要“等待”加载子菜单元素。有一个名为waitfor.js的 PhantomJS 实用程序正是这样做的:您告诉它等到满足某些条件(在这种情况下,加载子菜单)然后您可以完成您的功能。

所以在你的例子中,它可能看起来像这样:

function waitFor(testFx, onReady, timeOutMillis) {
    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
        start = new Date().getTime(),
        condition = false,
        interval = setInterval(function() {
            if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
                // If not time-out yet and condition not yet fulfilled
                condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
            } else {
                if(!condition) {
                    // If condition still not fulfilled (timeout but condition is 'false')
                    console.log("'waitFor()' timeout");
                    phantom.exit(1);
                } else {
                    // Condition fulfilled (timeout and/or condition is 'true')
                    console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
                    typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
                    clearInterval(interval); //< Stop this interval
                }
            }
        }, 250); //< repeat check every 250ms
};

var page = require('webpage').create();
page.open('http://www.bettingworld.co.za/', function (s) {

    window.setTimeout(function () { 
        var sports = page.evaluate(function(){
            $( "li:eq(48)" ).click()
         });
        waitFor(function() {
            // Check in the page if a specific element is now visible
            return page.evaluate(function() {
                return ($( "li:eq(48)" ).find('.level1').length > 0);
            });
        }, function() {
            // once it's visible, you can exit & spit out any html
            page.render('page.png');
            console.log(page.content);
           console.log("submenu open");
           phantom.exit();
        });    
    }, 60000);

});
于 2013-11-14T00:47:31.910 回答