【问题标题】:Extracting data from list in Python, after BeautifulSoup scrape, and creating Pandas table在 BeautifulSoup 抓取之后从 Python 中的列表中提取数据,并创建 Pandas 表
【发布时间】: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 中构建一个数据框,但我可能完全错了。

【问题讨论】:

    标签: python python-3.x pandas beautifulsoup


    【解决方案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]
    

    【讨论】:

      【解决方案2】:

      您可以使用 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-namedata-odig),所以我使用了类似名称的属性。我对赛马知之甚少,不知道这些是否有用,但此答案中的方法应该允许您选择任何可用的属性。

      【讨论】:

      • 非常感谢安德鲁,非常感谢。我唯一的问题是,例如,每个博彩公司在 中都有一个唯一标识符,即 data-bk="PP" 这意味着 PaddyPower 是博彩公司,随后是 data-odig 中的赔率。在获取博彩公司名称以将其与给定赔率相关联方面,我将如何工作,即在表格 PP 赔率中,然后在所有列中。谢谢
      • 不客气。如果<td><tr> 中,您可以使用.children 获取其属性。如果您需要比这更具体的帮助,我建议您打开一个单独的问题。
      【解决方案3】:

      如果是网络抓取,您可以采用将数据存储为各种变量的方法:

      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?)。

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签