sitemap.xmlからurlの一覧を取得し、対象サイトの全ページのタイトルとURLを取得する

photo by rawpixel on unsplash
スポンサーリンク

webページのsitemap.xmlからそのドメイン以下にあるURLの一覧を取得し、各ページをたどって情報を取得するクローラーを作ってみました。

XMLサイトマップを利用してクロールする際には、ScrapyのsitemapSpiderを使うと楽です。

はじめに注意:
クローラー作成の際は、絶対に後述の「クロール先に迷惑をかけないための設定」を行ってください。これを怠ると普通に逮捕されたりします。
(クローラーは全く違法なものではないですし、Googleをはじめとするあらゆる企業や個人などに利用されていますが、使用方法をミスると結果的に誰かのサーバーを攻撃した、みたいになることがあります)
・この記事を見て作成したクローラーにより生じたいかなる損害、不利益など、一切関知しませんし責任も負いかねます。
・記事のサンプルコードでは、クロール対象ドメインをこのブログのものにしています。しかし、僕のブログにはクローラー避けの対策がなされているので、これのコピペじゃデータ取得に失敗すると思います。適宜、クロールしても問題ないサイトのドメインに置き換えて実行してください。
・あとごめん、タイトルに「対象サイトの全ページのurlとタイトルを取得」とありますが、対象サイトのデータ形式によっては全ページ取れないこともあります。その時はぜひいいやり方を見つけて教えてください!

XMLサイトマップとはなんぞ?

ざっくり言うと、そのサイトに含まれる記事(URL)の全リストです。
各記事について、URL以外にも最終更新日、更新頻度、重要度などの情報が含まれており、これらをXML形式で記述しているものです。

XMLサイトマップの例

引用元:sitemaps.org – プロトコル

Webの文脈で一般に「サイトマップ」という言葉が使われる際には、それが指すものは2種類あります。

①サイトマップ(人間用に見やすくフォーマットしてる記事一覧)
②XMLサイトマップ(機械というかプログラムが読みやすいフォーマットで書かれたもの)

これらは混同されがちですが全く異なるもので、両方めっちゃ大事です。

当ブログで言えば、

①サイトマップ(人間用に見やすくフォーマットしてる記事一覧)
→https://sutaba-mac.site/sitemap/

②XMLサイトマップ(機械というかプログラムが読みやすいフォーマットで書かれたもの)
→https://sutaba-mac.site/sitemap.xml/

と、それぞれ全く違うフォーマットで書かれていることが分かるかと思います。

今回の記事で扱うのは後者、②XMLサイトマップ(機械というかプログラムが読みやすいフォーマットで書かれたもの)になります。
これは主にGoogleのクローラーにサイトの内容を伝えるためのもので、SEO的に非常に重要です。

XMLサイトマップをクロールする

今回はScrapyのsitemapSpiderを使います。楽そうなので。
Scrapyって何?って方はまずこちらを。

Scrapyのインストール

もし、Scrapyがインストールされていなければ、まずはpipを使ってインストールしてください。

仮想環境を立てる

Scrapyのインストールの際には、まず仮想環境を立てることが推奨されています。

まず、下記のコマンドでvirtualenvを使って仮想環境を用意します。

$ pip install virtualenv

仮想環境を使いたいプロジェクトのディレクトリに移動し、下記のコマンドで仮想環境を作成します。

$ virtualenv myenv

仮想環境の名前(myenv)はなんでもokです。

次のコマンドで、作成した仮想環境をアクティベートします。

$ source myenv/bin/activate

コンソールで行頭に(myenv)のように表示されればokです。

次に、pipでScrapyをインストールします。

(myenv) $ pip install scrapy

下記のコマンドを打って、scrapyのバージョンが表示されればインストール成功です。

(myenv) $ scrapy version

scrapyプロジェクトの作成

(myenv) scrapy startproject sitemapExplorer

プロジェクトのディレクトリに移動しておきます。

(myenv) cd sitemapExplorer/

genspiderコマンドでspiderを作成します。

(myenv) scrapy genspider sitemap sutaba-mac.site

genspiderコマンドの引数にはそれぞれ、
scrapy genspider [spiderの名前] [クロール対象のドメイン] を指定します。

すると、spiderディレクトリ内に下記のようなspiderのテンプレが生成されているはずです。

これを、下記のように変更します。

sitemap_urls のリストで、「 XMLサイトマップをリスト形式で指定。」とコメントしてるにもかかわらず、思いっきり”robots.txt”という関係なさそうなurlを指定してますが、robots.txtの中身にはXMLサイトマップの場所が書かれていることがあるので、これを指定してもOKです。

もちろん、素直にsitemap.xmlを指定してもok。

また、robots.txtとsitemap.xmlを同時に指定した場合でも”no more duplicates will be shown”(ダブったやつはもう表示しねえからな)とのメッセージが出たので問題なさそうではある。

クロール先に迷惑をかけないための設定(重要)

settings.pyを開いて、以下の3行を探してください。
デフォルトではコメントアウトされていることがあるので、忘れずにコメントを外して有効にしておきましょう。
これをしないで、クロール先に迷惑をかけた場合、最悪逮捕されるのでマジで注意です。

それから、ユーザーエージェントの設定に自分の連絡先を明示しておくのがベターです。

クロールの実行

下記のコマンドでクロール実行。
-o オプションを使うと、実行結果を.txt, csvなどの形式で出力できます。

$ scrapy crawl sitemap -o sitemaps.csv

うまくいってたら、sitamaps.csvって名前のファイルに実行結果が格納されてるはず。

課題とか手をつけれなかったものとか

sitemaps.org – プロトコルに載ってるフォーマットに従ったサイトマップのクロールはできるっぽいが、表記ゆれの検証(そもそも、そんなにフォーマットのバリエーションあるのか調査とか)できていない。

・sitemap_rules, sitemap_followなどの設定でもう少し細かくクロールを制御できるが、そこの設定は今回飛ばした。

・個人のサイトやブログなど、小規模なものは今回のコードで行けるが、記事数がめっちゃ多い巨大なサイト(ニュースサイトとか)だと多分sitemap.xmlに全アーカイブはなさそう(1日分とか1週間分とかのレベルで切り分けるはず)なので、そういうケースの対処は知らない。

参考にしたもの、ページ

スパイダー — Scrapy 1.2.2 ドキュメント
virtualenv 基本的なコマンド使い方メモ – Qiita
User Guide — virtualenv 16.0.0 documentation
sitemaps.org – プロトコル

ABOUTこの記事をかいた人

職業:遊び人。1日の半分は睡眠時間の超ロングスリーパー。元大手IT企業のサラリーマンだったが、ブラックな労働環境で体を壊した挙句クビになり、やむをえず独立。それ以来定職にもつかず、半分遊びのようなヌルい仕事をしながら適当に暮らしている。良く言えばノマドワーカー。 詳しいプロフィールはこちら