第10章 ScrapyとRaspberry Pi

はじめに

ここでは、Raspberry Piのセットアップ、Scrapyのインストール、MariDBのインストール、IPアドレスの固定、SSHとVNCでの接続、VS CODEのインストールの作業をはじめに行います。そして、実際に、Scrapyで作ったクローラーをRaspberry Piで定期的に実行する方法をまとめておきます。

Raspberry Pi、Python3、Scrapyのバージョンは下記の通りです。

pi@raspberrypi:~ $ cat /etc/issue
Raspbian GNU/Linux 10

pi@raspberrypi:~ $  python3 -V
Python 3.7.3

pi@raspberrypi:~ $ scrapy -V
Scrapy 1.5.1 - no active project

お金さえあれば、AWSの製品とか、GCP製品で環境構築して常時稼働させて、クローラーを実行すればいいんだろうけど、そんなお金ないので、家に転がっていたRaspberry Piを使います。

Raspberry Piのセットアップ

ここで書く必要も無いかもしれませんが、まとめておきます。まずは購入したRaspberry Piにフォーマット済みのSDカードとRaspberry Pi Imagerを使って、Raspbianをインストールしていきます。RaspbianはLinuxのディストリビューションであるDebianをベースにしているOSなので、似たような操作感で操作ができます。

SDカードをRaspberry Piに差し込み、電源を起動すると、Raspberry Piが起動します。設定ウィザードが表示されるので、順に従って設定します。

  1. Set Countryでは、「日本」を設定しておきます。

  2. Change Passwordでは、パスワードは初期設定のままだと「pi / raspberry」になっているので、よしなに修正します。

  3. Set Up Screenが表示されるので、スクリーンの端に黒い線が表示されているのであればチェックボックスにチェックをいれます。

  4. Select WiFi NetWorkでは、WiFiのネットワークを設定します。

  5. Update Softwareでは、アップデートしておきます。

  6. 再起動します。

再起動後、「Raspberry Piマーク > 設定 > Raspberry Piの設定」と進み、

「インターフェース」のSSH、VNCを有効にします。これでSSHとVNCでアクセスができます。

Interface

ここからはScrapyとMySQLをインストールしていきます。Raspberry PiにはPython3がすでにインストールされているので、Scrapyをインストールします。あわせてPyMySQLをインストールしておきます。

次はMySQLです。正確にはMariaDBですが、MariaDBはMySQLから派生したもので、非常に互換性も高く、細かい部分を除けばMySQLと同じような操作感で使用できます。

とりあえずテスト用のDBtest_dbとテスト用のユーザーuser01を作成します。

cronの設定を行います。下記コンフィグファイルを開き、cronがコメントアウトされているので、#を削除してcronを使えるようにします。

テキストエディタとしてVS CODEを入れておきます。

下記のコマンドでVS CODEを起動できます。

試しにデスクトップにhello.pyを作成して実行してみます。

最後にSSHでログインできるか確認しておきます。まずは、下記のip addrコマンドでipアドレスを調べ、ipアドレスが定期的に変動しないようにを固定します。

ip_addressの部分は固定した番号に変更してください。

再起動して、ipアドレスを確認します。固定した番号が表示されるはずです。

この作業のあとにブラウザからインターネットにアクセスできないようになっている場合は下記のコマンドで修正します。

SSHでターミナルからログインします。

問題なくSSHでもアクセスできるようになっています。もう1つ試しておきます。それはscpコマンドです。このコマンドはローカルのデータをSSH経由でサーバーに転送するコマンドです。Raspberry Pi側でScrapyのクローラーを作っても良いのですが、少し重たいので、手元のPCで作ったものをディレクトリごと、Raspberry Piに転送してクローラーを起動させることにします。もちろん、Git経由でも他の方法でも、転送できれば何でも良いです。

-rのオプションをつけるとディレクトリをコピーすることができます。ここでは、crawl.pyを格納しているscrapy_scpというディレクトリを丸ごと Raspberry Piのデスクトップに転送します。

