在casper.each中获取子元素

时间:2015-06-18 08:43:34

标签: javascript casperjs

使用CasperJS 1.1和以下代码,我能够从网页中获取有用的DOM html。

casper.each(c.getElementsInfo(xpath), function(casper, element, j) {
    var html = element["html"].trim();
    if(html.indexOf('Phone') > -1) {
        // what should I put here?
    }
});

但是,我想访问&获取元素的子元素。我怎样才能做到这一点?元素的HTML源代码(a.k.a html的值)如下:

循环1

<div class="fields">
                Phone
            </div>
            <div class="values">
                <a href="tel: 12345678">12345678</a> (Mr. Lee)              </div>

循环2

<div class="fields">
                Emergency Phone
            </div>
            <div class="values">
                <a href="tel: 23456789 (Emergency)">23456789 (Emergency)</a>
            </div>

循环3

<div class="fields">
                Opening Hours
            </div>
            <div class="values">
                9:00am-6:30pm(Weekday) /
                Close on Sundays and Public Holidays(Can be booked)(Holiday)
            </div>

循环4

<div class="fields">
                Last Update
            </div>
            <div class="values">
                 11/06/14               </div>

上面的HTML格式错误,并且包含很多空格。

我想要获取的数据是:

  • 电话:12345678
  • 紧急电话:23456789(紧急电话)
  • 营业时间:上午9:00至下午6:30(工作日)/星期日及公众假期休息(可预订)(假日)
  • 最后更新:2014年6月11日

尝试过RegEx,但RegEx过于复杂。

1 个答案:

答案 0 :(得分:1)

我不建议使用正则表达式执行此操作。它可以通过一些选择器轻松完成,但必须在页面上下文(evaluate()回调内部)中完成,因为DOM节点不能传递到外部。

CasperJS提供了一个辅助函数,用于通过始终自动插入的ClientUtils模块,通过XPath与__utils__.getElementsByXPath()匹配DOM节点。该函数的结果是一个数组,因此适用正常的forEach()模式。 DOM节点可以用作上下文节点,用于选择具有el.querySelector(".class")的子元素。

var info = casper.evaluate(function(xpath){
    var obj = {};
    __utils__.getElementsByXPath(xpath).forEach(function(el){
        obj[el.querySelector(".fields").textContent.trim()] = 
            el.querySelector(".values").textContent.trim();
    });
    return obj;
}, yourXPathString);

如果要根据CSS选择器选择元素,请使用以下命令:

var info = casper.evaluate(function(cssSelector){
    var obj = {};
    __utils__.findAll(cssSelector).forEach(function(el){
        obj[el.querySelector(".fields").textContent.trim()] = 
            el.querySelector(".values").textContent.trim();
    });
    return obj;
}, yourCssSelector);