无法在Google表格中抓取表格

时间:2018-02-21 16:16:09

标签: google-apps-script google-sheets

this SO questions的帮助下,我试图抓住following website。我想要两队和时间。例如,第一个条目是Chicago |迈阿密|下午12:30,最后一个条目是科罗拉多州Arizona |晚上10:10我的代码如下

function espn_schedule() {
  var url = "http://www.espn.com/mlb/schedule/_/date/20180329";
  var content = UrlFetchApp.fetch(url).getContentText();
  var scraped = Parser.data(content).from('class="schedule has-team-logos align-left"').to('</tbody>').iterate();
  var res = [];

  var temp = [];
  var away_ticker = "";
  scraped.forEach(function(e){
    var away_team = Parser.data(e).from('href="mlb/team/_/name/').to('"').build();
    var time = Parser.data(e).from('a data-dateformat="time1"').to('</a>').build();
    if (away_ticker == "") away_ticker = away_team;
    if (away_team != away_ticker) {
      temp.splice(1, 0, away_ticker);
      res.push(temp);
      temp = [];
      away_ticker = away_team;
      temp.push(time);
    }
  });
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Schedule");
  ss.getRange(ss.getLastRow() + 1, 1, res.length, res[0].length).setValues(res);
}

我收到以下错误:TypeError:无法从undefined中读取属性“length”。 (第42行,文件“代码”)

1 个答案:

答案 0 :(得分:0)

这是一个有效的修改后的解决方案

function espn_schedule() {
  var url = "http://www.espn.com/mlb/schedule/_/date/20180329";
  var content = UrlFetchApp.fetch(url).getContentText();
  var e = Parser.data(content).from('class="schedule has-team-logos align-left"').to('</tbody>').build();
  var res = [];
  //Logger.log(scraped[0])
  var temp = [];
  var away_ticker = "";
    var teams = Parser.data(e).from('<abbr title="').to('">').iterate();
    Logger.log(teams)
    var time = Parser.data(e).from('data-date="').to('">').iterate()
    Logger.log(time)

     for( var i = 0; i<teams.length ; i = i+2)
     {
       res[i/2] = []
       res[i/2][0] = teams[i]
       res[i/2][1] = teams[i+1]
       res[i/2][2] = new Date(time[i/2]).toLocaleTimeString('en-US')
     }
  Logger.log(res)
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Schedule");
  ss.getRange(ss.getLastRow() + 1, 1, res.length, res[0].length).setValues(res);
}

修改说明:
1)由于您只访问第一个表,因此在解析期间不需要迭代,只需获取第一个表。此外,由于您只获得第一个表,因此您无需使用forEach循环遍历每个元素。

var e = Parser.data(content)
        .from('class="schedule has-team-logos align-left"')
        .to('</tbody>')
        .build();   //Use build instead of iterate

2)您可以使用<abbr title="元素来删除名称,而不是解析HTML链接以获取团队名称。此外,您可以遍历表中的所有团队名称以获得一组团队名称。

var teams = Parser.data(e).from('<abbr title="').to('">').iterate();

3)与上述修改类似,您可以使用data-date标记获取时间。这为您提供了Date()类可以读取的日期。同样,我们遍历表格以获得所有时间

var time = Parser.data(e).from('data-date="').to('">').iterate()

4)最后,我们使用for循环来重新排列名为res的数组中的团队和时间。这允许直接将数据插入到工作表中。

for( var i = 0; i<teams.length ; i = i+2) //each loop adds 2 to the counter
         {
           res[i/2] = []         
           res[i/2][0] = teams[i]   //even team  (starts at zero)
           res[i/2][1] = teams[i+1] //vs odd teams
           res[i/2][2] = new Date(time[i/2]).toLocaleTimeString('en-US')
         }

参考:
Date(),Date.toLocaleTimeString()

编辑:
错误原因,在下面的代码中

Parser.data(e).from('href="mlb/team/_/name/').to('"').build()

您正在寻找字符串'href="mlb/team/_/name/',但它应该是href="/mlb/team/_/name/'。请注意差异mlb/mlb

其次,在以下代码中

Parser.data(e).from('a data-dateformat="time1"').to('</a>').build();

当您检查显示为a data-dateFormat的网站时,该字符串应为dateformat。但是,当您使用URLfetch调用它并记录文本时,它将显示为dateFormat