在 BeautifulSoup 抓取之后从 Python 中的列表中提取数据,并创建 Pandas 表
Posted
技术标签:
【中文标题】在 BeautifulSoup 抓取之后从 Python 中的列表中提取数据,并创建 Pandas 表【英文标题】:Extracting data from list in Python, after BeautifulSoup scrape, and creating Pandas table 【发布时间】:2020-12-28 06:23:51 【问题描述】:我学习 Python 的基础知识已经有一段时间了,并认为我会继续尝试将一些东西放在一起,但似乎遇到了一个绊脚石(尽管到处寻找我可能的地方会出错)。
我正在尝试从这里抢一张桌子:https://www.oddschecker.com/horse-racing/2020-09-10-chelmsford-city/20:30/winner
现在我意识到该表并未列出正常 html 的典型程度,因此尝试使用 Pandas 抓取它不会产生结果。因此深入研究 BeautifulSoup 以尝试获得结果。
似乎我需要的所有数据都在“diff-row evTabRow bc”类中,因此写了以下内容:
url = requests.get('https://www.oddschecker.com/horse-racing/2020-09-10-haydock/14:00/winner')
soup = BeautifulSoup(url.content, 'lxml')
table = soup.find_all("tr", class_="diff-row evTabRow bc")
这似乎将每匹马和我需要的所有相应数据放入一个列表中。在这个列表中,我只需要某些位,即马名的“data-name”和当前赔率的“data-odig”。
我认为可能有某种方法可以从列表中提取数据以构建列表列表,然后在 Pandas 中构建一个数据框,但我可能完全错了。
【问题讨论】:
【参考方案1】:您要查找的数据在行标签
问题是不是所有的
import pandas as pd
from bs4 import BeautifulSoup
import requests
url = requests.get('https://www.oddschecker.com/horse-racing/thirsk/13:00/winner')
soup = BeautifulSoup(url.content, 'lxml')
rows = soup.find_all("tr", class_="diff-row evTabRow bc")
my_data = []
for row in rows:
horse = row.attrs['data-bname']
for td in row:
if td.attrs['class'][0] != 'np':
continue #Skip
bookie = td['data-bk']
odds = td['data-odig']
my_data.append(dict(
horse = horse,
bookie = bookie,
odds = odds
))
df = pd.DataFrame(my_data)
print(df)
这将为您提供所需的内容:
horse bookie odds
0 Just Frank B3 3.75
1 Just Frank SK 4.33
2 Just Frank WH 4.33
3 Just Frank EE 4.33
4 Just Frank FB 4.2
.. ... ... ...
268 Tommy R RZ 29
269 Tommy R SX 26
270 Tommy R BF 10.8
271 Tommy R MK 41
272 Tommy R MA 98
[273 rows x 3 columns]
【讨论】:
您可以使用 BeautifulSoup 对象 .attrs
属性访问任何 <tr>
属性。
一旦你有了table
,循环遍历每个条目,提取你想要的属性作为字典列表。然后使用结果列表初始化 Pandas 数据框。
horse_attrs = list()
for entry in table:
attrs = dict(name=entry.attrs['data-bname'], dig=entry.attrs['data-best-dig'])
horse_attrs.append(attrs)
df = pd.DataFrame(horse_attrs)
df
name dig
0 Las Farras 9999
1 Heat Miami 9999
2 Martin Beck 9999
3 Litran 9999
4 Ritmo Capanga 9999
5 Perfect Score 9999
6 Simplemente Tuyo 9999
7 Anpacai 9999
8 Colt Fast 9999
9 Cacharpari 9999
10 Don Leparc 9999
11 Curioso Seattle 9999
12 Golpe Final 9999
13 El Acosador 9999
注意事项:
您提供的网址对我不起作用,但这个类似的网址对我有用:https://www.oddschecker.com/horse-racing/palermo-arg/21:00/winner 我没有看到你提到的确切属性(data-name
和data-odig
),所以我使用了类似名称的属性。我对赛马知之甚少,不知道这些是否有用,但此答案中的方法应该允许您选择任何可用的属性。
【讨论】:
非常感谢安德鲁,非常感谢。我唯一的问题是,例如,每个博彩公司在<td>
在<tr>
中,您可以使用.children
获取其属性。如果您需要比这更具体的帮助,我建议您打开一个单独的问题。
如果是网络抓取,您可以采用将数据存储为各种变量的方法:
l = []
for thing in elements:
var1 = ... # however you extract it
var2 = ...
l.append('column1_name': var1, 'column2_name': var2)
df = pd.DataFrame(l)
如何从 HTML 元素中选择数据取决于您(考虑选择td
?)。
【讨论】:
以上是关于在 BeautifulSoup 抓取之后从 Python 中的列表中提取数据,并创建 Pandas 表的主要内容,如果未能解决你的问题,请参考以下文章
BeautifulSoup 使用循环从多个 div 中抓取信息到 JSON
使用 python 3 和 beautifulsoup 从亚马逊抓取图像