我想知道如何简化这些混乱的代码并将输出放入漂亮的字典中,而不是元组列表中。我可以更好的方式使用BeautifulSoup吗?
from bs4 import BeautifulSoup as soup
import requests
data = []
sample = []
player_page = requests.get('https://www.premierleague.com/players/10483/Rolando-Aarons/stats')
cont = soup(player_page.content)
for strong_tag in cont.find_all('span', 'stat'):
sample.append(strong_tag.text)
tempStats = [x.replace("\r\n",",") for x in sample]
tempStats = [x.replace("\n","") for x in tempStats]
tempStats = [x.replace(" ","") for x in tempStats]
tempStats = [i.split(',', 1) for i in tempStats]
tempStats = list(map(lambda sublist: tuple(map(str, sublist)), tempStats))
tempStats = [tuple(int(item) if item.strip().isnumeric() else item for item in group) for group in tempStats]
data.append(tempStats)
print(data)
我想要的输出如下:
PlayerName {stat1: 1, stat2: 2 , stat: 3, etc,etc}
之所以采用这种结构,是因为我可以从多个播放器中提取特定的键并比较值。
答案 0 :(得分:4)
此脚本将创建页面上找到的所有统计信息的字典:
from bs4 import BeautifulSoup as soup
import requests
player_page = requests.get('https://www.premierleague.com/players/10483/Rolando-Aarons/stats')
cont = soup(player_page.content, 'lxml')
data = dict((k.contents[0].strip(), v.get_text(strip=True)) for k, v in zip(cont.select('.topStat span.stat, .normalStat span.stat'), cont.select('.topStat span.stat > span, .normalStat span.stat > span')))
from pprint import pprint
pprint(data)
打印:
{'Accurate long balls': '8',
'Aerial battles lost': '12',
'Aerial battles won': '7',
'Appearances': '18',
'Assists': '1',
'Big chances created': '1',
'Big chances missed': '0',
'Blocked shots': '2',
'Clearances': '11',
'Cross accuracy %': '21%',
'Crosses': '19',
'Duels lost': '67',
'Duels won': '54',
'Errors leading to goal': '1',
'Fouls': '11',
'Freekicks scored': '0',
'Goals': '2',
'Goals per match': '0.11',
'Goals with left foot': '1',
'Goals with right foot': '0',
'Headed Clearance': '6',
'Headed goals': '1',
'Hit woodwork': '1',
'Interceptions': '8',
'Losses': '12',
'Offsides': '1',
'Passes': '197',
'Passes per match': '10.94',
'Penalties scored': '0',
'Recoveries': '43',
'Red cards': '0',
'Shooting accuracy %': '27%',
'Shots': '11',
'Shots on target': '3',
'Successful 50/50s': '14',
'Tackle success %': '70%',
'Tackles': '20',
'Through balls': '0',
'Wins': '3',
'Yellow cards': '2'}
编辑:要使用玩家名称和他的数据创建字典,您可以执行此操作(data
来自上面的脚本):
players = {cont.select_one('.playerDetails .name').get_text(strip=True): data}
from pprint import pprint
pprint(players)
打印:
{'Rolando Aarons': {'Accurate long balls': '8',
'Aerial battles lost': '12',
'Aerial battles won': '7',
'Assists': '1',
'Big chances created': '1',
'Big chances missed': '0',
'Blocked shots': '2',
...and so on.
答案 1 :(得分:1)
您可以使用find_all
从statsListBlock
div
s访问数据:
import requests, re
from bs4 import BeautifulSoup as soup
d = soup(requests.get('https://www.premierleague.com/players/10483/Rolando-Aarons/stats').text, 'html.parser')
new_d = d.find_all('div', {'class':'statsListBlock'})
results = {i.div.text[1:-1]:{c.span.contents[0]:c.span.contents[-2].text for c in i.find_all('div', {'class':'normalStat'})} for i in new_d}
new_results = {a:{re.sub('\s+$', '', c):re.findall('\d+', d)[0] for c, d in b.items()} for a, b in results.items()}
输出:
{'Attack': {'Goals': '2', 'Goals per match': '0', 'Headed goals': '1', 'Goals with right foot': '0', 'Goals with left foot': '1', 'Penalties scored': '0', 'Freekicks scored': '0', 'Shots': '11', 'Shots on target': '3', 'Shooting accuracy %': '27', 'Hit woodwork': '1', 'Big chances missed': '0'}, 'Team Play': {'Assists': '1', 'Passes': '197', 'Passes per match': '10', 'Big chances created': '1', 'Crosses': '19', 'Cross accuracy %': '21', 'Through balls': '0', 'Accurate long balls': '8'}, 'Discipline': {'Yellow cards': '2', 'Red cards': '0', 'Fouls': '11', 'Offsides': '1'}, 'Defence': {'Tackles': '20', 'Tackle success %': '70', 'Blocked shots': '2', 'Interceptions': '8', 'Clearances': '11', 'Headed Clearance': '6', 'Recoveries': '43', 'Duels won': '54', 'Duels lost': '67', 'Successful 50/50s': '14', 'Aerial battles won': '7', 'Aerial battles lost': '12', 'Errors leading to goal': '1'}}
关联名称:
new_result = {d.find('div', {'class':'name t-colour'}).text:new_results}
输出:
{'Rolando Aarons': {'Attack': {'Goals': '2', 'Goals per match': '0', 'Headed goals': '1', 'Goals with right foot': '0', 'Goals with left foot': '1', 'Penalties scored': '0', 'Freekicks scored': '0', 'Shots': '11', 'Shots on target': '3', 'Shooting accuracy %': '27', 'Hit woodwork': '1', 'Big chances missed': '0'}, 'Team Play': {'Assists': '1', 'Passes': '197', 'Passes per match': '10', 'Big chances created': '1', 'Crosses': '19', 'Cross accuracy %': '21', 'Through balls': '0', 'Accurate long balls': '8'}, 'Discipline': {'Yellow cards': '2', 'Red cards': '0', 'Fouls': '11', 'Offsides': '1'}, 'Defence': {'Tackles': '20', 'Tackle success %': '70', 'Blocked shots': '2', 'Interceptions': '8', 'Clearances': '11', 'Headed Clearance': '6', 'Recoveries': '43', 'Duels won': '54', 'Duels lost': '67', 'Successful 50/50s': '14', 'Aerial battles won': '7', 'Aerial battles lost': '12', 'Errors leading to goal': '1'}}}