Posted at

RSSフィードの取得エラーが出たときの問題の切り分けかた

More than 1 year has passed since last update.


:book: はじめに

この記事は、オールアバウト Advent Calendar 2016の8日目の記事です。

先日は@takkyさんのWelcome to Laravel Voyagerでした。

新卒1年目エンジニアの @amymd が、RSSフィード関係の実装を通して得た知見を共有できればと思います。


:warning: 導入〜RSSフィード取得に失敗してる!さあどうしよう?

ある日のこと、自分はいつも通り会社に出社し、メールを確認しました。

すると、定期的にRSSを取得している処理がどうやら失敗しているようです。

RSS取得に失敗しているからといえ、この時点では、まだどこに問題があるかわかりません。

RSS取得の処理になにか問題あるかもしれませんし、RSS自体に問題があるのかもしれません。

その問題の切り分けをしていきましょう :muscle:


:pencil: エラーログを確認する

基本中の基本ですが、まずはエラーログの内容を確認します。

Logentriesでログの管理を行っているため、サーバにSSHせずともブラウザから簡単にログを確認できます。大変便利です。

This XML document is invalid.等のXMLエラーの場合、RSSに問題があるかもしれません。

プログラムの処理に関するエラーが出ていると、RSSの取得処理に問題があるかもしれません。

まずはログの内容から、どちらの問題なのか目処を付けてみます。


:eyes: RSSのどこが問題なのか調査する

RSSの問題だと思ったら、まずは該当のRSSをブラウザからアクセスしてみて、何かエラーが出てないか確認してみます。

また、特にブラウザ上では問題なくても、Validatorでチェックするとエラーが出ていることがあります。

W3C Validator

上記のURLでXMLに問題があるかチェックすることができます。

RSSのXMLやURL等を貼り付けて調べてみると、具体的にどの行でどのようなエラーが発生しているのかが表示されます。

以下は、自分が遭遇した問題の例をあげます。


例:CDATAセクションの中でCDATAセクションを呼び出していた

CDATAセクションとは、セクション内にマークアップが含まれず文字データのみを取り扱うことを示すものです。

https://msdn.microsoft.com/ja-jp/library/ms256076(v=vs.120).aspx

<![CDATA[An in-depth look at creating applications with XML, using <, >,]]>

このCDATAセクション内に、さらにCDATAセクションが埋め込まれていて、終端の]]>を誤認識してしまい、その結果下記のようなエラーが出ていました。

error on line 105 at column 3342: Opening and ending tag mismatch: encoded line 0 and script


例:「見えない文字」が原因で「This XML document is invalid.」

This XML document is invalid, likely due to invalid characters.

RSSを取得しようとすると上記のエラーが発生しておりました。

これは、XMLでは有効ではない文字列が含まれている、というエラーです。

原因を特定するために、先ほど示したW3C Validatorを使用してみました。

しかし、そのエラーが発生している行を確認しても、あやしい文字はどこにも含まれていませんでした。

こういう時は、Sublime Textなどのエディタに、その箇所をコピペしてみます(自分はmiというエディタに貼り付けました)。

すると、以下のように「見えない文字」が表示されました。

93078497-f29d-f525-0009-05f0f12e411c.png

※赤い背景に1Cとなっている箇所が、通常では見えない文字

このエディタ上で上記の文字を削除し、再度RSSを読み込んでみると……正常に取得できました!

原因はどうやらこの「見えない文字」のようです。


:thinking: なぜこのような見えない文字が含まれてしまうのか

これは一概に「これが原因だ!」とは言い切れないのですが、

個人的な経験からすると、このような「見えない文字」は、OCRにかけたPDFからコピペしてくるときに紛れていたり、Macで作成したPDFをWindowsからコピペするときに紛れていたり、ということが多いような気がします。

それが原因なのかは定かではありませんが……。

他には、制御文字(BackSpaceなど)が原因ということもあるみたいです。

WordPressのRSSフィードエラーは制御文字が原因?

ぱっと見てXMLに問題がなさそうであれば、このような症状を疑うと良いと思います。


:inbox_tray: RSSを取得する処理に問題がある場合

RSSに特に問題が無いようであれば、RSSを取得する処理に問題があるかもしれません。

その処理を見直してみましょう。

以下は、自分が遭遇した問題の例をあげます。


例:RSS取得の処理に時間が掛かってタイムアウト

自分はLaravelというPHPのWebフレームワークを使用しており、 RSSをパースするLaravelのライブラリとしてFeeds を利用していました。

すると、とあるRSSを取得する際に、表示まで時間が掛かってしまい、下記のようなエラーが出てしまいました。

cURL error 28: Operation timed out after 10000 milliseconds with 0 bytes received

このライブラリでは、内部でSimplePieというRSSやAtomをパースするライブラリを使っており、cURLのデフォルトのタイムアウトの処理時間が10000msec…つまり10秒となっていました。

この設定を書き換えるには、Feedsライブラリを直接書き換える必要があるので、注意する必要があります。

(SimplePieオブジェクトなので $this->simplepie->set_timeout(60)のようにセットするとタイムアウトの時間を60秒にセットすることができます)


FeedsFactory.php

public function make($feed_url = [], $limit = 0, $force_feed = false) {

$this->simplepie = new SimplePie();
$this->simplepie->set_timeout(60); // タイムアウトの秒数を指定


:green_book: おわりに

今回はRSSが取得できなかったときの問題とその対応例を紹介しましたが、RSSフィードをパースして値を処理する際の問題など、まだまだあるかと思います。

中には、RSSの問題だとわかりつつも、RSSを処理する側でどうにかできたり、逆にRSSを修正しないとどうにもできなかったり…。

今回自分が得た知見が共有されて、少しでもみなさんの開発の一助となれば幸いです。