Fessの増分クロールでnofollowを維持する修正と注意点

ページにnofollowを指定しているのに、2回目のクロールからリンク先が検索対象に入ってしまう問題を修正しました。変更のないページを増分クロールするときにも、最初のクロールで判断した「リンクをたどらない」という扱いを維持するための変更です。

変更のないページでもリンクをたどらない

初回の取得ではrobots metaタグやX-Robots-Tagヘッダーを読み、nofollowならリンク先をキューへ追加しません。一方、HEADで更新がないと判断した場合や、条件付きGETが304を返した場合は、本文を解析せず保存済みのanchorからリンクを処理します。従来はnofollowページにもanchorが残り、そこでリンク先を再びクロールしていました。

修正後はnofollowページをインデックスするときにanchorを空にします。本文を省略する増分クロールでも、たどるリンクが残らなくなります。nofollowのないページでは従来どおり保存済みリンクを使います。

指定方法と初期値

クロール先のHTMLで、ページ全体の指定を使います。

<meta name="robots" content="index, nofollow">

HTTPヘッダーのX-Robots-Tag: nofollowも対象です。Fessのcrawler.ignore.robots.tagsの初期値はfalseで、robotsタグを無視しない設定です。この修正のための新しい設定キーはありません。

nofollowはリンク追跡の指定で、ページ自体のインデックスを禁止する指定ではありません。ページを検索結果から除外するnoindexとは区別して運用してください。個々のaタグのrel=”nofollow”を新たに解釈する修正でもありません。

既存インデックスへの反映

すでに保存されたanchorは自動で消えません。修正を含むビルドでページの本文を再取得・解析し、文書を更新する必要があります。増分クロールで変更なしと判定され続けるページは、増分クロールを無効にして再取得するなど、本文を取り直す運用を検討してください。リンク先の既存文書を削除する処理も、このPRには含まれません。

更新後のnofollowページは、リンク先URLを指定するanchor:<URL>検索には一致しなくなります。また、Last-Modifiedを更新せずX-Robots-Tagだけを変えた場合などは、増分クロールで指定変更を検知できない点も従来どおりです。

関連PR

Fessのテーマ配信とHTTPエラー応答を改善する

FessのStaticテーマ配信で、公開を禁止したファイルのチェックを見直しました。あわせて、エラーページのHTTPステータスと、壊れたリクエストパラメーターへの応答を修正しています。テーマを運用する際の安全性と、障害を判断しやすい応答に関わる変更です。

パスを解決した後に公開可否を判定する

テーマのtheme.ymlやREADME、ドットで始まるファイルなどは、配信時の拒否リストで公開を防いでいます。しかし従来は生のリクエストURIで判定していたため、重複スラッシュ、ドットのパス、パーセントエンコードなどの表記と、サーブレットコンテナが解決したファイルのパスが一致しない場合がありました。

今回、コンテナが解決したパスでテーマの配信経路を判断し、拒否対象のファイル名を確認します。非アクティブなテーマに属するファイルでも、拒否リストの対象なら404を返します。通常のJavaScriptやCSSなどのアセットは引き続き配信します。

拒否リストはすべてのドキュメントを非公開にする機能ではありません。例えばDESIGN.mdのようにリストにない名前は対象外です。テーマ内に公開すべきでないファイルを置く場合は、配信対象の確認も必要です。

エラーページとHTTPステータスを一致させる

従来は/error/404や/error/not_foundでもHTTP 500を返す場合がありました。数値コードと名前の表記を整理し、例えば次のように応答します。

パスHTTPステータス
/error/404404
/error/not_found404
/error/400400
/error/502502

専用の画面がないコードでもHTTPステータスは維持し、近いエラーページを表示します。例えば401ではアクセス拒否の画面、502ではサーバーエラーの画面を使います。不明な名前などは従来どおり500です。

読み取れないパラメーターを400として扱う

不正なパーセントエンコードなどを含むパラメーターは、サーバー内部の不具合とは区別してHTTP 400を返すようにしました。API v2ではinvalid_requestのエラー形式を使い、他の画面では通常の400応答にします。フォームのサイズ制限を超えた場合は413を返します。

これにより、監視で500を数えている環境でも、壊れたリンクや不正な入力と、アプリケーションの障害を区別しやすくなります。他の例外まで400に変換するものではありません。

今回の対応を含むビルドを適用した後は、テーマの通常画面とアセットに加えて、404などの応答も確認するとよいと思います。

関連PR

FessのWebクロールでHTTPヘッダーの文字コードを反映する

Shift_JISやEUC-JPのページをFessでクロールしたとき、ブラウザーでは読めるのに検索結果のタイトルや本文が文字化けすることがあります。HTTPヘッダーだけで文字コードを指定しているページを正しく扱うため、fess-crawlerのHTTPクライアントとHTML解析処理を修正しました。

HTTPヘッダーのcharsetを使う

従来は文字コードをContent-Encodingから読み取っていました。このヘッダーはgzipなどの圧縮方式を表すもので、文字コードの指定ではありません。修正後はContent-Typeのcharsetを読み取り、HTML側に文字コード指定がない場合も解析処理へ引き継ぎます。HttpClient 4と5の両方が対象です。

Content-Type: text/html; charset=Shift_JIS

例えば実際の本文がShift_JISで、HTMLにmeta charsetがなく、上記のヘッダーだけがあるページが対象になります。EUC-JPも同じ考え方です。新しい有効化設定は追加されていません。

初期値と優先順位

HTML内のmeta charsetがある場合は、その指定が従来どおり優先されます。meta指定がなければクライアントが報告した文字コードを使います。HTTP応答のcharsetが未指定、未対応、または不正な名前の場合の初期値はUTF-8です。文字コードを自動推定する機能ではないので、何も宣言していないShift_JISのページは引き続き文字化けします。

HtmlTransformerのdefaultEncodingは、クライアントからも文字コードが報告されていない場合だけ使われます。HTTPクライアントは未指定時もUTF-8を報告するため、defaultEncodingだけでHTTPページの未指定文字コードを上書きできるとは考えないでください。

クロール先で確認すること

文字化けがあれば、まず応答ヘッダーとHTMLのmeta charset、実際のファイルの文字コードを照合します。ヘッダーもmetaもないページには正しい指定を追加し、本文を再取得してインデックスを更新します。誤ったcharsetを送るサーバーも、ヘッダーが尊重されるようになるため修正が必要です。

ファイル、FTP、SMB、S3、GCS経由のHTMLにも、meta指定がない場合はクライアントの設定charsetが引き継がれます。これらの初期値もUTF-8です。この変更はHTML標準に合わせてヘッダーをmetaより優先する変更ではなく、既存の優先順位を維持しています。

関連PR