【问题标题】:How to web scrape the starting lineup for the NBA?如何网上刮取NBA的首发阵容?
【发布时间】:2019-03-27 05:07:07
【问题描述】:

我是网络抓取的新手,需要一些帮助。我想使用 Xpath 抓取 NBA 的首发阵容、球队和球员的位置。我只从名字开始,因为我遇到了问题。

到目前为止,这是我的代码:

from urllib.request import urlopen
from lxml.html import fromstring 


url = "https://www.lineups.com/nba/lineups"

content = str(urlopen(url).read())
comment = content.replace("-->","").replace("<!--","")
tree = fromstring(comment)


for nba, bball_row in enumerate(tree.xpath('//tr[contains(@class,"t-content")]')):
    names = bball_row.xpath('.//span[@_ngcontent-c5="long-player-name"]/text()')[0]
    print(names)

看起来程序运行没有错误,但名称没有打印出来。任何有关如何更有效地使用 Xpath 解析的提示将不胜感激。我试着弄乱 Xpath 助手和 Xpath Finder。也许那里有一些技巧可以使过程更容易。提前感谢您的时间和精力!

【问题讨论】:

  • 您要抓取的数据正在通过 Javascript 注入。你不能以你正在做的方式刮它。试试看 Selenium。
  • 谢谢@aris!我会研究 Selenium,如果我弄明白了,我会更新我的代码。

标签: python xpath web-scraping lxml


【解决方案1】:

位于script 节点内的所需内容看起来像

<script nonce="STATE_TRANSFER_TOKEN">window['TRANSFER_STATE'] = {...}</script>

您可以尝试执行以下操作以将数据提取为简单的 Python 字典:

import re
import json
import requests

source = requests.get("https://www.lineups.com/nba/lineups").text
dictionary = json.loads(re.search(r"window\['TRANSFER_STATE'\]\s=\s(\{.*\})<\/script>", source).group(1))

可选:粘贴dictionary here 的输出并单击“美化”以将数据视为可读的JSON

然后您可以通过键访问所需的值,例如

for player in dictionary['https://api.lineups.com/nba/fetch/lineups/gateway']['data'][0]['home_players']:
    print(player['name'])

Kyrie Irving
Jaylen Brown
Jayson Tatum
Gordon Hayward
Al Horford

for player in dictionary['https://api.lineups.com/nba/fetch/lineups/gateway']['data'][0]['away_players']:
    print(player['name'])

D.J. Augustin
Evan Fournier
Jonathan Isaac
Aaron Gordon
Nikola Vucevic

更新

我想我只是把它弄得太复杂了:)

应该像下面这样简单:

import requests

source = requests.get("https://api.lineups.com/nba/fetch/lineups/gateway").json()
for player in source['data'][0]['away_players']:
        print(player['name'])

更新 2

要获得所有团队的阵容,请使用以下:

import requests

source = requests.get("https://api.lineups.com/nba/fetch/lineups/gateway").json()

for team in source['data']:
    print("\n%s players\n" % team['home_route'].capitalize())
    for player in team['home_players']:
        print(player['name'])
    print("\n%s players\n" % team['away_route'].capitalize())
    for player in team['away_players']:
        print(player['name'])

【讨论】:

  • 做得很好。您是如何发现指向所需结果的链接可能在任何脚本@sir Andersson 中的?使用开发工具有什么窍门吗?
  • @SIM ,首先尝试的是简单地复制部分所需数据->打开页面源(右键单击页面->查看页面源)-> Ctrl + F -> Ctrl + V . 如果数据不存在,那么它很可能来自 XHR。但在这种情况下,数据以 JSON 格式保存在 script 节点中,JSON 的第一个键是 API 的链接。没有魔法:)
  • 这与宣传的一样完美......非常感谢@Andersson的帮助。惊人的工作! =)
  • 我刚刚注意到所有的球队和球员都没有被打印出来。我最初认为这是因为所有的启动器都还没有出现,但是启动器现在已经更新了。我看到上面的代码打印了 7 个团队,而顶级团队没有头衔。有什么建议@Andersson?非常感谢您的帮助先生。
  • @AbleArcher ,嗯...我有 3 场当前比赛的 6 支球队首发...你能澄清一下输出到底有什么问题吗,因为我不确定你想得到什么输出?确保您使用的是第二个更新块中的代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-09
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多