【问题标题】:Counting words on a html web page using php使用 php 计算 html 网页上的单词
【发布时间】:2011-03-29 23:29:00
【问题描述】:

我需要一个 PHP 脚本,它获取网页的 URL,然后回显一个单词被提及的次数。

示例

这是一个通用的 HTML 页面:

<html>
<body>
<h1> This is the title </h1>
<p> some description text here, <b>this</b> is a word. </p>
</body>
</html>

这将是 PHP 脚本:

<?php
htmlurl="generichtml.com";
the script here
echo(result);
?>

所以输出将是这样的表格:

WORDS       Mentions
This        2
is          2
the         1
title       1
some        1
description 1
text        1
a           1
word        1

这就像搜索机器人在网上冲浪时所做的那样,所以,你知道如何开始,或者更好的是,你有一个 PHP 脚本已经这样做了吗?

【问题讨论】:

    标签: php html scripting bots


    【解决方案1】:

    在从字符串中剥离所有 HTML 标记后,下面的一行将执行不区分大小写的字数统计。

    Live Example

    print_r(array_count_values(str_word_count(strip_tags(strtolower($str)), 1)));
    

    要获取页面的源代码,您可以使用cURLfile_get_contents()

    $str = file_get_contents('http://www.example.com/');
    

    由内而外:

    1. 使用strtolower() 将所有内容变为小写。
    2. 使用strip_tags()去除HTML标签
    3. 使用str_word_count() 创建一个单词数组。参数 1 返回一个数组,其中包含在字符串中找到的所有单词。
    4. 使用array_count_values() 通过计算单词数组中每个值的出现次数来捕获多次使用的单词。
    5. 使用print_r() 显示结果。

    【讨论】:

    • 好吧,但是scriptstyle 标签呢?
    • @Yijiang - 如果你想单独处理这些,很多 HTML 解析器已经存在。重写一个没有意义,因为它们是挑剔和复杂的野兽。
    【解决方案2】:

    前面的代码是一个起点。下一步是使用正则表达式删除 html 标签。寻找 ereg 和 eregi 函数。样式和脚本标签需要一些其他技巧(您必须删除内容) 点和逗号也必须删除...

    【讨论】:

    • ereg 已被弃用,首先,正则表达式不是解析任意 HTML 的合适工具。
    • 如果正则表达式存在于 perl O.O 中,如何弃用它们?
    • 答案并不总是按时间顺序在 SO 上列出,所以 previous code 不是很有帮助。网址链接(每个答案都有一个唯一的)或作者参考更好。
    • 正则表达式没有被弃用,只有 ereg 扩展。改用 PCRE(preg_ 函数族)。
    【解决方案3】:

    下面的脚本会读取远程 url 的内容,去除 html 标签,并统计其中每个唯一单词的出现次数。

    警告:在您的预期输出中,“This”的值为 2,但下面的内容区分大小写,因此“this”和“This”都被记录为单独的单词。如果原始大小写对您的目的不重要,您可以在处理之前将整个输入字符串转换为小写。

    此外,由于只对输入运行基本的 strip_tags,格式错误的标签不会被删除,因此假设您的源 html 是有效的。

    编辑: Charlie 在 cmets 中指出,head 部分之类的内容仍将被计算在内。在user notes of the strip_tags function 中定义的函数的帮助下,这些现在也得到了处理。

    generichtml.com

    <html>
    <body>
    <h1> This is the title </h1>
    <p> some description text here, <b>this</b> is a word. </p>
    </body>
    </html>
    

    parser.php

    // Fetch remote html
    $contents = file_get_contents($htmlurl);
    
    // Get rid of style, script etc
    $search = array('@<script[^>]*?>.*?</script>@si',  // Strip out javascript
               '@<head>.*?</head>@siU',            // Lose the head section
               '@<style[^>]*?>.*?</style>@siU',    // Strip style tags properly
               '@<![\s\S]*?--[ \t\n\r]*>@'         // Strip multi-line comments including CDATA
    );
    
    $contents = preg_replace($search, '', $contents); 
    
    $result = array_count_values(
                  str_word_count(
                      strip_tags($contents), 1
                      )
                  );
    
    print_r($result);
    

    ?>

    输出:

    Array
    (
        [This] => 1
        [is] => 2
        [the] => 1
        [title] => 1
        [some] => 1
        [description] => 1
        [text] => 1
        [here] => 1
        [this] => 1
        [a] => 1
        [word] => 1
    )
    

    【讨论】:

    • 这是一个干净的解决方案,但样式和脚本标签内容仍然存在。比所有页面的头部都应该被删除。
    • 如果你使用 regExpressions 无效的 html 代码可以被分析 ;) 标点仍然是一个问题
    • 请不要使用正则表达式解析 HTML。
    • 顺便说一句,strip_tags()(您使用的)已经删除了多行 HTML cmets 和 CDATA - codepad.org/gpdden0T php.net/manual/en/function.strip-tags.php
    【解决方案4】:

    这是一项复杂的工作,您不应该独自尝试。

    您必须提取不属于标签/cmets 且不是scriptstyle 等元素的子元素的文本。为此,您还需要一个宽松的 HTML 解析器(就像在 libxml2 中实现并在 DOMDocument 中使用的那个。

    然后你必须tokenize 文本,这提出了自己的挑战。最后,在继续计算条款之前,您可能会对某种形式的 stemming 感兴趣。

    我建议您为此使用专门的工具。我没有使用过这些,但是你可以尝试HTMLParser 进行解析和Lucene 进行标记化/词干化(Lucene 的目的是Text Retrieval,但这些操作对于构建索引是必要的)。

    【讨论】:

    • 一份复杂的工作? ConroyP 代码运行良好,并且完成了您列出的大部分内容。 HTML 有一个非常规则的语法
    • @Charlie 缺少很多东西...处理非 ASCII 编码,正确处理 HTML(我可以轻松地构建一个带有圣经转录的 HTML 文档,不会让他产生任何文字不管他的代码),一个合适的标记器(str_word_count 是非常基本的,只处理 ASCII),一个词干分析器,...
    • 词干分析器?首先为什么要添加一个无法找到每种语言的根源的词干分析器? (目的是什么?最初的问题要求一个简单的 HTML 解析器,而不是语言分析器)
    • 您可以find 多种语言的词干分析器。 OP没有说他想要阻止,但假设他想要是合法的,尤其是因为他的问题中已经存在某种形式的术语规范化(“This”和“this”被视为相同)。我想你承认其他观点......
    • 是的,我的疑虑仍在词干分析器上。您发出信号的列表中的意大利语与 30% 的意大利语单词不正确匹配,并且它包含的词汇只是 1% 的意大利语单词(我不是在开玩笑)。 Martin Porter 编写了一个对英语(也许)有用但对其他更复杂的语言不利的算法。
    【解决方案5】:

    这是我计算包含 html 标签的单词的代码:

    $sayilacak_metin = str_replace("&nbsp;", " ", $sayilacak_metin);
    $sayilacak_metin = preg_replace("/<([^>]*(<|$))/", "&lt;$1", $sayilacak_metin);
    $sayilacak_metin = strip_tags($sayilacak_metin);
    $sayilacak_metin = str_replace(chr(194)," ",$sayilacak_metin);
    $sayilacak_metin = str_replace(chr(160)," ",$sayilacak_metin);
    $sayilacak_metin = preg_replace(array('/\s{2,}/', '/[\r\t\n]/','/\r/','/\t/','/\n/'), ' ', $sayilacak_metin);
    $sayilacak_metin=trim($sayilacak_metin);
    $parca = explode(" ", $sayilacak_metin);
    $sonuc=count(array_filter($parca));
    
    • Step1:将所有nbsp转换为空格
    • Step2:修复损坏的html标签(如果不修复striptags函数会损坏字符串)
    • 第三步:去除html标签
    • Step4&5&6:清除隐藏的空格和换行符/制表符
    • Step7:修剪字符串的开头和结尾
    • Step8:将每个单词转换为数组
    • Step9:计算过滤后的数组

    【讨论】:

      猜你喜欢
      • 2018-02-26
      • 2014-06-09
      • 2010-09-17
      • 2020-07-10
      • 1970-01-01
      • 2017-06-29
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多