Python BeautifulSoup-通过标记内的文本进行搜索

Python BeautifulSoup-通过标记内的文本进行搜索,python,regex,beautifulsoup,Python,Regex,Beautifulsoup,请注意以下问题: import re from bs4 import BeautifulSoup as BS soup = BS(""" <a href="/customer-menu/1/accounts/1/update"> Edit </a> """) # This returns the <a> element soup.find( 'a', href="/customer-menu/1/accounts/1/update"

请注意以下问题:

import re
from bs4 import BeautifulSoup as BS

soup = BS("""
<a href="/customer-menu/1/accounts/1/update">
    Edit
</a>
""")

# This returns the <a> element
soup.find(
    'a',
    href="/customer-menu/1/accounts/1/update",
    text=re.compile(".*Edit.*")
)

soup = BS("""
<a href="/customer-menu/1/accounts/1/update">
    <i class="fa fa-edit"></i> Edit
</a>
""")

# This returns None
soup.find(
    'a',
    href="/customer-menu/1/accounts/1/update",
    text=re.compile(".*Edit.*")
)
对。根据,soup使用正则表达式的匹配函数,而不是搜索函数。因此,我需要提供DOTALL标志:

pattern = re.compile('.*Edit.*')
pattern.match('\n Edit\n')  # Returns None

pattern = re.compile('.*Edit.*', flags=re.DOTALL)
pattern.match('\n Edit\n')  # Returns MatchObject
好的。看起来不错。让我们一起喝汤试试

soup = BS("""
<a href="/customer-menu/1/accounts/1/update">
    <i class="fa fa-edit"></i> Edit
</a>
""")

soup.find(
    'a',
    href="/customer-menu/1/accounts/1/update",
    text=re.compile(".*Edit.*", flags=re.DOTALL)
)  # Still return None... Why?!

现在,当我想查找上面的元素时,我只需运行
find_by_text(soup,'Edit','a',href='/customer menu/1/accounts/1/update')
问题在于您的

虽然string用于查找字符串,但您可以将其与 查找标记的参数:Beauty Soup将查找所有 .string与字符串的值匹配。此代码查找标记 谁的.string是“Elsie”:

soup.find_all("a", string="Elsie")
# [<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>]
(……)

如果标签包含多个内容,那么不清楚是什么 .string应引用,因此.string定义为无:

print(soup.html.string)
# None
这正是你的情况。您的

""")
links=soup.find_all('a',href=“/customer menu/1/accounts/1/update”)
对于链接中的链接:
如果link.find(text=re.compile(“编辑”):
链接
打破
打印(链接)
我认为没有太多指向
/customer menu/1/accounts/1/update
的链接,因此应该足够快。

如果
文本包含对
的“编辑”,则可以传递返回
True
的链接。查找

In [51]: def Edit_in_text(tag):
   ....:     return tag.name == 'a' and 'Edit' in tag.text
   ....: 

In [52]: soup.find(Edit_in_text, href="/customer-menu/1/accounts/1/update")
Out[52]: 
<a href="/customer-menu/1/accounts/1/update">
<i class="fa fa-edit"></i> Edit
</a>

在一行中使用lambda

soup.find(lambda tag:tag.name=="a" and "Edit" in tag.text)

由于bs4.7.1,您可以使用:contains css伪类选择器以节点的文本为目标

from bs4 import BeautifulSoup as BS

soup = BS("""
<a href="/customer-menu/1/accounts/1/update">
    Edit
</a>
""")
single = soup.select_one('a:contains("Edit")').text.strip()
multiple = [i.text.strip() for i in soup.select('a:contains("Edit")')]
print(single, '\n', multiple)
从bs4导入美化组作为BS
汤=BS(“”)
""")
single=soup.select_one('a:contains(“Edit”)).text.strip()
multiple=[i.text.strip()表示汤中的i.select('a:contains(“Edit”))]
打印(单个,“\n”,多个)

对。好的。这就解释了问题的原因。谢谢。您将如何补救?目标仍然是找到包含文本“Edit”的标记“这不正是我在做的吗?您可以使用find方法的text参数。看看您的示例,这将产生与我的相同的结果code@Eldamir不同之处在于我在查看
标记内部。你自己试试看,效果很好。当我们正在寻找的标签中有任何br标签时,这会有所帮助,因为汤。在这种情况下,“全部查找”(“a”,string=“Elsie”)将失败。当你使用BeautifulSoup 3时,这也会有所帮助
import re
from bs4 import BeautifulSoup as BS

soup = BS("""
<a href="/customer-menu/1/accounts/1/update">
    <i class="fa fa-edit"></i> Edit
</a>
""")

links = soup.find_all('a', href="/customer-menu/1/accounts/1/update")

for link in links:
    if link.find(text=re.compile("Edit")):
        thelink = link
        break

print(thelink)
In [51]: def Edit_in_text(tag):
   ....:     return tag.name == 'a' and 'Edit' in tag.text
   ....: 

In [52]: soup.find(Edit_in_text, href="/customer-menu/1/accounts/1/update")
Out[52]: 
<a href="/customer-menu/1/accounts/1/update">
<i class="fa fa-edit"></i> Edit
</a>
def Edit_in_text(tag):
    return tag.name == 'a' and 'Edit' in tag.get_text()
soup.find(lambda tag:tag.name=="a" and "Edit" in tag.text)
from bs4 import BeautifulSoup as BS

soup = BS("""
<a href="/customer-menu/1/accounts/1/update">
    Edit
</a>
""")
single = soup.select_one('a:contains("Edit")').text.strip()
multiple = [i.text.strip() for i in soup.select('a:contains("Edit")')]
print(single, '\n', multiple)