python - 查找包含给定单词的最多提及次数的 HTML 元素

标签 python html dom html-parsing cluster-analysis

我有一个 HTML 文档,我想找到最接近给定词的最大提及簇的 HTML 元素。

使用以下 HTML:

<body>
    <p>
        Hello <b>foo</b>, I like foo, because foo is the best.
    <p>
    <div>
        <blockquote>
            <p><strong>Foo</strong> said: foo foo!</p>
            <p>Smurfs ate the last foo and turned blue. Foo!</p>
            <p>Foo foo.</p>
        </blockquote>
    </div>
</body>

我想要一个函数

find_largest_cluster_wrapper(html, word='foo')

...这将解析 DOM 树并返回我 <blockquote>元素,因为它包含最大密度的 foo 提及并且它是最接近的包装器。

第一个<p>包含 foo 3 次,<b>只有一次,内部 <p> s 包含 foo 3 次,两次又两次,<strong>只有一次。但是<blockquote>包含 foo 4 次。 <div>也是如此,但它不是最接近的包装器。 <body>元素的提及次数最多,但聚类过于稀疏。

没有集群的直接实现总是给我 <html><body>或类似的东西,因为此类元素总是具有最多的请求提及次数,并且可能是最接近它们的包装器。但是,我需要采用最大集群的东西,因为我只对网页中单词密度最高的部分感兴趣。

解析部分我不是很好奇,beautifulsoup4可以很好解决或其他图书馆。我想知道一种有效的聚类算法。我在谷歌上搜索了一会儿,我想 clustering packagescipy可能会有帮助,但我不知道如何使用它。谁能推荐我最好的解决方案并将我推向正确的方向?例子会非常棒。


嗯,一般来说很难回答这样的问题,因为正如您所指出的,条件是模糊的。所以,更具体地说:

通常,文档可能只包含一个这样的簇。我的目的是找到这样的集群并获取它的包装器,以便我可以对其进行操作。这个词也可以在页面的其他地方提到,但我正在寻找一个显着的这样的词群。如果有两个或更多值得注意的集群,那么我必须使用外部偏见来决定(检查标题、页面标题等)。这个集群值得注意是什么意思?这正是我刚才介绍的意思 - 没有“认真的”竞争对手。如果竞争对手是认真的还是不认真的,我可以提供一些数字(比率),例如如果有 10 个集群和 2 个集群,差异将是 80%。我可以说,如果有一个集群的差异大于 50%,那将是值得注意的集群。这意味着,如果它是 5 个簇,另一个是 5 个簇,函数将返回 None。 (无法决定)。

最佳答案

所以这里有一个方法:

|fitness(node, word) = count of word in node text if node is a leaf
|fitness(node, word) = sum(fitness(child, word) for child in children) / 
                         count of overall elements in node tree

这里是:

import lxml.html

node = """<html><body>
    <p>
        Hello <b>foo</b>, I like foo, because foo is the best.
    <p>
    <div>
        <blockquote>
            <p><strong>Foo</strong> said: foo foo!</p>
            <p>Smurfs ate the last foo and turned blue. Foo!</p>
            <p>Foo foo.</p>
        </blockquote>
    </div>
</body></html>"""

node = lxml.html.fromstring(node)

def suitability(node, word):
    mx = [0.0, None]
    _suitability(node, word, mx)
    return mx[1]

def _suitability(node, word, mx):

    children = node.getchildren()
    sparsity = 1
    result = float(node.text_content().lower().count(word))
    for child in children:
        res, spars = _suitability(child, word, mx)
        result += res
        sparsity += spars
    result /= sparsity
    current_max, max_node = mx
    if current_max < result:
        mx[0] = result
        mx[1] = node
    return result, sparsity

print suitability(node, 'foo')

它为我们提供了 blockquote 元素作为最适者。并且通过调整评分函数,您可以更改所需集群的参数。

关于python - 查找包含给定单词的最多提及次数的 HTML 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13346408/

相关文章:

python - 我刚收到一条以前从未见过的大型错误消息,它是什么意思?

Javascript 转换未按顺序执行

javascript - 在不使用 insertNode 的情况下在插入符处粘贴 HTML

javascript - 为新创建的 DOM 对象获取准确的尺寸

javascript - 为什么我的脚本不会在鼠标单击时更新?

python - 如何在 python 中从游标中删除和返回值

python - 从unittest.TestCase切换到tf.test.TestCase后的幻像测试

javascript - 在标记中心添加圆圈

java - Gwt 中的多个 Html 页面

python - 重命名字典列表中的键