【问题标题】:select two specific classes with find_all in Beautifulsoup在 Beautifulsoup 中使用 find_all 选择两个特定的类
【发布时间】:2018-05-17 14:19:06
【问题描述】:

我想使用 BeautifulSoup 从网站上抓取一些数据。数据在一个表中,其中不同的表行总共为 4 个不同的类。

<table class="timeteam">
    <tbody>
        <tr class="even"></tr>
        <tr class="even smallrow"></tr>
        <tr class="odd"></tr>
        <tr class="odd smallrow"></tr>
    </tbody>
</table>

“偶数”行和“奇数”行中的数据属于同一行。所以我想在 Dataframe 的末尾获取这两行(以及其他行)。

使用 find_all('tr', class_=['even', 'odd']) 我还得到了其他行(使用 smallrow)。因此我尝试了重新编译功能。但还是一样的结果。

我需要在我的代码中进行哪些更改以仅选择具有“偶数”和“奇数”类的行?

这是我的代码:

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

page = request.get('https://regatta.time-team.nl/hollandia/2017/results/003.php')
soup = bs(page.content, 'html.parser')

tables = soup.find_all('table', class_='timeteam')

player_data_even = []
player_data_smallrow = []
for i in range(len(tables)):    
    for tr in tables[i].find_all('tr', class_ = re.compile(r"^(even|odd)$")):      
        player_row_even = []
        for td in tr.find_all('td'):    
            player_row_even.append(td.get_text())    
        player_data_even.append(player_row_even)
    for tr in tables[i].find_all('tr', class_=['even smallrow', 'odd smallrow']):
        player_row_smallrow = []
        for td in tr.find_all('td'):
            player_row_smallrow.append(td.get_text())
        player_data_smallrow.append(player_row_smallrow)

players_even = pd.DataFrame(player_data_even)
players_smallrow = pd.DataFrame(player_data_smallrow)

【问题讨论】:

    标签: python class beautifulsoup find


    【解决方案1】:

    您可以使用检查包含类的列表的长度是否为 1:

    from bs4 import BeautifulSoup as soup
    content = """
      <table class="timeteam">
       <tbody>
        <tr class="even">yes</tr>
        <tr class="even smallrow">no</tr>
        <tr class="odd">yes</tr>
        <tr class="odd smallrow">no</tr>
       </tbody>
    </table>
    """
    s = [i.text for i in soup(content, 'html.parser').find_all('tr') if len(i['class']) == 1]
    

    输出:

    ['yes', 'yes']
    

    【讨论】:

    • 感谢分享。我尝试了这个选项,但没有在我的脚本中得到我想要的。我得到一个属性错误。如果我能做到,我会进一步研究
    【解决方案2】:

    好的,看来你的问题已经解决了。您现在可以按顺序获取所有数据。试一试:

    from bs4 import BeautifulSoup
    import requests
    
    res = requests.get("https://regatta.time-team.nl/hollandia/2017/results/003.php")
    soup = BeautifulSoup(res.text,"lxml")
    
    for table in soup.find(class_="timeteam").find_all("tr",class_=['even','odd']):
        if "smallrow" not in table.get('class'):  #this is the fix
            data = [item.get_text(strip=True) for item in table]
            print(data)
    

    你可能会得到如下输出:

    ['1.', 'PHO', 'Phocas 1 (p2)', '', '--', '', '--', '', '--', '', '06:39,86', '(1)', 'KF']
    ['2.', 'PAM', 'Pampus (p4)', '', '--', '', '--', '', '--', '', '06:45,21', '(2)', 'KF']
    ['3.', 'SKO', 'Skøll 1', '', '--', '', '--', '', '--', '', '06:46,23', '(3)', 'KF']
    ['4.', 'NJO', 'Njord (p1)', '', '--', '', '--', '', '--', '', '06:49,44', '(4)', 'KF']
    ['5.', 'GYA', 'Gyas (SB)', '', '--', '', '--', '', '--', '', '06:50,04', '(5)', 'KF']
    ['6.', 'PRO', 'Proteus 1 (p7)', '', '--', '', '--', '', '--', '', '06:50,24', '(6)', 'KF']
    

    【讨论】:

    • 这就是我要找的。现在我必须找到一种方法以正确的顺序获取数据,并将数据与其他行中的数据与偶数小行和奇数小行的类结合起来。
    • 所以是的,顺序很重要;-)
    • 不要错过@Jeroen Spaans 的更新。我已经解决了你的问题。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2010-12-07
    • 2021-11-25
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    相关资源
    最近更新 更多