Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用BeautifulSoup根据不同的条件查找不同的元素_Python_Html_Parsing_Html Parsing_Beautifulsoup - Fatal编程技术网

在Python中使用BeautifulSoup根据不同的条件查找不同的元素

在Python中使用BeautifulSoup根据不同的条件查找不同的元素,python,html,parsing,html-parsing,beautifulsoup,Python,Html,Parsing,Html Parsing,Beautifulsoup,我想使用Python库的findAll()函数,在HTML中查找几个元素。这些要素必须满足多个标准,但相互独立 例如,假设我的对象如下所示: <div class="my_class"> <span class="not_cool"> <p name="p_1">A</p> <p name="p_2">B</p> </span> <span class

我想使用Python库的
findAll()
函数,在HTML中查找几个元素。这些要素必须满足多个标准,但相互独立

例如,假设我的对象如下所示:

<div class="my_class">
    <span class="not_cool">
        <p name="p_1">A</p>
        <p name="p_2">B</p>
    </span>
    <span class="cool">
        <p name="p_3">C</p>
    </span>
</div>
在一个完美的世界里,我想做:

.findAll([
        ["span",attrs={"class":"cool"}],
        ["p",attrs={"name":"p_1"}]
    ]}
但当然,它不是这样工作的

实际上,我试图创建一个将HTML转换为BBCode的函数(我不想要也不能使用现有的函数)。 所以,我只需要保留一些我感兴趣的标签

但是,我还必须知道这些元素的顺序。如果我使用两个不同的
.findAll()
,我将不知道什么之前是什么,什么之后是什么


有人有解决方案吗?

只需通过迭代所有所需的
span
来查找每个
span
特定类的所有子类

spans = soup.findAll("span",attrs={"class":"cool"})
for span in spans:
    ps = span.findAll("p",attrs={"name":"p_1"})

通过迭代所有所需的
span
,只需找到每个
span
的所有子类

spans = soup.findAll("span",attrs={"class":"cool"})
for span in spans:
    ps = span.findAll("p",attrs={"name":"p_1"})

您必须使用搜索功能:

.find_all(lambda t: (t.name == 'span' and 'cool' in t['class']) or
                    (t.name == 'p' and t.get('name') == 'p_1'))
一个可调用的参数将传递给树中的每个标记对象;如果可调用函数返回
True
,则包含它。上面的
lambda
测试标记名是否匹配以及是否存在特定属性。
class
属性的特殊之处在于,当它出现时,它总是被解析为一个列表


请注意,对于Beautifulsoup4,驼峰大小写函数名已被弃用;带有下划线名称的小写字母是规范方法。如果您仍在使用BeautifulSoup 3,则可能需要升级。版本3已经两年多没有更新了。

您必须使用搜索功能:

.find_all(lambda t: (t.name == 'span' and 'cool' in t['class']) or
                    (t.name == 'p' and t.get('name') == 'p_1'))
一个可调用的参数将传递给树中的每个标记对象;如果可调用函数返回
True
,则包含它。上面的
lambda
测试标记名是否匹配以及是否存在特定属性。
class
属性的特殊之处在于,当它出现时,它总是被解析为一个列表


请注意,对于Beautifulsoup4,驼峰大小写函数名已被弃用;带有下划线名称的小写字母是规范方法。如果您仍在使用BeautifulSoup 3,则可能需要升级。版本3已经两年多没有更新了。

@That1Guy:是的,BeautifulSoup 3也支持可调用的搜索。@That1Guy:但是,要知道BeatifulSoup 3早已过时。它已经两年多没有新版本了。是的,我知道。我之所以问这个问题,是因为OP似乎在使用BeautifulSoup 3(findAll vs find_all)。@That1Guy:BeautifulSoup 4也支持BS3 camelcase方法,很多教程出于某种原因仍然使用这些方法,所以假设起来总是不安全的。我没有意识到,谢谢你的更正。无论如何+1。您的答案比我的答案更正确,但是我会将我的答案留作首选迭代的替代方案。@That1Guy:是的,BeautifulSoup 3还支持可调用的搜索。@That1Guy:但是,要知道BeatifulSoup 3早已过时。它已经两年多没有新版本了。是的,我知道。我之所以问这个问题,是因为OP似乎在使用BeautifulSoup 3(findAll vs find_all)。@That1Guy:BeautifulSoup 4也支持BS3 camelcase方法,很多教程出于某种原因仍然使用这些方法,所以假设起来总是不安全的。我没有意识到,谢谢你的更正。无论如何+1。你的答案比我的更正确,但是我将把我的作为首选迭代的替代方案。我的例子可能并不完美。假设
p
span
之外,而我仍然想要得到它,那么您的代码将无法工作。我的示例可能并不完美。假设
p
span
之外,并且我仍然想要得到它,那么您的代码将无法工作。