如何将一组参数作为一个长变量传递给find()/find_all()

2024-03-29 00:12:31 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有以下html代码:

html = """
<div non_class="first"></div>
<h2 style="some_style"> Text 1</h2>
<div non_class="second"></div>
<div non_class="first">Text 2</div>
"""

使用此代码:

from bs4 import BeautifulSoup as bs
soup = bs(html,'lxml')

我向soup.find_all()传递两个参数,一个标记和一个属性/属性值对:

first = soup.find_all('div',non_class='first')
for i in first:
    print(i)

将输出:

<div non_class="first"></div>
<div non_class="first">Text 2</div>

很简单。现在让我们假设,我不想硬连接参数,而是将它们作为变量传递给find_all()。基于问题such as thisthisor this,我使用了以下方法:

my_tag = 'div'
my_att = {'non_class': 'first'}

second = soup.find_all(my_tag,my_att)
for i in second:
    print(i)

它产生正确的输出。但这远不能令人满意。我的'target'标记是<div non_class="first">,并且(如果一切顺利的话)它将是我打算在for循环中使用的目标列表中的一个条目。但这些答案中提出的方法需要(除非有人有更好的方法!)我将目标分解为它的组件:首先,一个标记(在本例中为-div),然后获取属性/属性值对(在本例中为non_class="first"),并将其转换为一个字典({'non_class': 'first'}),然后将这两个输入到find_all(_)。这是可行的,但不雅观。你知道吗

所以我试着用一个变量传递整个参数集,但是

target = '<div non_class="first">'

third = soup.find_all(target)

什么也找不到。使用f字符串为目标提供信息:

fourth = soup.find_all(f'{target}')

也失败了。你知道吗

编辑:为了澄清,这个练习的目的是将元素提供给find_all(),而不必首先手动或使用helper函数将元素分解为其组成部分。从概念上讲,我想我不明白为什么find_all()可以直接将元素作为字符串参数,但是如果字符串被赋给一个变量,find_all()就不能将该变量作为字符串参数重新构造。。。你知道吗

那么,这是可行的,还是我必须屈服于切割目标?或者,可以用硒来做吗?你知道吗


Tags: 字符串textdivtarget目标参数属性my
1条回答
网友
1楼 · 发布于 2024-03-29 00:12:31

有很多方法可以提取数据。如果我正确理解用例,下面的选项可能会帮助您。你知道吗

html = """
<div non_class="first"></div>
<h2 style="some_style"> Text 1</h2>
<div non_class="second"></div>
<div non_class="first">Text 2</div>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')


print(soup.find_all(non_class="first"))

find_element = lambda target,soup : soup.find_all(target['tag'],{target['attribute']:target['value']})
target = {'tag':'div','attribute':'non_class','value':'first'}
print(find_element(target,soup))

target = {'non_class': 'first'}
print(soup.find_all(attrs=target))

print(soup.find_all(non_class="first"))

甚至您也可以实现下面这样的东西,将html标记作为字符串并返回目标值。你知道吗

def get_element(selector_string,soup):
    element = BeautifulSoup(selector_string,'lxml').body.next
    return soup.find_all(element.name,element.attrs)

print(get_element('<div non_class="first">',soup))

相关问题 更多 >