ScrapyでRSSをスクレイピング
RSSリーダがすでにあるのに、スクレイピングをするなんて、、、いや、余計なことは考えない!!
スパイダーを作ってアイテムに入れるまで
今回のお題としては、はてぶの人気エントリのRSSを取ってきてアイテムに入れるまで。パイプラインに関しては今回は扱わない。
まずはプロジェクトの作成
scrapy startproect hatena_hotentry
続いてスパイダーの生成
cd hatena_hotentry
scrapy genspider HotentrySpider feeds.feedburner.com
ここまでは何の問題もなく終わる。
それからシェルを使ってxpathの確認
scrapy shell http://feeds.feedburner.com/hatena/b/hotentry
例によってソースを確認して(※データは記事作成時のもの)
~前略~ <item rdf:about="http://anond.hatelabo.jp/20170118083140"> <title>映画館でわざわざ観る必要がない問題</title> <link>http://anond.hatelabo.jp/20170118083140</link> <description>「この世界の片隅に」はわざわざ映画館で観る理由がない。映画館で観る人はとにかく褒めたいアーリーアダプターと話題に乗っかりたいブロガーさんだけである。 いずれYoutubeかAmazonビデオでなら観るだろう。そしてレビューに「素晴らしかった!」とか書くんだろう。 この手の話はここ10年映画が衰退している理由でもある。 BDの普及、レンタル屋、テレビの高精細大画面化。 キネマ旬報はこの流れとともにお...</description> <content:encoded><![CDATA[<blockquote cite="http://anond.hatelabo.jp/20170118083140" title="映画館でわざわざ観る必要がない問題"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fanond.hatelabo.jp%2F" alt="" /> <a href="http://anond.hatelabo.jp/20170118083140">映画館でわざわざ観る必要がない問題</a></cite><p>「この世界の片隅に」はわざわざ映画館で観る理由がない。映画館で観る人はとにかく褒めたいアーリーアダプターと話題に乗っかりたいブロガーさんだけである。 いずれYoutubeかAmazonビデオでなら観るだろう。そしてレビューに「素晴らしかった!」とか書くんだろう。 この手の話はここ10年映画が衰退している理由でもある。 BDの普及、レンタル屋、テレビの高精細大画面化。 キネマ旬報はこの流れとともにお...</p><p><a href="http://b.hatena.ne.jp/entry/http://anond.hatelabo.jp/20170118083140"><img src="http://b.hatena.ne.jp/entry/image/http://anond.hatelabo.jp/20170118083140" alt="はてなブックマーク - 映画館でわざわざ観る必要がない問題" title="はてなブックマーク - 映画館でわざわざ観る必要がない問題" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://anond.hatelabo.jp/20170118083140"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote><img src="http://feeds.feedburner.com/~r/hatena/b/hotentry/~4/8vfCvvBcSzw" height="1" width="1" alt=""/>]]></content:encoded> <dc:date>2017-01-18T08:57:56+09:00</dc:date> <dc:subject>エンタメ</dc:subject> <hatena:bookmarkcount>197</hatena:bookmarkcount> </item> <item rdf:about="https://note.mu/wakusei2nd/n/n562b7d525897"> <title>なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note</title> <link>https://note.mu/wakusei2nd/n/n562b7d525897</link> <description>なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』 ★☆★☆★☆★☆★☆★☆★☆★☆★☆ こちらの記事は、1/19(木)24:00までの期間限定で全文無料でお読みいただけます! ★☆★☆★☆★☆★☆★☆★☆★☆★☆ Daily PLANETS では毎月第2水曜日に、古川健介さんの連載『TOKYO INTERNET』を配信しています。連載...</description> <content:encoded><![CDATA[<blockquote cite="https://note.mu/wakusei2nd/n/n562b7d525897" title="なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fnote.mu%2F" alt="" /> <a href="https://note.mu/wakusei2nd/n/n562b7d525897">なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note</a></cite><p><a href="https://note.mu/wakusei2nd/n/n562b7d525897"><img src="http://cdn-ak.b.st-hatena.com/entryimage/316512078-1484693699.jpg" alt="なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note" title="なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note" class="entry-image" /></a></p><p>なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』 ★☆★☆★☆★☆★☆★☆★☆★☆★☆ こちらの記事は、1/19(木)24:00までの期間限定で全文無料でお読みいただけます! ★☆★☆★☆★☆★☆★☆★☆★☆★☆ Daily PLANETS では毎月第2水曜日に、古川健介さんの連載『TOKYO INTERNET』を配信しています。連載...</p><p><a href="http://b.hatena.ne.jp/entry/https://note.mu/wakusei2nd/n/n562b7d525897"><img src="http://b.hatena.ne.jp/entry/image/https://note.mu/wakusei2nd/n/n562b7d525897" alt="はてなブックマーク - なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note" title="はてなブックマーク - なぜ日本が世界共通語「Emoji」を生み出したのか、そしてその影響とは/古川健介『TOKYO INTERNET』|PLANETS|note" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?https://note.mu/wakusei2nd/n/n562b7d525897"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote><img src="http://feeds.feedburner.com/~r/hatena/b/hotentry/~4/Yrhv1rRQwes" height="1" width="1" alt=""/>]]></content:encoded> <dc:date>2017-01-18T07:51:51+09:00</dc:date> <dc:subject>テクノロジー</dc:subject> <hatena:bookmarkcount>287</hatena:bookmarkcount> </item> ~後略~
なるほどね、itemタグからのtitleタグなのねと以下のように入れたら何も出なかった
In [1]: response.xpath('//item/title/text()').extract() Out[1]: []
公式のドキュメントにそれっぽい記述があった。
Selectors — Scrapy 1.3.0 documentation
Once in the shell we can try selecting all <link> objects and see that it doesn’t work (because the Atom XML namespace is obfuscating those nodes): But once we call the Selector.remove_namespaces() method, all nodes can be accessed directly by their names:
どうやらscrapyする相手がxmlとかrssとかatom形式の場合だと名前空間が邪魔して、素直に読めないからひと手間必要ということが分かった。
ということで以下のようにする
In [2]: response.selector.remove_namespaces() In [3]: response.xpath('//item/title/text()').extract() Out[3]: ['映画館でわざわざ(略)
これでOK。rssなどをscrapeした場合はresponse.selector.remove_namespaces()しないとデータが見えない。
ついでに<dc:subject>とかなってるタグ。そのままでは取れないけど、dcとかの前部分を無視してコロン以降の後部分を使えばデータが取れる
In [4]: response.xpath('//item/subject/text()').extract() Out[4]: ['エンタメ(略)
shellで検証した結果を受けて編集したSpiderとItem
- Spider
- Item
最後にcrawlが動かせれば出来上がり
scrapy crawl Hotentry (結果略)
scrapyを作る際はshellの検証が必須ですねぇ
関連記事
20161228アンテナ
自身のアンテナを書くのをマネしてみた。気が付いたらまた見直そう
アンテナ
- データサイエンス
- 技術
- IOT
- ビーコン
- RaspberryPI
- Arduino
- Edison
- Docker
- IOT
- 開発
- OS
- DB
- 開発環境
- Vim
- プラグイン
- vimshell
- PowerShell
- Vim
- 学問
- その他
- 手帳
- 文房具
- Amazonプライム
- ボルダリング
- ランニング
- サッカー
- 映画
- 本
今回はPython関係多めかな。
Jupyter Notebookの設定をする
JupyterNotebookの設定をする。導入はこちら
Jupyter notebookをホストのブラウザで使用する
Ubuntu on Virtualboxで運用しているので、Jupyterとか使用する際にはゲスト側ではなく、ホスト側のブラウザで実行すると捗る。ということでJupyterを起動する際には以下のようにしていた。
- ポートフォワードの設定
VMの設定→ネットワーク→NATアダプタ→ポートフォワーディング
ポートフォワードの設定をしておく。これをしておくとホスト側のブラウザなどでポートを指定すると、ゲスト側のポートにフォワードしてくれる。下段がJupyter用で、上段がDjango用に設定している。Djangoについては今回関係ないので割愛。
- jupyter notebook実行時のコマンド
cd my/favorite/notebook/directory jupyter notebook --ip=0.0.0.0
ipのオプションを付けることでアクセス制限をかけることが出来る。「0.0.0.0」はアクセス制限なし。これを利用してホスト側のブラウザでJupyterを使う。以上でホスト側のブラウザでhttp://localhost:8888を打つとゲストで起動しているJupyterを使うことが出来る。
jupyter_notebook_config
ということで、jupyter notebookを使うときはいつも同じディレクトリで動かしているし、ipの指定もしている。ついでに件のコマンドを打つとゲスト側でブラウザが立ち上がってくる。使わないのに。ということでこれを制御する方法。
まずはコンフィグファイルの生成
jupyter notebook --generate-config
~/.jupyter/jupyter_notebook_config.pyが生成される。このファイルを編集して設定する。
- ip指定
コンフィグファイルから「c.NotebookApp.ip」という文字列を探す。jupyterに設定できる項目はコメントアウトされているので、これを有効にするだけでいいようになっている。それでip指定は以下のように変更
c.NotebookApp.ip = '*'
- ディレクトリ指定
同様に「c.NotebookApp.notebook_dir」という文字列を探す。これを指定することでいつも同じディレクトリで動かせる。
c.NotebookApp.notebook_dir = 'your/favorite/notebook/directory'
- ブラウザの自動起動
「c.NotebookApp.open_browser」という文字列を探して設定。jupyter起動後にブラウザは自動起動しなくなる。
c.NotebookApp.open_browser = False
他のコメントアウトされている項目を見るとそれなりに想像がつきそうだが、自分の場合はこんな感じで十分かと。他の設定項目に関して知りたいのであれば公式ドキュメントを見てもらうといい。
Configuration Overview — Jupyter Notebook 5.0.0.dev documentation
これで以下のようにシンプルにコマンドを打てば設定どおりにjupyterが使える。
jupyter notebook
実はこの設定ファイル云々は本来ならばサーバ用の設定となる。運用しているサーバでjupyterを起動し、その際の挙動を設定ファイルで制御するという形だ。なので設定次第で、スマホでjupyterなんてこともできるようになる。
Powershellでzipファイルを作る
WindowsのエクスプローラとではファイルをZIPするには任意のファイル(またはフォルダ)をクリックして選択して、右クリののちにZIPしていると思われる。でもそういったGUIでの操作よりもCUIでできないものかと思った。
ZIPをCUIで作る
Windowsではcmd.exeではなく、powershellでできる。
- 構文
Compress-Archive -Path <target file> -Destination <file name>
- 基本形
Compress-Archive -Path a.txt -Destination archive.zip
- フォルダを指定する
Compress-Archive -Path my_folder -Destination archive.zip
- 拡張子を指定する場合
Compress-Archive -Path *.log -Destination archive.zip
- 複数指定する場合
Compress-Archive -Path a.txt, my_folder, *.log -Destination archive.zip
- cmd.exeから実行する場合
powershell Compress-Archive -Path *.txt -Destination archive.zip
この通りcmd.exeからもコマンドの前にpowershellをつけるだけで実行できるのでファイルをアーカイブするバッチが作れる。そもそもpowershellのスクリプトを作ればいいのだが、それはそれ。あとは「zip」とかでエイリアスを作っておくのもいい。
- zipでエイリアスを作る
Set-Alias zip Compress-Archive
このCompress-ArchiveコマンドレットはPowerShellV5からの導入なので、バージョンが低い場合は新しいのを入れる必要がある。
Powershellでリモート接続
WindowsでもCUIでリモート接続をしたいと思った。Powershellならできると聞いて早速試してみた。リモートデスクトップ接続しちゃえばいいじゃんなんてことは言わない!!
事前準備
まずは接続される側で設定が必要。PowerShellを起動してリモート接続をEnableにする。
Enable-PSRemoting
接続
接続する側でコマンドを打てば接続ができる。これは接続先としてcomputernameを指定するやり方。
Enter-PSSession -ComputerName <computername>
ファイルの編集
SSHならvimとかviとかエディタのコマンドを打ってファイルの編集が開始できるのだが、先方にvimが入っていたとしてもPowerShell内では動かなかった。ではどうすればいいのかということでそれ専用のコマンドを見つけた。
PSEdit <file-name>
ただし、「Windows PowerShell ISE」のv5以上でしかPSEditは動かなかったので注意。ということで、これでファイルの編集ができるようになった。接続後はPATHとかも先方の環境で通っているので、何かしらのEXEとか、設定済のタスクとかを先方の環境で実行ができる。
あとは
PowerShellをマスターしたいなぁ。でもほとんどはCMD.exeで事足りるんだよなぁ。
Pythonでクラスタ分析
俺たちのirisでクラスタ分析を行う。
クラスタ分析とは
機械学習の一つで教師なし学習に分類される。データの特徴をプログラムが判定して、それぞれのクラスタに分けることが出来る。
クラスタリング分析は一般的にK-means法が使われる。データに対してまずは適当なクラスタに振り分けてその中心を計算する。その中心に対してそれぞれのデータがもっとも近い中心にクラスタを振り分けなおす。再振り分け後にその中心を計算し、、、と続けていき、中心があまり動かなくなってきたところで終了とする。つまりどういうことだってばよ?っていうのはこのサイトで視覚的に理解ができる。
クラスタリングを行うことで、そのクラスタに属するデータがどのような傾向にあるかを調べることが出来る。 結果を受けてレコメンドやマーケティングなどにも適用することが可能だ。
Pythonで実装
scikit-learnにKMeansが用意されているのでそれを使う。基本的にデータとクラスタリング数をKMeansに渡すだけで結果が得られる。
最後の図にはクラスタリング後のデータに対してその中心地もプロットした。
どれくらいのクラスタ数にするか
これは完全に作業を行う人の主観がはいる。どれくらいのクラスタ数が適当なのか正しい答えはない。反対に言えば恣意的に分析結果を操作することが可能ともいえるので注意が必要だ。
とはいえ、これくらいでいいのではないかなという手法はある。「シルエット分析」と呼ばれている方法だ。そのシルエット分析に関してはscikit-learnの公式に説明があるので、参照するといい。
要は分類数に対してそれっぽく(できれば均等に)データが集まっていればそれがクラスター数の最適な値だということになるのだ。