如何在抓取网络时将网页内容转换为一致的字符集?

时间:2011-11-22 20:24:46

标签: php html character-encoding web-scraping

我已就此进行了大量研究并进行了大量测试。

据我所知,只有在设置了Web服务器的情况下才会设置H​​TTP标头,并且即使开发人员不打算这样做,也可能默认使用特定的编码。只有当开发人员决定在他们的代码中这样做时才会设置元标题...这也可能由某些开发框架自动设置(如果开发人员不考虑这个问题,则会出现问题)。

我发现,如果这些设置完全存在,它们往往会相互冲突。例如。 HTTP标头表示页面为iso-8859-1,而元标记指定windows-1252。我可以假设一个取代另一个(可能是元标记),但这似乎相当不可靠。在处理数据时,似乎很少有开发人员会考虑这一点,因此动态生成的网站通常会混合编码或使用他们不打算通过来自数据库的不同编码进行编码。

我的结论是做到以下几点:

  1. 使用mb_detect_encoding()检查每个页面的编码。
  2. 如果失败,我会使用元编码(http-equiv="Content-Type"...)。
  3. 如果没有元内容类型,我使用HTTP标头(content_type)。
  4. 如果没有http内容类型,我假设为UTF-8。
  5. 最后,我使用mb_convert_encoding()转换文档。然后我抓了它的内容。 (我故意省略了要转换的编码,以避免在此讨论。)
  6. 我试图获得尽可能多的准确内容,而不仅仅是忽略网页,因为开发人员没有正确设置标题。

    您认为这种方法存在哪些问题?

    我是否会使用mb_detect_encoding()和mb_convert_encoding()方法遇到问题?

1 个答案:

答案 0 :(得分:1)

是的,你会遇到问题。 mb_detect_encoding并不可靠,请参阅以下示例:

这会输出bool(false),表示检测失败:

var_dump(mb_detect_encoding(file_get_contents('http://www.pazaruvaj.com/')));

另一个输出string(5) "UTF-8",这显然是不正确的结果。 HTTP标头和http-equiv在此网站上正确设置,并且无效UTF-8:

var_dump(mb_detect_encoding(file_get_contents('http://www.arukereso.hu/')));

我建议您应用所有可用的方法,并使用外部库(例如:http://mikolajj.republika.pl/)并使用最可能的编码。

使其更精确的另一种方法是构建特定于国家/地区的可能字符集列表,并仅使用mb_convert_encoding的字符集。与匈牙利一样,ISO-8859-2或UTF-8最有可能,其他人则不值得考虑。可以通过TLD,Content-Language HTTP标头和IP地址位置的组合来猜测国家/地区。虽然这需要一些研究工作和额外的开发,但值得努力。

mb_convert_encoding文档中的一些评论报告iconv更适合日语字符集。