本日の投稿は Python Advent Calendar の5日目 です。初Python系のに参加です。初心者が紛れ込んですみません・・・
私は普段(多分)極度のSlack依存生活です。運営しているコミュニティ3つ、カンファレンスグループ2つ、と会社のやつ。付け加えて、自分が興味のあるもの(例えばAWSのニュースとか舞浜関係の情報とか)をキュレーションしたり遊び開発したりに使ってる1人Slackが1つ。とりあえずSlack開いておけば見たい情報は流れてくるような生活です。
が。どうでしょう。Qiitaのアドベントカレンダーはrssがついているので
/feed subscribe 【URL】
してあげれば毎日データが流れてくるのですが、ADVENTARは残念ながらrssが見当たりません(探すのが下手なだけ?)。でも私はSlackにADVENTARのアドベントカレンダーの情報も流したい!Geek Women Advent Calendar をPyLadies JapanのSlackとGeek Women のSlackに、Python Advent Calendar をPyLadies JapanのSlackに流したい。
そんなわけで、スクレイピング+Slack Incomming Hook をやってみることにしました。たった一人のちっぽけで簡単なプロジェクトです。実はこの組み合わせ、1年前にも挑戦していましたw が、当時の私はSlackpyのライブラリを呼んでSlackに情報を流すのが精一杯で、スクレイピングは結局Javaで書いておりました。1年越しのリベンジなるか….?
当時PyLadies Tokyo のmeetup で発表した資料がこちらです。
発表資料はここをクリック
1. どこを取るか決める
まずは、ADVENTARのページを観察します。どこの情報をどうとればいいか考えます。
ADVENTARのカレンダーの下にある、レコード式に書かれた各日付ごとの情報をとってあげれば、欲しい情報をSlackに流すことができそうです。
htmlを確認してみます。
ふむ。「id=“list-yyyy-MM-dd”」のdivの中に1日分の情報が埋まっているようですね。欲しい情報をCSSセレクタ化するとこんな感じ。
- 担当者名 : #list-yyyy-MM-dd > .mod-entryList-user
- 記事タイトル : #list-yyyy-MM-dd > .mod-entryList-body > .mod-entryList-title
- 記事URL : #list-yyyy-MM-dd > .mod-entryList-body > .mod-entryList-url > a
2. 何を使うか決める
スクレイピングするには何がいいのか。htmllibとかBeautiful Soupとか色々あることが調べてみてわかったんですが、一番興味を持ったlxmlを使ってみることにしました。興味を持った理由は直感です。特に意味はありません。Beautiful Soupはよく聞く名前なので、こっちはこっちでまた別の機会に・・・また、今回開発の途中で気がついたんですが(最初html見た時点で気づけよ)、このページどうやらjsから出力されている。。。静的なページであればlxmlだけでよかったんですが、js介すということで、seleniumとseleniumのゴーストドライバーとしてPhantomJSを使用しました。あと、Slackに投げつけるツールであるSlackpyですね。
そのほかこまかいものもありますよ・・・というわけで、準備したツールは以下のとおり。
pip installしたもの
- lxml
- cssselect(XpathではなくCSSから取得するようにしたかったため利用)
- python-dateutil(日付取得用)
- Selenium
- slackpy
brew installしたもの
- phantomjs
ソースコードはきったないのですが、一応後ほどGitHubにあげたいとおもいます(とりあえず日付が変わらないうちにアドベントブログを・・・・!)
3. はまったところ・工夫したところ・感想など
はまったことは2つだけで、色々調べながらでもそれなりにサクッと作成することができました。ライブラリ何にしようかしら・・・から始めて各記述の意味とか調べながら進めて3時間半くらい・・・でブログ文章作成までこぎつけた感じです。ソースの行数的にもJavaでやった時よりもだいぶ少なくすんでスッキリしている感じでした。
はまったことの1つ目は上述したjs問題。最初試しに簡単に取れるタイトルとかを抽出していたのでおっけーいけるやん!とか思ってたんですが、全然取れなくて絶望しました。何か取れる手立てはないものかと調べたらJavaでもお世話になってるSeleniumさんが出てきたのでなんだか安心しました(?)。普段テストツールとして使っていたのでChromeとかのブラウザドライバーのイメージが強かったんですが、PhantomJSなんかも使えるんですねぇ・・・!
はまったことの2つ目はPhantomJSパスが通らないよ問題。これはPythonでもなんでもないんですが、
PhantomJSをインストールする->環境変数PATHにPhantomJSのパスを設定する(.bash_pofile)-> source .bash_profileで再読み込みする->「パスが通ってないよエラー」が発生し続ける・・・
という悲しい感じでございました。どうにもこうにも時間もなかったので、今回は取り急ぎ、以下記述で脱出しました。後々きちんとPATH変数の読み込みが行われるよう修正したいとおもいます。
webdriver.PhantomJS(executable_path='/usr/local/opt/phantomjs/bin/phantomjs')
工夫したところはSlack上の表記・・・になるかな・・ちょっとしたことなんですが、名前とタイトルとURLがだだーっとただ並ぶだけだと通知が大変見づらいので、タイトルに記事URLのリンクをつけるようにしました。小ネタですが、こんな感じの記述でSlack Incomming Hook のメッセージ部分をリンクにすることができます。
<【リンク先URL】 | 【表示させたい文字列】>
というわけで初心者の拙い開発で失礼いたしました。今後はこれをきちんと汎用化させて外部ファイルで抽出内容の制御ができるようにしていきたいなぁと思っております。それはまた別のブログで、ということで。。。
ありがとうございました!
Python Advent Calendar 次は6日目seong15_さんの投稿です!お楽しみに!
1件のコメント 追加