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

时间:2015-03-16 16:17:22

标签: python beautifulsoup

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

例如:如果http://www.google.com在HTML正文中列出两次,那么我需要将链接组合在一起并列出<a>的{​​{1}}属性。 (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"
    }
]

1 个答案:

答案 0 :(得分:0)

您可以使用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的集合。