【发布时间】:2010-03-04 00:00:14
【问题描述】:
我目前正在为各种文本数据抓取一个网站(当然是经过许可的)。我看到的问题是某些字符在此过程中未正确编码。这在撇号 (') 中尤为突出:导致以下字符:.
目前,我使用以下代码从抓取的数据中转换各种 HTML 实体:
htmlentities($content, ENT_COMPAT, 'UTF-8', FALSE)
有没有更好的方法来处理这种事情?
【问题讨论】:
我目前正在为各种文本数据抓取一个网站(当然是经过许可的)。我看到的问题是某些字符在此过程中未正确编码。这在撇号 (') 中尤为突出:导致以下字符:.
目前,我使用以下代码从抓取的数据中转换各种 HTML 实体:
htmlentities($content, ENT_COMPAT, 'UTF-8', FALSE)
有没有更好的方法来处理这种事情?
【问题讨论】:
HTML 实体有两个目标:
它们并不完全是一个编码工具。
如果你想从一个字符集转换成另一个字符集,我建议你使用iconv()。但是,您必须知道源字符集和目标字符集。源字符集应在 Content-Type 响应标头中提及,目标字符集是您在启动站点时决定的(尽管在您的情况下,UTF-8 看起来是最合理的选择)。
【讨论】:
您不想立即使用 htmlentities,我会在您存储之前的最后一点对数据使用它。您将遇到的问题之一是人们并不总是正确地编码他们的实体。不是每个人都使用™,他们只是将商标复制进去。如果你输入一些逻辑来尝试抓取他们输入的任何内容并正确编码,你可能会更好。例如:
$patterns = array();
$patterns[0] = '/—/';
$patterns[1] = '/&nsbsp;/';
$patterns[2] = '/®/';
$replacements = array();
$replacements[2] = '&151;';
$replacements[1] = '&160;';
$replacements[0] = '&174;';
$ourhtml = preg_replace($patterns, $replacements, $html);
您可以找到所有“陷阱”字符,如破折号和单引号、撇号等,并手动对其进行编码,以及对实体(文本或数字)使用一套标准。
您也可以使用正则表达式来做同样的事情,这可能是一个更优雅的解决方案。但我的建议是花一些时间手动过滤掉你不想要的东西,然后你就知道你的数据会按照你喜欢的方式准备好。
【讨论】:
htmlentities 接受文字 &amp; 并将其转换为 &amp;(例如,它对 < 执行相同的操作等等)。您的代码似乎采用实体编码的字符串并将它们从命名版本转换为十进制版本。我不认为这是海报所遇到的问题。此外,您在这里使用preg_replace 完全是多余的,str_replace 就足够了。
根据提供的信息提出建议有点困难。你能提供一个文本的示例 sn-p 吗?
如果做不到这一点,我将采用霰弹枪方法(例如,提出一堆建议并希望其中一个成功)
首先,您确定您正在访问的页面是用 UTF-8 编码的吗? mb_detect_encoding 说什么?
一个选项(根据您的需要可能不起作用)是使用iconv 和TRANSLIT 选项将字符转换为更易于使用PHP 处理的字符。您还可以查看使用 mb_* 函数来处理多字节字符串。
您确定htmlentities 是问题所在吗?如果内容是 UTF-8,并且您的网站设置为使用 ISO-8859-1,您将看到奇怪的字符。检查您的浏览器使用的编码,以确保它与您正在生成的字符的编码相匹配。
【讨论】:
只要您将false 作为最后一个参数传递,我认为使用 htmlentities() 没有任何问题。这将确保您不会对任何内容进行两次编码(例如将 &amp;amp; 转换为 &amp;amp;)。
【讨论】: