【问题标题】:Web scraping data tables to excel网页抓取数据表到excel
【发布时间】:2020-05-10 03:18:07
【问题描述】:

我正在尝试从网站抓取数据以生成 Excel。现在它工作正常,但是当它搜索像 Sergio Rodriguez 这样的人时,会出现多个名称 (https://basketball.realgm.com/search?q=Sergio+Rodriguez),因此它会跳过名称并抛出“No International table for Sergio Rodriguez”。我如何从该列表中选择一个在 NBA 打球的球员,并继续从每场比赛和高级统计数据表中脱颖而出?在这种情况下,当你搜索他的名字时,rodriguez 是第二个。

import requests
from bs4 import BeautifulSoup
import pandas as pd


playernames=['Carlos Delfino', 'Sergio Rodriguez']

result = pd.DataFrame()
for name in playernames:

    fname=name.split(" ")[0]
    lname=name.split(" ")[1]
    url="https://basketball.realgm.com/search?q={}+{}".format(fname,lname)
    response = requests.get(url)

    soup = BeautifulSoup(response.content, 'html.parser')


    try:
        table1 = soup.find('h2',text='International Regular Season Stats - Per Game').findNext('table')
        table2 = soup.find('h2',text='International Regular Season Stats - Advanced Stats').findNext('table')

        df1 = pd.read_html(str(table1))[0]
        df2 = pd.read_html(str(table2))[0]

        commonCols = list(set(df1.columns) & set(df2.columns))
        df = df1.merge(df2, how='left', on=commonCols)
        df['Player'] = name

    except:
        print ('No international table for %s.' %name)
        df = pd.DataFrame([name], columns=['Player'])

    result = result.append(df, sort=False).reset_index(drop=True)

cols = list(result.columns)
cols = [cols[-1]] + cols[:-1]
result = result[cols]
result.to_csv('international players.csv', index=False)

【问题讨论】:

  • 看起来你可以知道它是第二行,因为 NBA 列不为空。您将不得不遍历搜索的候选者并确保您拥有最有可能的候选者。表中没有很多类、ID 或太多结构。这会很困难。
  • 是的,我也想过nba专栏,但我不太清楚该怎么做,所以我想我应该问
  • 我将相关的 html 粘贴到您的问题中,您将获得更多帮助。人们不愿意查看随机网址。如果他们可以在不离开页面的情况下回答您的问题,那么您获得解决方案的几率就更大。如何解决这个问题对我来说并不明显。祝你好运!
  • 除了链接我应该放什么?

标签: python pandas web-scraping beautifulsoup


【解决方案1】:

检查您收到的页面的 URL,搜索结果为单个匹配项会将您定向到

https://basketball.realgm.com/player/{player-name}/Summary/{player-id}

但是当你得到多个结果时

https://basketball.realgm.com/search?q={player-name}

为两个url写一个解析器函数,如(伪代码)

...
for name in playernames:
    fname=name.split(" ")[0]
    lname=name.split(" ")[1]
    url="https://basketball.realgm.com/search?q={}+{}".format(fname,lname)
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')
    # check the response url
    if (response.url == "https://basketball.realgm.com/search..."):
        # parse the search results, finding the players you want
        ... get urls from the table ...
        soup.table...  # etc.
        foreach url in table:
            response = requests.get(player_url)
            soup = BeautifulSoup(response.content, 'html.parser')
            # call the parse function for a player page
            ...
            parse_player(soup)
    else: # we have a player page
        # call the parse function for a player page, same as above
        ...
        parse_player(soup)
    ...

有少量的代码重复,但是当您了解它并使其正常工作时,不要担心。

【讨论】:

  • 我看到了逻辑,但我不知道怎么写。还有,这样岂不是只记录了列表中所有玩家的牌桌?
  • 是的,它会记录列表中的所有玩家。您需要了解一些附加信息才能选择正确的播放器。您还知道结果表中显示的哪些内容?职位、出生日期、选秀年份?任何有助于唯一识别您想要的播放器的内容。
  • 如果球员不在nba,你可以看到nba栏是空的,所以如果栏不为空,那就是我想要的球员。但是我又不知道怎么写。
  • 我对这一切都很陌生,所以很抱歉
  • “所以如果该列不为空,那就是我想要的球员” 但是如果有两个同名球员都在 NBA 的情况会发生什么? (我不知道这是否会发生,但这并非不可能)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 2014-11-25
  • 1970-01-01
  • 2021-10-15
  • 2021-12-28
  • 1970-01-01
相关资源
最近更新 更多