【问题标题】:How to scrape the starting MLB lineups into Pandas DataFrame?如何将 MLB 的起始阵容抓取到 Pandas DataFrame 中?
【发布时间】:2020-09-18 03:27:03
【问题描述】:

我是爬虫新手,还在学习。使用 Python 将 MLB 首发阵容解析为 Pandas DataFrame 的最佳方法是什么?

这是我在这里的一次尝试:


import pandas as pd
import requests
from bs4 import BeautifulSoup

url = 'https://www.baseballpress.com/lineups'
headers = {'User-Agent':
           'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}

df = pd.read_html(url)

print(df)

我收到一个错误:

ValueError: No tables found

每支球队有 1 名投手和 9 名击球手,每场比赛有 2 支球队(因此每场比赛共有 20 名球员)。

这是我正在寻找每个团队的输出示例:

Seth Lugo

Brandon Nimmo
Michael Conforto
J.D. Davis
Dominic Smith
Robinson Cano
Pete Alonso
Jeff McNeil
Andres Gimenez
Robinson Chirinos

这是数据的图片:

提前感谢您提供的任何帮助。非常感激。 =)

【问题讨论】:

    标签: python pandas dataframe web-scraping


    【解决方案1】:

    首先,您使用了错误的链接(如果您考虑附上图片)从那里抓取数据。其次,虽然其中的内容似乎在表格中,但没有与它们关联的trtd 标签。此外,如果您使用html.parser,则无法获取所有玩家姓名。不过,您可以使用 lxmlhtml5lib 解析器获取所有这些。所以,这是您获得它们的方法之一。

    import requests
    from bs4 import BeautifulSoup
    
    url = "https://www.baseballpress.com/lineups/2020-09-17"
    
    r = requests.get(url)
    soup = BeautifulSoup(r.text,'lxml')
    for item in soup.select("[data-league='NL']:contains('Mets') .player > a.player-link"):
        player_name = item.get('data-razz').split("/")[-2].replace("+"," ")
        print(player_name)
    

    尝试以下方法以获取相应的阵容:

    import requests
    import pandas as pd
    from bs4 import BeautifulSoup
    
    url = "https://www.baseballpress.com/lineups/2020-09-17"
    
    def get_names(item):
        try:
            player_name = item.get('data-razz').split("/")[-2].replace("+"," ")
        except IndexError: player_name = ""
        return player_name
    
    r = requests.get(url)
    soup = BeautifulSoup(r.text,'lxml')
    first_lineup = [get_names(item) for item in soup.select(".col--min:nth-of-type(1) > a.player-link, [class$='col--min']:nth-of-type(1) .player > a.player-link")]
    second_lineup = [get_names(item) for item in soup.select(".col--min:nth-of-type(2) > a.player-link, [class$='col--min']:nth-of-type(2) .player > a.player-link")]
    
    df = pd.DataFrame({"first_lineup":first_lineup,"second_lineup":second_lineup})
    df.to_csv("baseballpress.csv", encoding='utf-8', index=False)
    print(df)
    

    【讨论】:

    • Ty 先生 @SIM 为您的帮助和解释!您能否解释一下为什么选择使用“lxml”以及为什么会这样?另外,我希望得到每支球队的阵容。我注意到代码仅包含“大都会”。有什么建议可以让每支球队的所有球员都参加吗?
    • 另外,有些名字好像是双印的。
    • 我使用Mets这个词只是为了识别您所附图像中的数据。要获得所有玩家,您应该踢掉这个[data-league='NL']:contains('Mets') 部分并坚持其余部分。我使用lxml的原因可以找到here。简而言之,它具有修复损坏标签的能力。谢谢。
    • 太棒了@SIM!非常感谢你的帮助。非常令人印象深刻。我会从中学到很多东西。 =)
    猜你喜欢
    • 2020-12-05
    • 2021-06-07
    • 1970-01-01
    • 2019-07-06
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    相关资源
    最近更新 更多