无法在 Google 张中抓取 table

Not Able to Scrape table in Google Sheets

I am trying to scrape the following website 的帮助下。我想要两支球队和时间。例如,第一个条目是 Chicago |迈阿密 | 12:30 PM,最后一个条目是 Colorado |亚利桑那 | 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: Cannot read property "length" from undefined. (line 42, file "Code")

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

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) 由于您只访问第一个 table,因此在解析过程中不需要迭代,只需获取第一个 table。此外,由于您只获得第一个 table,因此无需使用 forEach 遍历每个元素。

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

2) 除了解析 HTML link 来获取团队名称之外,您还可以使用 <abbr title=" 元素来抓取名称。此外,您可以遍历 table 中的所有团队名称以获得团队名称数组。

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

3) 和上面的修改类似,可以通过data-date标签获取时间。这为您提供了 Date() class 可以读取的日期。同样,我们遍历 table 以获得所有时间

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

4) 最后,我们使用for循环重新排列数组res中的球队和时间。这允许将数据直接插入 sheet。

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