Python 如何在一个div中返回同一跨度的多个实例?

Python 如何在一个div中返回同一跨度的多个实例?,python,web-scraping,beautifulsoup,Python,Web Scraping,Beautifulsoup,我在看。我要做的是创建一个.csv,其中包含客场球队、客场首发、客场投手利手的列,然后是每个客场击球手和每个客场击球手利手的单独列,然后是主队 以下是我到目前为止根据以下数据得出的结论: 如果我按原样使用脚本,我可以让球队、投手和惯用手都很好。我可以得到阵容中的第一名球员和他们的惯用手。我似乎无法让它获取entryInfo span类的每个实例 如果我注释掉player和player_的手线,只使用lineup div(在客场阵容行中),我可以得到完整的阵容,在我将其导入Excel时导出到一个大

我在看。我要做的是创建一个.csv,其中包含客场球队、客场首发、客场投手利手的列,然后是每个客场击球手和每个客场击球手利手的单独列,然后是主队

以下是我到目前为止根据以下数据得出的结论:

如果我按原样使用脚本,我可以让球队、投手和惯用手都很好。我可以得到阵容中的第一名球员和他们的惯用手。我似乎无法让它获取entryInfo span类的每个实例

如果我注释掉player和player_的手线,只使用lineup div(在客场阵容行中),我可以得到完整的阵容,在我将其导入Excel时导出到一个大单元格中,而不是将其分解到各个列中

无论用哪种方法,我都可以得到客队球员(他们在分区中排名第一),但不能得到主队球员

以下是发布的脚本的结果:

以下是使用客场阵容线获得整个“阵容”div的结果:

以下是我的目标(每个队只需要两名球员,但我希望全部九名球员都能上场):

我知道我可能在这里遗漏了一些非常明显和基本的东西,但我试着梳理一下这个网站,发现类似的情况通过使用findnext或兄弟姐妹解决了,但我运气不好。我尝试引入第二个嵌套for循环,但我似乎不知道如何让它歌唱

tl;dr:我要在一个页面上抓取的div中有18个相同的span类,我不知道如何获取它们并正确地对它们进行排序


非常感谢您的帮助。

一种方法是在循环匹配过程中进行处理,如下所示。我抓取单个列中的玩家列表,然后将其拆分为单独的列,最后使用正则表达式重命名这些列,并从1开始递增玩家编号。您只需要在末尾应用列排序顺序

此外,您还需要决定如何处理TB@LAA,因为源代码中有两个数字6。下面的当前方法将在该数字上递增,而不是平铺。您可以根据下面的示例编写一些更进一步的正则表达式来处理这个问题,假设只有数字1-9,并且从html中提取了两次6

import requests
from bs4 import BeautifulSoup as bs
import pandas as pd

url = 'https://www.rotoballer.com/fantasy-baseball-daily-projected-starting-mlb-lineups'
r = requests.get(url)
soup = bs(r.text, "lxml")
matches = soup.select('.mlbMatchup')
results = []

for match in matches:
    
    away_team = match.select_one('.away').text
    away_pitcher = match.select_one('.away a').text
    away_pitcher_hand = match.select_one('.away .handed').text
    away_player = [i.text for i in match.select('.lineup:nth-child(3) .entryInfo [href*=player]')]
    away_player_hand = [i.text for i in match.select('.lineup:nth-child(3) .entryInfo .handed')]
    
    home_team = match.select_one('.home').text
    home_pitcher = match.select_one('.home a').text
    home_pitcher_hand = match.select_one('.home .handed').text
    home_player = [i.text for i in match.select('.lineup:nth-child(4) .entryInfo [href*=player]')]
    home_player_hand = [i.text for i in match.select('.lineup:nth-child(4) .entryInfo .handed')]
    
    row = [away_team, away_pitcher, away_pitcher_hand, away_player, away_player_hand,
           home_team, home_pitcher, home_pitcher_hand, home_player, home_player_hand]
    results.append(row)

cols = ['away_team', 'away_pitcher', 'away_pitcher_hand', 'away_player', 'away_player_hand',
        'home_team', 'home_pitcher', 'home_pitcher_hand', 'home_player', 'home_player_hand']

df = pd.DataFrame(results, columns = cols)

splits = ['away_player', 'away_player_hand', 'home_player', 'home_player_hand']

for split in splits:
    df2 = pd.DataFrame(df[split].values.tolist()).add_prefix(split)
    df = pd.concat([df, df2], axis=1)
    df.drop([split], axis=1, inplace=True)

