嗯,这开始是一个问题,但我想通了一半。我无法在stackoverflow或Google上找到这样的问题,所以无论如何我都会发布它以帮助任何偶然发现它的人。
我想使用BeautifulSoup中的SoupStrainer来解析两个标签而不是html文档中的一个。
我知道我可以这样做:
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer('p'))
这将获得<p>
标签。我还想获得<h3>
标签。所以我尝试了这个:
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer('h3', 'p'))
但是这不起作用,因为SoupStrainer只接受一个参数。
答案如下。
答案 0 :(得分:3)
要使SoupStrainer解析多个标记,您需要将它们放在列表中。像这样:
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer(['h3', 'p']))
这解析了<h3>
中<p>
和content.text
标记的 ,即使它们是兄弟姐妹(即一个标记不在另一个标记内)。
您也可以使用两个以上的代码进行此操作,只要您将它们作为一个列表传递给SoupStrainer。
一个标签:
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer('p'))
多个标签:
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer(['h1', 'h3', 'p', 'h4']))
答案 1 :(得分:1)
regex
中的功能更多。使用re
模块。
这将获得
<p>
标签。我还想获得<h3>
标签。
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer(re.compile(r"p|h3")))
@马丁(Martijn)
对于属性,可以使用attrs
。
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer(re.compile(r"p|h3")), class_="foo")
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer(re.compile(r"p|h3")), attrs={"class": "foo"})
但是您显然不能为每个HTML class
应用tag
。您可以使用css
选择器来解决它。
soup = BeautifulSoup(content.text, 'lxml', parse_only=SoupStrainer(["h1", "h2", "h3", "p"])).select("h1.foo, h2, h3, p")
答案 2 :(得分:0)
这是在bs4中定义SoupStrainer
的构造函数的方法:
class SoupStrainer(object):
"""Encapsulates a number of ways of matching a markup element (tag or
text)."""
def __init__(self, name=None, attrs={}, text=None, **kwargs):
...
因此,在@JohnStrood的答案中,您可以使用attrs
参数(一个字典)来限制一个或多个属性的匹配:
attrs_dict = { "class": "foo", "other_attr": ["value1", "value2"] }
strainer = SoupStrainer([h3, p], attrs=attrs_dict)