【问题标题】:ImportXML XPath issue using Google Sheets on a simple web scraping query在简单的网络抓取查询中使用 Google 表格的 ImportXML XPath 问题
【发布时间】:2020-07-03 19:55:44
【问题描述】:

我一直在尝试使用 google 表格从 url https://www.pro-football-reference.com/boxscores/201912290car.htm 抓取高级接收表数据来导入xml,但没有成功。

我尝试过直接从以下检查 chrome 页面复制的 XPath://*[@id="div_receiving_advanced"] 我总是收到“导入的内容为空”错误消息。

我很困惑,因为它使用以下 XPath 处理 Passing、Rushing 和 Receiving 表数据://*[@id="div_player_offense"]

当我使用 //*[@id="all_receiving_advanced"] 的 XPath 时,我得到以下结果。

unparsed results

但是,我想解析第二列中的数据,使其看起来像这样。

parsed results

任何帮助将不胜感激。

【问题讨论】:

    标签: xpath web-scraping google-sheets google-sheets-importxml


    【解决方案1】:

    由于某些播放器没有特定列的值(例如:“Rec/Br”),直接转换IMPORTXML返回的数据会产生一个乱码表。

    2 个解决方案:

    A) 使用IMPORTFROMWEBaddon(免费计划中请求数量有限)激活JS 渲染并使用基本选择器选项来保持数据结构。数据所需的 XPath 表达式:

    /th/a
    /td[@data-stat="team"]
    /td[@data-stat="targets"]
    /td[@data-stat="rec"]
    /td[@data-stat="rec_yds"]
    /td[@data-stat="rec_first_down"]
    /td[@data-stat="rec_air_yds"]
    /td[@data-stat="rec_air_yds_per_rec"]
    /td[@data-stat="rec_yac"]   
    /td[@data-stat="rec_yac_per_rec"]   
    /td[@data-stat="rec_broken_tackles"]    
    /td[@data-stat="rec_broken_tackles_per_rec"]    
    /td[@data-stat="rec_drops"] 
    /td[@data-stat="rec_drop_pct"]
    

    对于标题:

    //div[@id="div_receiving_advanced"]//th[contains(@class,"poptip")]
    

    对于基本选择器:

    //div[@id="div_defense_advanced"]//tr[@data-row][not(@class)]
    

    C6 中使用的公式:

    IMPORTFROMWEB(B1;B2:O2;B3:C4)
    

    输出:

    旁注:IMPORTFROMWEB 经常输出加载错误。

    B) 使用IMPORTDATA 和公式生成表格。首先,我们使用过滤器 (QUERY) 加载感兴趣的数据。然后我们用SUBSTITUTE 修复空白单元格问题。之后,我们使用REGEXEXTRACT 提取数据。最后,我们应用最后一个过滤器和SPLIT 数据来填充单元格。

    公式:

    =ARRAYFORMULA(SPLIT(QUERY(ARRAYFORMULA(REGEXREPLACE(ARRAYFORMULA(SUBSTITUTE(QUERY(IMPORTDATA(B3);"select Col1 where Col1 contains 'rec_broken_tackles_per_rec'");"></td>";">0</td>"));".+htm.+?>(.+?)<.+team.+([A-Z]{3}).+targets.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+?rec.+?>(.+?)<.+";"$1;$2;$3;$4;$5;$6;$7;$8;$9;$10;$11;$12;$13;$14"));"select * WHERE NOT Col1 contains '<'");";"))
    

    输出:

    在这两种情况下,空白单元格都替换为0

    我的工作簿是here

    编辑:

    对于带有IMPORTDATA 的“高级防御表”:

    =ARRAYFORMULA(SPLIT(QUERY(ARRAYFORMULA(REGEXREPLACE(ARRAYFORMULA(SUBSTITUTE(QUERY(IMPORTDATA(B3);"select Col1 where Col1 contains 'def_tgt_yds_per_att'");"></td>";">0</td>"));".+htm.+?>(.+?)<.+team.+([A-Z]{3})<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?def.+?>(.+?)<.+?bli.+?>(.+?)<.+?qb_.+?>(.+?)<.+?qb_.+?>(.+?)<.+?sac.+?>(.+?)<.+?pre.+?>(.+?)<.+?tac.+?>(.+?)<.+?tac.+?>(.+?)<.+?tac.+?>(.+?)<.+";"$1;$2;$3;$4;$5;$6;$7;$8;$9;$10;$11;$12;$13;$14;$15;$16;$17;$18;$19;$20;$21;$22"));"select * WHERE NOT Col1 contains '<'");";"))
    

    输出:

    【讨论】:

    • E. - 感谢您提供两 (2) 个不错的选择。 IMPORTFROMWEB 函数是否有 15 个 xpath 的上限?我尝试对 Advanced Defense 表使用此命令,但出现错误。如果我将 xpath 的数量限制为 15 个,但如果更大则失败。您能否分享 Advanced Defense 表的 IMPORTDATA 解决方案?我尝试修改用于接收表的那一个,但没有成功。
    • 我不认为这是一个上限,但是是的,尝试限制 IMPORTFROMWEB 公式中的 XPath 数量。否则你会得到超时错误。因此,对于“高级防御表”,使用 2 个IMPORTFROMWEB 公式。如果您为“高级防御表”选择IMPORTDATA 选项,则帖子已更新为公式。工作簿也更新了。 IMPORTFROMWEB 公式已经优化了一点(更好的 baseSelector)。黄色背景的单元格包含公式。
    • 当然,如果您的问题得到解决,请将我的帖子标记为最佳答案。
    猜你喜欢
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多