【问题标题】:Beautiful Soup: Select a row in a table if a cell is containing a wordBeautiful Soup:如果单元格包含单词,请选择表格中的一行
【发布时间】:2021-03-20 21:55:25
【问题描述】:

感谢您关注我的帖子,

经过多次研究,如果单元格包含特定值,我找不到仅抓取表格行的平均值。

更具体地说:我想将包含单词“oui”的行保留在下表的最后一列中:

<table align="center" cellspacing="0" cellpadding="3" width="100%">
<tbody><tr>
<td class="tdhg" align="left"><b>Liste des candidats</b></td>
<td class="tdhv"><strong>Voix</strong></td>
<td class="tdhv"><strong>%&nbsp;Inscrits</strong></td>
<td class="tdhv"><strong>%&nbsp;Exprimés</strong></td>
<td class="tdhv"><strong>Elu(e)</strong></td>
</tr>
<tr>
<td class="tdcbf" align="left">M.&nbsp;Jean-François LAMOUR&nbsp;(UMP) </td>
<td class="tdcd" align="right">23&nbsp;964</td>
<td class="tdcd" align="right">  33,01</td>
<td class="tdcd" align="right">  54,60</td>
<td class="tdcd" align="center">oui
                          &nbsp;</td>
</tr>
<tr>
<td class="tdcbf" align="left">M.&nbsp;Gilles ALAYRAC&nbsp;(RDG) </td>
<td class="tdcd" align="right">19&nbsp;927</td>
<td class="tdcd" align="right">  27,45</td>
<td class="tdcd" align="right">  45,40</td>
<td class="tdcd" align="center">
                          &nbsp;</td>
</tr>
</tbody></table>

我第一次尝试通过正则表达式,我成功找到了匹配的单词,但保持关注行似乎很复杂,所以我决定改变方法并通过 BeautifulSoup。

到目前为止我做的最好的是:

url='www.someurl.com'
headers = {"User-Agent":"Mozilla/5.0"}
response = requests.get(url.format())
html_soup = soup(response.content, 'lxml')
html_soup.select('td.tdcd')

我无法更进一步,特别是声明将 'tr' 保留在 'tdcd' 包含 'oui' 的位置。即使我阅读了https://www.crummy.com/software/BeautifulSoup/bs4/doc/ 的文档,如果我没有弄错的话,也很难将一个单元格作为一个孩子来考虑。

谢谢,

【问题讨论】:

    标签: python css beautifulsoup


    【解决方案1】:

    这就是你所追求的。只需读入数据框,然后过滤数据框

    html = '''<table align="center" cellspacing="0" cellpadding="3" width="100%">
    <tbody><tr>
    <td class="tdhg" align="left"><b>Liste des candidats</b></td>
    <td class="tdhv"><strong>Voix</strong></td>
    <td class="tdhv"><strong>%&nbsp;Inscrits</strong></td>
    <td class="tdhv"><strong>%&nbsp;Exprimés</strong></td>
    <td class="tdhv"><strong>Elu(e)</strong></td>
    </tr>
    <tr>
    <td class="tdcbf" align="left">M.&nbsp;Jean-François LAMOUR&nbsp;(UMP) </td>
    <td class="tdcd" align="right">23&nbsp;964</td>
    <td class="tdcd" align="right">  33,01</td>
    <td class="tdcd" align="right">  54,60</td>
    <td class="tdcd" align="center">oui
                              &nbsp;</td>
    </tr>
    <tr>
    <td class="tdcbf" align="left">M.&nbsp;Gilles ALAYRAC&nbsp;(RDG) </td>
    <td class="tdcd" align="right">19&nbsp;927</td>
    <td class="tdcd" align="right">  27,45</td>
    <td class="tdcd" align="right">  45,40</td>
    <td class="tdcd" align="center">
                              &nbsp;</td>
    </tr>
    </tbody></table>'''
    
    import pandas as pd
    
    table = pd.read_html(html)[0]
    
    # Keep any rows that have 'oui' in the row; doesn't matter which column
    filter_table = table[table.values == 'oui']
    
    # Or if you specifically need to look in the last column
    #filter_table = table[table.iloc[:,-1] == 'oui']
    
    # Or specific column name
    #filter_table = table[table[4] == 'oui']
    

    输出:

    print (filter_table)
                                   0       1     2     3    4
    1  M. Jean-François LAMOUR (UMP)  23 964  3301  5460  oui
    

    替代方案:

    在这里你可以遍历行,并且只在它包含'oui'时追加

    html_soup = BeautifulSoup(html, 'lxml')
    data_rows = html_soup.select('tr')
    
    rows = []
    for row in data_rows:
        data = [ x.text.strip() for x in row.find_all('td',{'class':'tdcd'})]
        if 'oui' in data:
            rows.append(data)
            
    table = pd.DataFrame(rows)
    

    【讨论】:

    • 感谢您的回答,这似乎很一致。好吧,我没有考虑在熊猫阶段进行过滤,但它可以解决问题。问题是我在同一页面上废弃了一堆变量,因此它们将在每一页的每一行重复(即使它不包含'oui')并且因为我有很多页面我想在存储之前过滤到一个熊猫文件。
    • 嗯,好的。我也会研究另一种解决方案。但是你说得有道理
    • 非常感谢!
    【解决方案2】:

    找到包含ouitd.tdcd选择它的父级

    html_soup = soup(response.content, 'lxml')
    tds = html_soup.select('td.tdcd')
    
    for td in tds :
      if 'oui' in td.text:
        print(td.parent)
    

    【讨论】:

    • 非常感谢,这似乎是我一直在寻找的东西!我专注于孩子,而不是父母,这是一种非常有趣的方法。最后一个小问题:为什么 td.parent 单独显示没有 'oui' 的行(这只是为了完全理解机制)?
    • 它显示oui你可以在repl.it/@uingtea/PythonTester上测试它
    猜你喜欢
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    相关资源
    最近更新 更多