# re-number to start from 1 using lambda idea from @georg https://stackoverflow.com/a/9925319
df.columns = [re.sub(r'player(?P<g1>\d+)$', lambda m: 'player' + str(int(m.group('g1')) + 1), i) for i in df.columns]   
df.columns = [re.sub(r'(?P<g1>_hand)(?P<g2>\d+)', lambda m: str(int(m.group('g2')) + 1) + m.group('g1'), i) for i in df.columns]     
# print(df.head())
导入请求
从bs4导入BeautifulSoup作为bs
作为pd进口熊猫
url='1〕https://www.rotoballer.com/fantasy-baseball-daily-projected-starting-mlb-lineups'
r=请求。获取(url)
汤=bs(右文本,“lxml”)
匹配=汤。选择(“.mlbMatchup”)
结果=[]
对于匹配中的匹配:
客场球队=比赛。选择一个('.away')。文本
客场投手=匹配。选择一个('.away a')。文本
客场投手手匹配。选择一个('.away.hand')。文本
客场球员=[i.text代表比赛中的i.select('.lineup:nth child(3.entryInfo[href*=player]')]
客场球员手=[i.text代表比赛中的i.select('.lineup:nth child(3).entryInfo.hand')]
主页\团队=匹配。选择一个('.home')。文本
主投手=匹配。选择一个('.home a')。文本
home\u pitcher\u hand=匹配。选择一个('.home.hand')。文本
home_player=[i.text for i in match.select('.lineup:n个孩子(4.entryInfo[href*=player]')]
home\u player\u hand=[i.text代表比赛中的i.select('.lineup:nth child(4).entryInfo.hand')]
row=[客场球队,客场投手,客场投手,客场球员,客场球员,
主场球队,主场投手,主场投手,主场球员,主场球员]
结果。追加(行)
cols=[“客场球队”、“客场投手”、“客场投手”、“客场球员”、“客场球员”,
“主场球队”、“主场投手”、“主场投手”、“主场球员”、“主场球员”]
df=pd.DataFrame(结果,列=cols)
拆分=[“客场球员”、“客场球员”、“主场球员”、“主场球员”]
对于拆分中的拆分:
df2=pd.DataFrame(df[split].values.tolist())。添加前缀(split)
df=pd.concat([df,df2],轴=1)
落差([split],轴=1,原地=真)
#使用@georg的lambda idea从1开始重新编号https://stackoverflow.com/a/9925319
df.columns=[re.sub(r'player(?P\d+)$),lambda m:'player'+str(int(m.group('g1'))+1),i)表示df.columns中的i]
df.columns=[re.sub(r'(?P_hand)(?P\d+),lambda m:str(int(m.group('g2'))+1)+m.group('g1'),i)表示df.columns中的i]
#打印(df.head())

一种方法是在循环匹配过程中进行处理,如下所示。我抓取单个列中的玩家列表,然后将其拆分为单独的列,最后使用正则表达式重命名这些列,并从1开始递增玩家编号。您只需要在末尾应用列排序顺序

此外,您还需要决定如何处理TB@LAA,因为源代码中有两个数字6。下面的当前方法将在该数字上递增,而不是平铺。您可以根据下面的示例编写一些更进一步的正则表达式来处理这个问题,假设只有数字1-9,并且从html中提取了两次6

import requests
from bs4 import BeautifulSoup as bs
import pandas as pd

url = 'https://www.rotoballer.com/fantasy-baseball-daily-projected-starting-mlb-lineups'
r = requests.get(url)
soup = bs(r.text, "lxml")
matches = soup.select('.mlbMatchup')
results = []

for match in matches:
    
    away_team = match.select_one('.away').text
    away_pitcher = match.select_one('.away a').text
    away_pitcher_hand = match.select_one('.away .handed').text
    away_player = [i.text for i in match.select('.lineup:nth-child(3) .entryInfo [href*=player]')]
    away_player_hand = [i.text for i in match.select('.lineup:nth-child(3) .entryInfo .handed')]
    
    home_team = match.select_one('.home').text
    home_pitcher = match.select_one('.home a').text
    home_pitcher_hand = match.select_one('.home .handed').text
    home_player = [i.text for i in match.select('.lineup:nth-child(4) .entryInfo [href*=player]')]
    home_player_hand = [i.text for i in match.select('.lineup:nth-child(4) .entryInfo .handed')]
    
    row = [away_team, away_pitcher, away_pitcher_hand, away_player, away_player_hand,
           home_team, home_pitcher, home_pitcher_hand, home_player, home_player_hand]
    results.append(row)

cols = ['away_team', 'away_pitcher', 'away_pitcher_hand', 'away_player', 'away_player_hand',
        'home_team', 'home_pitcher', 'home_pitcher_hand', 'home_player', 'home_player_hand']

df = pd.DataFrame(results, columns = cols)

splits = ['away_player', 'away_player_hand', 'home_player', 'home_player_hand']

for split in splits:
    df2 = pd.DataFrame(df[split].values.tolist()).add_prefix(split)
    df = pd.concat([df, df2], axis=1)
    df.drop([split], axis=1, inplace=True)

# re-number to start from 1 using lambda idea from @georg https://stackoverflow.com/a/9925319
df.columns = [re.sub(r'player(?P<g1>\d+)$', lambda m: 'player' + str(int(m.group('g1')) + 1), i) for i in df.columns]   
df.columns = [re.sub(r'(?P<g1>_hand)(?P<g2>\d+)', lambda m: str(int(m.group('g2')) + 1) + m.group('g1'), i) for i in df.columns]     
# print(df.head())
导入请求
从bs4导入BeautifulSoup作为bs
作为pd进口熊猫
url='1〕https://www.rotoballer.com/fantasy-baseball-daily-projected-starting-mlb-lineups'
r=请求。获取(url)
汤=bs(右文本,“lxml”)
匹配=汤。选择(“.mlbMatchup”)
结果=[]
对于匹配中的匹配:
客场球队=比赛。选择一个('.away')。文本
客场投手=匹配。选择一个('.away a')。文本
客场投手手匹配。选择一个('.away.hand')。文本
客场球员=[i.text代表比赛中的i.select('.lineup:nth child(3.entryInfo[href*=player]')]
客场球员手=[i.text代表比赛中的i.select('.lineup:nth child(3).entryInfo.hand')]
主页\团队=匹配。选择一个('.home')。文本
主投手=匹配。选择一个('.home a')。文本
home\u pitcher\u hand=匹配。选择一个('.home.hand')。文本
home_player=[i.text for i