使用 casperJS 从网页中抓取一些链接

Using casperJS to scrape some links from a webpage

我正在使用 casperJS 1.1.2 和 phantomJS 2.1.1 从网页中检索一些链接。我感兴趣的链接在 href 属性中都有字符串 "javascript" ,如下所示:

<td>
<a href="javascript:WebForm_DoPostBackWithOptions(new 
WebForm_PostBackOptions(&quot;ctl00$CenterContent$ctl01&quot;,
&quot;&quot;, true, &quot;&quot;, &quot;&quot;, false,
true))">Species A    
</a></td>
<td>
<a href="javascript:WebForm_DoPostBackWithOptions(new
WebForm_PostBackOptions(&quot;ctl00$CenterContent$ctl02&quot;,
&quot;&quot;, true, &quot;&quot;, &quot;&quot;, false,
true))">Species B   </a></td>
<td><a href="javascript:WebForm_DoPostBackWithOptions(new
WebForm_PostBackOptions(&quot;ctl00$CenterContent$ctl03&quot;,
&quot;&quot;, true, &quot;&quot;, &quot;&quot;, false,
true))">Sepcies C    </a></td>
<td>
<a href="javascript:WebForm_DoPostBackWithOptions(new
WebForm_PostBackOptions(&quot;ctl00$CenterContent$ctl04&quot;,
&quot;&quot;, true, &quot;&quot;, &quot;&quot;, false,
true))">Species D</a></td>
<td>
<a href="javascript:WebForm_DoPostBackWithOptions(new
WebForm_PostBackOptions(&quot;ctl00$CenterContent$ctl05&quot;,
&quot;&quot;, true, &quot;&quot;, &quot;&quot;, false,
true))">Species E    </a></td>

我在 casperJS 中写了一些脚本来抓取所有 href 属性包含 "javascript" 字符串的链接并将其写入文件,如下所示。

var links=[];
var casper = require('casper').create({
  waitTimeout: 10000,
    verbose: true,
    logLevel: 'debug',
    pageSettings: {
        loadImages: false,
        loadPlugins: false
    }
});

var fs = require('fs');

casper.start("https://apps.ams.usda.gov/CMS/", function()
    {
       links = _utils_.getElementsByXPath('.//td/a[contains(@href,"javascript")]');
    });

fs.write("plantVarietyResults.json", links, 'w');


casper.run();

我不明白为什么我的脚本没有正确写入文件链接。

关于 CasperJS 的一些误解以及您的代码中的错误:

  • It's __utils__ and not _utils_.
  • .
  • The page context can be accessed through casper.evaluate.
  • 非原始对象,如 DOM 节点,cannot be passed out of the page context. (and reference)
  • 如果您对 href 感兴趣,那么您必须阅读 DOM 元素中的 href 属性。
  • casper.start是异步的,而fs.write不是,所以你必须把fs.write的调用放在另一个异步函数中,在casper.start之后执行。
  • A JavaScript 对象不会简单地将自身转换为 JSON 字符串。你必须自己做。

下面是一个应该有效的例子(未经测试):

casper.start("https://apps.ams.usda.gov/CMS/", function() {
    var links = this.evaluate(function(){
        return __utils__.getElementsByXPath('.//td/a[contains(@href,"javascript")]')
            .map(function(element){
                return element.href;
            });
    });
    fs.write("plantVarietyResults.json", JSON.stringify(links), 'w');
});

casper.run();

这里有一个稍微短一点的方法:

var x = require('casper').selectXPath;
casper.start("https://apps.ams.usda.gov/CMS/", function() {
    var links = this.getElementsAttribute(x('.//td/a[contains(@href,"javascript")]'), 'href');
    fs.write("plantVarietyResults.json", JSON.stringify(links), 'w');
});

casper.run();