带有美丽汤的Python2 - 过滤具有多个CSS类的元素

时间:2017-08-31 14:32:30

标签: python python-2.7 beautifulsoup

我试图让BS4过滤掉包含某个类的元素。这是我的HTML:

<!-- language: lang-html -->
<html>
<head>
    <title>Test</title>
</head>

<body>

<table>
    <tr class='test hidden'><td>foo</td></tr>
    <tr class='testabc'><td>bar</td></tr>   
    <tr class='test hidden'><td>foo</td></tr>
    <tr class='testxyz'><td>bar</td></tr>   
</table>

</body>

</html>

我的Python代码:

# import libraries
import urllib2
import re
from bs4 import BeautifulSoup
from bs4 import Comment
import operator

with open('sample.html', 'r') as myfile:
    html=myfile.read()

soup = BeautifulSoup(html, 'html.parser')
rows = soup.find('table').find_all('tr', class_=lambda x: 'hidden' not in x)

for row in rows:
    print row

您可以看到该表的行包含class =&#39; test hidden&#39;或者类=&#39;完整&#39;。我试图将所有行隐藏起来&#39;不是元素上的类。

基本上我希望输出为:

<tr class='testabc'><td>bar</td></tr>   
<tr class='testxyz'><td>bar</td></tr>

相反,我获得了所有行:

<tr class='test123 hidden'><td>foo</td></tr>
<tr class='testabc'><td>bar</td></tr>   
<tr class='test456 hidden'><td>foo</td></tr>
<tr class='testxyz'><td>bar</td></tr>   

我已经尝试了多种组合&#34;而不是&#34;或&#34;!=&#34;。我已经尝试创建一个lambda调用的函数,这样我就可以看到x是什么类型的对象,并更好地理解如何使用它,但我不能让它工作,除非我努力 - 将lambda编码为lambda x:x ==&#39; testabc&#39;或x ==&#39; testxyz&#39;

这可以做我正在尝试的事吗?有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:2)

你可以这样做(获取l元素然后过滤掉你不想要的那些):

from bs4 import BeautifulSoup

html = """
<html>
<head>
    <title>Test</title>
</head>

<body>

<table>
    <tr class='test hidden'><td>foo</td></tr>
    <tr class='testabc'><td>bar</td></tr>
    <tr class='test hidden'><td>foo</td></tr>
    <tr class='testxyz'><td>bar</td></tr>
</table>

</body>

</html>
"""

soup = BeautifulSoup(html, 'html.parser')
rows = soup.find('table').find_all('tr')

for row in rows:
    if 'hidden' not in row.attrs['class']:
        print row

输出:

<tr class="testabc"><td>bar</td></tr>
<tr class="testxyz"><td>bar</td></tr>

答案 1 :(得分:1)

问题是class_参数仅使用attrs['class']列表中的第一个字符串。
您可以使用.get('class')访问完整的类列表。

使用lambda:

rows = soup.find('table').find_all(
    lambda tag: tag.name == 'tr' and 'hidden' not in tag.get('class', '')
)

使用列表推导:

rows = [
    tr for tr in soup.find('table').find_all('tr') if 'hidden' not in tr.get('class', '')
]