使用PhantomJS处理DOM元素

时间:2017-07-06 14:47:39

标签: javascript node.js parsing dom phantomjs

我想加载网站的完整DOM并稍后处理每个元素。示例代码/测试用例将记录网站的所有标记。

这在普通浏览器中非常有用:

var dom = document.getElementsByTagName('*'),
    i;

for (i in dom)
{
    console.log(dom[i] && dom[i].tagName ? dom[i].tagName : 'invalid');
}

此测试用例记录:

HTML
BODY
DIV
...etc...

这在PHANTOMJS内部无效:

var page = require('webpage').create();

page.open('https://google.com', function ()
{
    var dom = page.evaluate(function ()
        {
            return document.getElementsByTagName('*');
        }),
        i;

    for (i in dom)
    {
        console.log(dom[i] && dom[i].tagName ? dom[i].tagName : 'invalid');
    }
    phantom.exit();
});

由于某种原因,只有第一个对象包含值。因此,此测试用例记录:

HTML
invalid
invalid
...

需要帮助!谢谢

1 个答案:

答案 0 :(得分:1)

来自文档:

  

注意:evaluate函数的参数和返回值必须   是一个简单的原始对象。经验法则:如果可以的话   通过JSON序列化,然后就可以了。

     

闭包,函数,DOM节点等不起作用!

最后,我找到答案......只需在评估方法中准备并返回一个简单的对象。

var page = require('webpage').create();

page.open('https://google.com', function ()
{
    var dom = page.evaluate(function ()
        {
            var temp =  document.getElementsByTagName('*'),
                tempArray = [],
                j;

            for (j in temp)
            {
                tempArray.push(
                {
                    tagName: temp[j].tagName,
                    className: temp[j].className
                });
            }
            return tempArray;
        }),
        i;

    for (i in dom)
    {
        console.log(dom[i] && dom[i].tagName ? dom[i].tagName : 'invalid');
        console.log(dom[i] && dom[i].className ? dom[i].className : 'invalid');
    }
    phantom.exit();
});