无法抓取数据

时间:2018-10-27 16:56:51

标签: google-apps-script web-scraping html-parsing

我刚开始使用Google Apps脚本。由于最佳编码实践建议尽量使用尽可能少的工作表公式,因此我尝试使用GAS Parser进行网页抓取,然后将数据推送到电子表格中。

在我的工作表中,使用以下公式返回的数据表正是我在GAS中寻找的数据。

=IMPORTHTML("https://finance.yahoo.com/quote/BOO.L/history?p=BOO.L", "table", 1)

两个问题herehere相似,但是尝试这些方法也失败了。似乎几乎没有得到完整的页面内容,因为当我在下面的代码后在Logger.log()中查看数据时,没有得到与所需页面相似的任何内容。

UrlFetchApp.fetch(url).getContentText();

因为运行公式似乎可以完美地获取数据,所以我只能假设自己的代码有问题,而无法确定问题出在哪里。这是到目前为止我尝试过的代码;

function scrapeData() {
var url = "https://finance.yahoo.com/quote/BARC.L/history?p=BARC.L";
var fromText = '<td class="Py(10px) Ta(start) Pend(10px)"><span>';
var toText = '</span></td>';
var content = UrlFetchApp.fetch(url).getContentText();
var scraped = Parser
          .data(content)
          .from(fromText)
          .to(toText)
          .iterate();

Logger.log(scraped)
}

非常感谢任何指导。

1 个答案:

答案 0 :(得分:1)

  • 您要使用Google Apps脚本从URL中检索值并将其放入电子表格。

如果我的理解是正确的,那么该修改如何?我认为您的情况有几个答案。因此,请将此视为其中之一。

修改点:

  • 为了检索表,我使用了ParserXmlService
    1. 使用Parser将表作为字符串值检索。
    2. 使用XmlService解析表。我认为XmlService使我们可以轻松地分析表格。

XmlService是XML的强大分析工具。因此,当可以将其用于HTML时,它使我们可以更轻松地从HTML检索值。但是,最近,XmlService无法直接解析最多的HTML。所以我总是使用此流程。

修改后的脚本:

function scrapeData() {
  // Retrieve table as a string using Parser.
  var url = "https://finance.yahoo.com/quote/BOO.L/history?p=BOO.L";
  // var url = "https://finance.yahoo.com/quote/BARC.L/history?p=BARC.L";
  var fromText = '<div class="Pb(10px) Ovx(a) W(100%)" data-reactid="30">';
  var toText = '<div class="Mstart(30px) Pt(10px)"';
  var content = UrlFetchApp.fetch(url).getContentText();
  var scraped = Parser.data(content).from(fromText).to(toText).build();

  // Parse table using XmlService.
  var root = XmlService.parse(scraped).getRootElement();
  // Retrieve header
  var headerTr = root.getChild("thead").getChildren();
  var res = headerTr.map(function(e) {return e.getChildren().map(function(f) {return f.getValue()})});
  var len = res[0].length;
  // Retrieve values
  var valuesTr = root.getChild("tbody").getChildren();
  var values = valuesTr.map(function(e) {return e.getChildren().map(function(f) {return f.getValue()})})
  .map(function(e) {return e.length == len ? e : e.concat(Array.apply(null, new Array(len - e.length)).map(String.prototype.valueOf,""))});
  Array.prototype.push.apply(res, values);

  // Put the result to the active spreadsheet.
  var ss = SpreadsheetApp.getActiveSheet();
  ss.getRange(1, 1, res.length, res[0].length).setValues(res);
}

注意:

  • 在运行此修改后的脚本之前,请安装Parser的GAS库。
  • 在我的环境中,我可以确认修改后的脚本同时适用于p=BOO.Lp=BARC.L。我无法确认其他人。因此,当您尝试其他脚本时,如果发生错误,请修改脚本。

参考:

如果这不是您想要的,对不起。