【问题标题】:Not Able to Scrape table in Google Sheets无法在 Google 表格中抓取表格
【发布时间】:2018-02-21 16:16:09
【问题描述】:

this SO questions的帮助下,我正在尝试抓取following website。我想要两支球队和时间。例如,第一个条目是 Chicago |迈阿密 | 12:30 PM,最后一个条目是科罗拉多 |亚利桑那 |晚上 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:无法从未定义中读取属性“长度”。 (第 42 行,文件“代码”)

【问题讨论】:

  • 我看到的第一个区别是他们在.from('class=\"screener-body-table-nw\"') 调用中逃脱了"。也请 Logger.log(scraped) 看看你是否得到任何东西。

标签: google-apps-script web-scraping google-sheets urlfetch


【解决方案1】:

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

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) 您可以使用&lt;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

【讨论】:

  • 谢谢!我非常感谢非常清晰的解释。
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2021-11-10
相关资源
最近更新 更多