使用美丽汤查找所有链接并按链接目标 (href) 分组



我正在使用BeautifulSoup包来解析HTML正文以搜索所有<a>标签。我正在尝试做的是收集所有链接,并按<a>目标(href)对它们进行分组。

例如:如果http://www.google.com在HTML正文中列出两次,那么我需要将链接组合在一起并列出<a>data-name属性。(data-name是我的编辑器在用户命名其链接时添加的内容)。

def extract_links_from_mailing(mailing):
    content = "%s %s" % (mailing.html_body, mailing.plaintext)
    pattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')
    links = []
    soup = BeautifulSoup(content, "html5lib")
    for link in soup.findAll('a'):
        if not link.get('no_track'):
            target = link.get('href')
            name = link.get('data-name')
            link_text = unicode(link)
            if any([
                not target,
                'example.net' in target,
                target.startswith('mailto'),
                '{' in target,
                target.startswith('#')
            ]):
                continue
            target = pattern.search(target)
            # found a target and the target isn't already apart of the list
            if target and not any(l['target'] == target.group() for l in links):
                links.append({
                    'name': name,
                    'target': target.group()
                })
    return links

上面的输出如下所示:

[
    {
        "name": "Goog 1",
        "target": "https://www.google.com"
    },
    {
        "name": "Yahoo!",
        "target": "http://www.yahoo.com"
    },
    {
        "name": "Goog 2",
        "target": "https://www.google.com"
    }
]

我想要实现的目标:

[
    {
        "target": "https://www.google.com",
        "names": ["Goog 1", "Goog 2"]
    },
    {
        "target": "http://www.yahoo.com",
        "names": ["Yahoo!"]
    },
]
您可以使用

collections.defaultdict对目标进行分组:

from collections import defaultdict 
links = defaultdict(set)
for link in soup.findAll('a'):
    ...
    if target:
        links[target.group()].add(name)

因此,links将包含一个字典,其中键将target s和值 - name s的集合。

最新更新