【问题标题】:How to scrape NHL skater stats using Xpath?如何使用 Xpath 抓取 NHL 溜冰者的统计数据?
【发布时间】:2019-04-07 06:01:52
【问题描述】:

我正在尝试获取 2017/2018 NHL 滑冰运动员的统计数据。我已经开始编写代码,但在解析数据和打印到 excel 时遇到了问题。

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

#import modules 

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

import pandas as pd

#connect to url

url = "https://www.hockey-reference.com/leagues/NHL_2018_skaters.html"

#remove HTML comment markup

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

#setting up excel columns

columns = ("names", "gp", "g", "s", "team")
df = pd.DataFrame(columns=columns)    

#attempt at parsing data while using loop    

for nhl, skater_row in enumerate(tree.xpath('//table[contains(@class,"stats_table")]/tr')):
    names = pitcher_row.xpath('.//td[@data-stat="player"]/a')[0].text
    gp = skater_row.xpath('.//td[@data-stat="games_played"]/text()')[0]
    g = skater_row.xpath('.//td[@data-stat="goals"]/text()')[0]
    s = skater_row.xpath('.//td[@data-stat="shots"]/text()')[0]
    try:
        team = skater_row.xpath('.//td[@data-stat="team_id"]/a')[0].text

    # create pandas dataframe to export data to excel

    df.loc[nhl] = (names, team, gp, g, s)

#write data to excel

writer = pd.ExcelWriter('NHL skater.xlsx')
df.to_excel(writer, 'Sheet1')
writer.save()

谁能解释一下如何解析这些数据?是否有任何提示可以帮助编写 Xpath,以便我可以遍历数据?

我在写这行时遇到问题:

for nhl, skater_row in enumerate(tree.xpath...

您是如何找到 Xpath 的?你用过 Xpath Finder 还是 Xpath Helper?

另外,我遇​​到了一行错误:

df.loc[nhl] = (names, team, gp, g, s)

它显示 df 的语法无效。

我是网络抓取的新手,之前没有编码经验。任何帮助将不胜感激。提前感谢您的宝贵时间!

【问题讨论】:

    标签: python parsing xpath web-scraping lxml


    【解决方案1】:

    如果您仍想坚持使用 XPath 并仅获取所需数据而不是过滤完整数据,您可以尝试以下操作:

    for row in tree.xpath('//table[@id="stats"]/tbody/tr[not(@class="thead")]'):
        name = row.xpath('.//td[@data-stat="player"]')[0].text_content()
        gp = row.xpath('.//td[@data-stat="games_played"]')[0].text_content()
        g = row.xpath('.//td[@data-stat="goals"]')[0].text_content()
        s = row.xpath('.//td[@data-stat="shots"]')[0].text_content()
        team = row.xpath('.//td[@data-stat="team_id"]')[0].text_content()
    

    print(name, gp, g, s, team)的输出:

    Justin Abdelkader 75 13 110 DET
    Pontus Aberg 53 4 70 TOT
    Pontus Aberg 37 2 39 NSH
    Pontus Aberg 16 2 31 EDM
    Noel Acciari 60 10 66 BOS
    Kenny Agostino 5 0 11 BOS
    Sebastian Aho 78 29 200 CAR
    ...
    

    【讨论】:

    • 漂亮的工作@Andersson!这段代码完美无瑕...谢谢先生=)
    • 关于写这行的任何建议:tr[not(@class="thead")] @Andersson?只是好奇你是怎么想到的。
    • @AbleArcher 在每 20 个玩家行之后有一个标题行。因此,要从选择中排除这些行并仅获取包含玩家的条目,您需要添加 [not(@class="thead")] 谓词
    • 这很有意义@Andersson...再次感谢您的知识和专业知识!
    【解决方案2】:

    IIUC:BeautifulSouppandas read_html 可以这样完成

    import requests
    import pandas
    from bs4 import BeautifulSoup
    
    url = 'https://www.hockey-reference.com/leagues/NHL_2018_skaters.html'
    pg = requests.get(url)
    bsf = BeautifulSoup(pg.content, 'html5lib')
    tables = bsf.findAll('table', attrs={'id':'stats'})
    dfs = pd.read_html(tables[0].prettify())
    df = dfs[0]
    

    生成的数据框将包含表中的所有列,并使用 pandas 过滤所需的列。

    #Filters only columns 1, 3 and 5 similarly all required columns can be filtered.
    dff = df[df.columns[[1, 3, 5]]]
    

    【讨论】:

    • 感谢@Abbas 的宝贵时间!惊人的!我希望使用 Xpath,但这似乎绰绰有余。
    猜你喜欢
    • 1970-01-01
    • 2019-05-29
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多