有没有一种方法可以从网站的来源以编程方式运行javascript函数

时间:2019-10-25 19:07:48

标签: javascript web-scraping

在basketball-reference.com上,有一个受伤页面,显示了NBA当前的所有受伤情况。我想开始存档此数据,以记录谁每天在NBA中受伤的记录。除了简单地成为一名篮球运动员之外,这还将是贝叶斯模型的输入,该模型可以预测球员因队友受伤而上场的时间。

现在,我每天只需访问他的页面一次,单击Get Table as a CSV" button,然后将其复制并粘贴到文件中,但这似乎是一项很简单的工作。

我可以抓取原始的html并进行解析,但是该网页的get_csv_output(e)文件中已经具有一个sr-min.js函数,该函数随时可用。实际上,如果我打开开发者控制台并输入

get_csv_output("injuries")

我把所有的csv作为字符串转储了。当我可以简单地使用此功能时,感觉就像重新发明轮子一样。

尽管如此,我的内心还是有些疏离。我不担心如何访问页面,运行js函数以及保存输出而不会通过selenium或其他东西来旋转完整的chrome驱动程序实例。这感觉就像是一个我不知道的简单解决方案所带来的简单问题。

尽管我更喜欢python,bash或其他轻量级解决方案,但我并不特别关心解决方案的语言。

请让我知道我是否天真。

编辑:页面为https://www.basketball-reference.com/friv/injuries.cgi

编辑2:可接受的答案是一个很好的解决方案,可供将来参考。

我最终做了

curl https://www.basketball-reference.com/friv/injuries.cgi | python3 convert_injury_html_to_csv.py > "$(date +'%Y%m%d')".tsv

python脚本在哪里...

import sys
from bs4 import BeautifulSoup


def parse_injury_html(html_doc):
    soup = BeautifulSoup(html_doc, "html.parser")
    injuries_table = soup.find(id="injuries")
    for row in injuries_table.tbody.find_all("tr"):
        if row.get('class', None) == "thead":
            continue
        name = row.th
        team, update, description = row.find_all("td")
        yield((name.string, team.string, update.string, description.string))


def main():
    for (name, team, update, description) in parse_injury_html(sys.stdin.read()):
        print(f"{name}\t{team}\t{update}\t{description}")


if __name__ == '__main__':
    main()

2 个答案:

答案 0 :(得分:1)

您可以直接在该JS函数中直接运行代码。 Node.js是一个独立的JS引擎,因此您可以使用它来运行完全相同的功能。

该功能很可能只是发出HTTP请求以从服务器下载数据,也许需要进行一些轻微的数据操作。节点和浏览器JS之间的网络层不相同,但是有可用的polyfill。如果JS函数使用访存API,则可以使用node-fetch,或者如果它使用XHR样式的请求,xmlhttprequest

由于代码可能是简单的数据获取,因此对发生的事情进行反向工程并自己编写自己的脚本(使用您喜欢的任何语言来编写相同类型的HTTP请求)可能很简单。观察开发人员工具的“网络”标签中发生的情况,可以告诉您数据的获取位置。

答案 1 :(得分:1)

仅执行此功能不会带来任何好处,因为必须在该伤害页面的上下文中执行该功能。如果查看其代码,它将有效地解析html数据。做事的方式很怪异,但我发现情况更糟。没关系。

最简单的解决方案是使用某些方法来打开页面并调用该函数,就像在devtools中一样。 Barmar建议使用Selenium,但我个人更喜欢p。它通过NodeJS运行,以无窗口模式打开Chrome,并在任何站点上执行所有打开的API。在我们的例子中-get_csv_output函数。

在那之后,您可以对结果字符串做任何您想做的事情。将其转储到数据库或保存到文件。

An example of puppeteer code