七月 01, 2006

Encode

这两天在用Perl写一个程序,从一个网页上抽取出某个表格的内容,然后存起来供日后使用。

取网页用LWP::UserAgent,分析表格使用HTML::TableExtract,保存使用Config::General。然而,在用Config::General读取它自己存的文件时出了问题,根源在于编码。网页编码是GB2312,而Perl的内部表示使用Unicode,所以Perl把中文字符看成是一系列奇怪的字节,而Config::General偏偏使用chr(182)作为一个特殊的标志,用来处理Here-Document。当某些中文字符恰好含有这个字节的时候,Config::General就被骗了。

一度,我只好把数据存为CSV格式。

后来在Advanced Perl Programming第二版上看到6.5节Encode后,把网页内容读入后用decode处理一下,在print出去之前再用encode处理一下,就可以了。而Config::General保存的文件本身就是Unicode,所以无需使用Encode来处理。

举个例子

use LWP::UserAgent;
use Encode;

$browser = new LWP::UserAgent;
$response = $browser->get('http://some.where');
$content = decode('euc-cn', $response->content);

这样,一个汉字就会被当成一个字,而不是一系列字节。这里euc-cn就代表gb2312,对于Encode来说它们是同义词,或者说gb2312是euc-cn的alias。

直接打印经过decode的字符串会产生警告,去掉警告的方法是再encode一下,如:

$content = encode('utf8', $content);
print $content, "\n";

2 条评论:

时间 11:44 上午 , Anonymous jzhang 说...

perl5.8.7后可以直接用
$response->decoded_content();
得到utf8编码的网页

 
时间 12:06 下午 , Blogger netcasper 说...

果然,我看了一下HTTP/Message.pm,最终还是调用了Encode,不过肯定是用decoded_content好了,一来不怕人家改编码,二来代码也精简。

 

发表评论

指向此帖子的链接:

创建链接

<< 主页