无法在 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
在
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