我试图让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;
这可以做我正在尝试的事吗?有人能指出我正确的方向吗?
答案 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', '')
]