RSSのparseエラーの回避(さらに追記:試行錯誤は続く…)


 cronで動かしているperlが“たまに”エラーで停止するようになった。

amazon.co.jpのRSSをピックアップするスクリプトなので、大したことはしていない。
エラーメッセージ:
not well-formed (invalid token) at line 1, column 0, byte 0 at /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/XML/Parser.pm line 187

でも、エラーになるときがある。
RSSだから、エントリの内容が影響しているのは間違いないのだが、原因を特定するには根が深すぎる。
基本的な部分はこんな感じ。

use strict;
use XML::RSS;
use LWP::Simple;
use Encode;
my $rss = new XML::RSS;
my $contents = get($url);
$rss->parse($contents);
ググってみて、対策を組み込んでみた。
最初に、制御文字を削除してみた。
my $rss = new XML::RSS;
my $contents = get($url);
$contents = tr/¥x00-¥x1F¥x7F//d; # 追加
$rss->parse($contents);
だめでしたorz


今度は、少々乱暴な感もある「エンコードしてデコードする」という方法。

my $rss = new XML::RSS;
my $contents = get($url);
Encode::from_to($contents, ‘UTF-8’, ‘euc-jp’); # 追加
Encode::from_to($contents, ‘euc-jp’, ‘UTF-8’); # 追加
$rss->parse($contents);


これで動いたようです。
これでいいのか?
動けばいいんですw
結果オーライ!
— 2012/07/05 追記… —
駄目だったorz
同じエラーだ。
原因を探るためにソースデータを保存しつつ処理させるようにするしかないか。
evalでエラーとなる場合のみソースデータを保存し、処理をスキップ、次のデータを処理するようにしてみようか。
あ~
— 2012/07/05 さらに追記… —

で、evalでエラー検出して、sleep 1;の後にリトライさせるように変更。

効果がなかった前述のエンコード&デコード部分は削除しました。
その後は問題なく動作してくれているようだ。
パースがエラーになったデータを保存する処理を組み込めば調査できるかも知れないが、それは次の機会に。
リトライすれば上手くいくパースのエラーって…?

謎は残ります…。