试图从foresets.com上抓取文本



我正试图从foreset.com上获取某些信息。我似乎能够获取主队、awayteam、位置,但无法获取预测分数、正确分数或天气。

有人能看看我的代码,告诉我家里的预测分数,正确的分数和天气吗。这是我迄今为止的代码:

from bs4 import BeautifulSoup
import requests
source = requests.get('https://www.forebet.com/en/predictions-world/world-cup').text

soup = BeautifulSoup(source, 'lxml')
teams= soup.find_all('a', class_= 'tnmscn')
for team in teams:
hometeam = team.find('span',class_= 'homeTeam').text
predictedscore = team.select_one('div', class_='ex_sc tabonly')
awayteam = team.find('span',class_ = 'awayTeam').text
date = team.find('span', class_='date_bah').text
location = team.find('name address', 'content').text
weather = team.find('span', class_="wnums")[0].text
print(hometeam,predictedscore ,awayteam,date,weather)

感谢的帮助

尝试抓取forest.com似乎无法抓取所有必要的数据。

您使用tnmscn类在超链接中循环,但这只涵盖团队和日期信息;如果你还想要更多的数据,比如位置/天气/分数/赔率等。,你需要覆盖整排

# teams = soup.find_all('a', class_= 'tnmscn')
rows = soup.find_all('div', {'class': 'rcnt'})
# for team in teams:
for r in rows:
hometeam = r.find('span',class_= 'homeTeam').text
#### AND SO ON ####

(您也可以使用for team in soup.find_all('div', {'class': 'rcnt'})进行循环,并在循环中继续使用team.find...-这在结果方面不会有什么不同,但我认为for r in rows...在整个行上循环[而不仅仅是主客场球队列]更有意义。)


关于使用此行获取位置:

location = team.find('name address', 'content').text

我在这行上得到AttributeError,因为.find('name address', 'content')返回None[而您无法从None]获得.text]。如果您没有收到这样的错误,我会感到非常惊讶,因为.find的主要输入应该是一个标签名称,而试图查找name address永远不会返回任何内容,因为html标签名称中没有空格。


关于用这条线获得预测分数:

predictedscore = team.select_one('div', class_='ex_sc tabonly')

class_不是可以传递给.select/.select_one的参数,所以它只是选择team中的第一个div。您可以传递更精细的CSS选择器,因此它应该像.select_one('div.ex_sc.tabonly')那样。

应该使用的是.find('span', {'itemprop': 'location'}).meta['content']来获取meta标签的content属性,例如。

此外,请不要说这实际上会给你带来正确的分数,而不是预测的分数。


以获取预测分数、正确分数和天气

如果你在整行上循环,那么你可以使用

  • .find('span', class_='forepr').text获得预测得分
  • .find('div', class_='ex_sc tabonly').text以获得正确的分数
  • .find('div', class_="prwth tabonly")来获取天气,但它可能会丢失,所以您应该
    • 在另一行中有if weather: weather = weather.text以避免获得AttributeError
    • [如果您想跳过这样的"行",请使用else: continue添加另一行。]


建议的解决方案:

尽管这只是这里的天气数据的一个问题,但在尝试获取.text之前,检查.find....select...返回了什么总是更安全的;由于您重复执行[.find....text],因此将其作为一个函数更方便。

我已经有了一个函数,我在使用bs4进行刮擦时经常使用它,但它使用的是.select_one(而不是.find)。你所需要的只是一个选择器列表,如果你使用列表理解,你可以在一个语句中获得所有数据:

# def selectForList.... # PASTE FROM https://pastebin.com/ZnZ7xM6u
rData = [selectForList(r, [
'span.homeTeam', 'span.awayTeam', # home/away teams
'span.forepr', 'div.ex_sc.tabonly', # pred/correct scores
'span.date_bah', # date [location below]
('span[itemprop="location"]>meta[itemprop="name address"][content]', 'content'), 
'div.prwth.tabonly>span.wnums', # temperature
]) for r in soup.select('div.rcnt')]

您可以通过使用printList=' '设置selectForList的打印选项进行打印,也可以循环使用rData来更好地控制打印方式。

for r in rData: 
print(f'# {r[0]} vs {r[1]}: {r[3] if r[3] else "score_unknown"}', 
f'[pred: {r[2]}] on {r[4]} (at {r[5]})', 
f'[{("temp: "+r[6]) if r[6] else "no_weather_data"}]')

### PRINTED OUTPUT BELOW ###
# Argentina vs France: 2 - 2 [pred: X] on 18/12/2022 16:00 (at Lusail Iconic Stadium) [temp: 21°]
# Croatia vs Morocco: 0 - 0 [pred: X] on 17/12/2022 16:00 (at Khalifa International Stadium) [temp: 22°]
# Argentina vs Croatia: 1 - 1 [pred: X] on 13/12/2022 20:00 (at Lusail Iconic Stadium) [temp: 22°]
# France vs Morocco: 3 - 1 [pred: 1] on 14/12/2022 20:00 (at Al Bayt Stadium) [temp: 22°]
# Juventus W vs Zurich (W): score_unknown [pred: 1] on 15/12/2022 18:45 (at Allianz Stadium) [no_weather_data]
# SL Benfica (W) vs Barcelona (W): score_unknown [pred: 2] on 15/12/2022 21:00 (at Caixa Futebol Campus) [no_weather_data]

对于稍微结构化的输出,您可以为选择器定义[而不是列表]一个参考字典(selRef),然后获得与selRef:具有相同键的字典列表中的数据

selRef = {'home_team': 'span.homeTeam', 'away_team': 'span.awayTeam', 'pred-y_n': ('div[class^="predict"]:has(>span.forepr)', 'class'), 'pred': 'span.forepr', 'correct_score': 'div.ex_sc.tabonly', 'date': 'span.date_bah', 'location': ('span[itemprop="location"]>meta[itemprop="name address"][content]', 'content'), 'temperature': 'div.prwth.tabonly>span.wnums', 'weather_icon': ('div.prwth.tabonly>img.wthc[src]', 'src')}
rdList = [dict(zip(
selRef.keys(), selectForList(r, selRef.values()) #, printList=' ')
)) for r in soup.select('div.rcnt')]

那么您可以使用panda将其转换为DataFrame,就像pandas.DataFrame(rdList)一样。[查看数据帧]


您可能会注意到,除了拆分预测之外,我还添加了一个weather_icon列。此列可用于添加天气的描述

wiRef = {'w-32': 'sunny', 'w-31': 'clear', 'w-30':'cloudy-day', 'w-29':'cloudy-night', 'w-20': 'fog', 'w-12': 'rainy-day', 'w-11': 'rainy-night'}
for ri, w in ([(i, r['weather_icon']) for i, r in enumerate(rdList) if r['weather_icon']]):
rdList[ri]['weather_icon'] = f'https://www.forebet.com{w}' # replace with full link
w = w.split('/')[-1].split('.png')[0].strip()
rdList[ri]['weather'] = wiRef[w] if w in wiRef else f'{w}.png'
# import pandas
pandas.DataFrame(rdList).to_csv('wcPreds.csv', index=False)

天气图标的完整列表以及输出"wcPreds.csv"的内容可以在该电子表格中找到。


您可以使用print(pandas.DataFrame(rdList).drop(['weather_icon'], axis=1).rename({'temperature':'temp'}, axis=1).to_markdown(index=False))打印下表的标记:

home_team位置temp天气
阿根廷21°清除
克罗地亚清除
阿根廷清除
法国清除
尤文图斯Wnan
SL Benfica(W)nan

相关内容

  • 没有找到相关文章

最新更新