python - 使用 BeautifulSoup 检测 URL 并添加 anchor 标记

标签 python python-3.x beautifulsoup

我正在使用 BeautifulSoup 解析 html。给定以下 HTML:

<!DOCTYPE html>
<html>
    <body>
        <p>An absolute URL: https://www.w3schools.com</p>
    </body>
</html>

我希望将其转换为:

<!DOCTYPE html>
<html>
    <body>
        <p>An absolute URL: <a href="https://www.w3schools.com" target="_blank">https://www.w3schools.com</a></p>
    </body>
</html>

到目前为止编写的代码:

def detect_urls_and_update_target(self, root): //root is the soup object
        for tag in root.find_all(True):
            if tag.name == 'a':
                if not tag.has_attr('target'):
                    tag.attrs['target'] = '_blank'
            elif tag.string is not None:
                  for url in re.findall(self.url_regex, tag.string): //regex which detects URLS which works
                      new_tag = root.new_tag("a", href=url, target="_blank")
                      new_tag.string = url
                      tag.append(new_tag)

这会添加所需的 anchor 标记,但我无法弄清楚如何从标记中删除原始 URL。

最佳答案

您可以使用 BeautifulSoup 来重建父内容,如下所示:

from bs4 import BeautifulSoup
import re

html = """<!DOCTYPE html>
<html>
    <body>
        <p>An absolute URL: https://www.w3schools.com</p>
        <p>Another link: https://stackoverflow.com/questions/50413693/detect-url-and-add-anchor-tags-using-beautifulsoup%22</p>
        <div><div>some div</div>Hello world from https://www.google.com</div>
    </body>
</html>"""

soup = BeautifulSoup(html, "html.parser")
re_url = re.compile(r'(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)')

for tag in soup.find_all(text=True):
    tags = []
    url = False

    for t in re_url.split(tag.string):
        if re_url.match(t):
            a = soup.new_tag("a", href=t, target='_blank')
            a.string = t
            tags.append(a)
            url = True
        else:
            tags.append(t)

    if url:
        for t in tags:
            tag.insert_before(t)
        tag.extract()

print(soup)    
print()

这将显示以下输出:

<!DOCTYPE html>

<html>
<body>
<p>An absolute URL: <a href="https://www.w3schools.com" target="_blank">https://www.w3schools.com</a></p>
<p>Another link: <a href="https://stackoverflow.com/questions/50413693/detect-url-and-add-anchor-tags-using-beautifulsoup%22" target="_blank">https://stackoverflow.com/questions/50413693/detect-url-and-add-anchor-tags-using-beautifulsoup%22</a></p>
<div><div>some div</div>Hello world from <a href="https://www.google.com" target="_blank">https://www.google.com</a></div>
</body>
</html>

首先使用正则表达式分割包含文本的任何标签来查找任何 URL。对于每个条目,如果它是 URL,则将其在列表中替换为新的 anchor 标记。如果未找到 URL,请保留该标记。接下来,在现有标签之前插入每个更新标签列表,然后删除现有标签。


要跳过 DOCTYPE 中的任何 URL,可以按如下方式更改 find_all():

from bs4 import BeautifulSoup, Doctype

...

for tag in soup.find_all(string=lambda text: not isinstance(text, Doctype)):

关于python - 使用 BeautifulSoup 检测 URL 并添加 anchor 标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50413693/

相关文章:

python - 找出 10 个最常出现的形态词

python - 使用CMD终端时Python无法显示希伯来语

python - 无法提取文本并找到所有由 BeautifulSoup 提供的内容

python - 计算Python程序的数据依赖图

python - 查找是否已经在python中加载了一个类?

python - 对象成员的 Cython 缓冲区声明

python - Python 3 中使用 sys 模块的奇怪行为

python-3.x - PyQt5:QAction功能可以通过QPushButton触发吗

python - bs4.FeatureNotFound : . .. lxml 与 MacOS 和 Conda/Python 3

html - 在亚马逊主要网站上搜索一个词(解析)