Raspberry Pi側で確認しておきます。デスクトップにscrapy_scpというディレクトリが作られ、crawl.pyも保存されています。

反対にRaspberry Piのデータをもらう場合は下記のように書きます。ここでは、Raspberry PiのDesktopにあるexcute.logというデータをローカルのデスクトップに転送する例です。

これ以降は環境にあわせて、Raspberry Piを設定してください。GUIからCUIに変更するには、「Raspberry Piマーク > 設定 > Raspberry Piの設定」と進み、「システム」からブートをCLIにしてから再起動します。

再起動後はCLIになります。戻すためには下記の通り設定します。

データベースへのテストインサート

データベースにテストでインサートできるかを確認しておく。まずはデータベースにログインし、下記の通り、テスト用のテーブルを先程作成したtest_dbの中に作成します。

下記のテストインサート用のコードtest_insert.pyを利用します。pymysqlでMariaDBは操作できるので、これまでの内容と合わせるために、pymysqlを利用します。

とりあえずデスクトップに保存し、インサートを実行します。問題なくtestテーブルにインサートが行われています。

cronのテスト

次はcronが実際に動かうかどうか、動作テストをしていきます。下記のようなバッシュスクリプトを作成します。これはRaspberry Piの温度を表示してくれるものです。

次はcronの設定です。ここではデスクトップにファイルを保存して、1分毎にログを出力するようにします。

数分ほど放置しておいたあとでログファイルを見てみると、cronは問題なく動いていることがわかります。

これでRaspberry PiでScrapyを定期的に実行し、データベースに保存する準備が整いました。

Scrapyを実行する

今回は、ヤフーニュースの記事を取得するクローラーを作成していきます。イメージは下記のような感じで、ヤフーニュースのトップの「主要タブ」のニュースのリンクからスタートして、ピックアップページでは「続きを読む」から中に入り、アーティクルのページにあるニュース本文を取得します。これを「主要タブ」のニュース数分繰り返します。

Image of Crawler

ここではローカルで作業したものをRaspberry Piに転送することにします。いつものようにプロジェクトを作成するところからはじめます。

items.pyでは、記事のタイトル、本文、ニュースのID、報道局の名前を保存するためのフィールドを定義します。

yahoo_news_spider.pyでは、トップページ、ピックアップページ、アーティクルページの情報を抽出できるようにコードを書いておきます。動画のニュースの場合は、HTMLの構造が変わるので、スクレイピングできないコードですが、ここでは不要なのでこのままにします。

pipelines.pyは、データベースへのコネクションや同じニュースをインサートしないように、ニュースIDを使って重複しているかを判定しています。新規の記事であれば、データベースにインサートしていきます。データベースへのコネクションはconfigparserライブラリを使って、ファイルの中から取得する方法のほうがセキュリティ的によろしいかと思います。

settings.pyでは、データベースへのパイプラインを機能させる設定とFEED_EXPORT_ENCODINGの設定を行います。FEED_EXPORT_ENCODINGを設定しておかないと日本語の文字が文字化けします。

クローラーが完成したので、scpコマンドでクローラーのスクリプトを転送します。

Raspberry Piではデータを受け取るDBnewsynewsテーブルを作成しておきます。

cronjobを設定します。まずはテストのため、1時間ごとにクロールするように設定します。cronの設定は、crontab guruで調べるのが簡単かもしれません。

時間になるとクローラーが実行されます。ターミナルに出力すると見づらいので、MySQL WorkBenchからクエリを発行した画面で確認しておきます。NULLは動画のニュースの場合です。ここでは不要なので、このままにしておきます。

ログも出力されています。

意図したように機能しているので、cronの設定を1時間ごとから6時間ごとに変更しておきます。

おまけ

再起動するとネットワークが繋がらなくなります。SSHやVNCではアクセスできるのにネットにはつながらないという状態です。この場合、もちろんScrapyもHTTPリクエストを送ることができません。下記のコマンドを実行することで解消されます。

最終更新

役に立ちましたか?