Scrapyチュートリアル
インストール
前回記事より。 dragstar.hatenablog.com
プロジェクトの作成
まずはプロジェクトを作る
scrapy startproject tutorial
ツリー構成はこんな感じ
tutorial/ ├── tutorial │ ├── __init__.py │ ├── items.py │ ├── pipelines.py │ ├── settings.py │ └── spiders │ └── __init__.py └── scrapy.cfg
一番上のディレクトリをホームとする
Itemの作成
スクレイピングした結果をItemクラスに保持することになる。items.pyにItemを定義する。
# items.py import scrapy class MyItem(scrapy.Item): title = scrapy.Field() link = scrapy.Field()
どういった情報を保持していくか、用途に合わせて項目を定義していく。
Spiderの作成
実際にスクレイピングをしてくれるSpiderを作る。処理の中でItemにデータを入れるのを忘れずに
# spiders.py import scrapy from scrapy.selector import Selector from tutorial.items import MyItem class MySpider(BaseSpider): name = "MySpider" #spiderに名前を付ける。実行時に使う allowed_domains = ["test.com"] start_urls = [ "http://www.test.com/foo/bar" ] def parse(self, response): item = MyItem() sel = Selector(response) ## この辺でスクレイピング処理を書いていく item['title'] = sel.xpath('//html/head/title/text()').extract() item['link'] = sel.xpath('//a/@href').extract() yeild item
コツとしてはFirefoxとかで対象サイトの要素をあらかじめ見ておくと希望するものにたどり着きやすい。よっぽどのサイトでなければCSSとかちゃんとやってるのでクラス指定とかID指定とかするとよりいい感じで取得できる。
shell
scrapy shellを動かして試しながらの使い方がおすすめ。xpathの使い方に慣れることができる。また、Itemにどんな感じで帰ってくるかも確認できるのでその後のpipeline作成にも役に立つ。
scrapy shell "http://www.test.com"
Pipelineの作成
スクレイピングした結果を料理するのがPipeline
# pipelines.py class MyPipeline(object): def process_item(self, item, spider): # Spiderが実行されてitemに格納されるのでitemをDBにいれるなりなんなり t = item['title'] link_list = item['link'] # listで帰ってくると仮定 for l in link_list: print(l) return item
パイプラインを有効にするにはsettings.pyを変える。コメントアウトされているので外して、作ったpipelineを指定する
# settings.py ITEM_PIPELINES = { 'tutorial.pipelines.MyPipeline': 300, }
jsonとかで出力できるので、必要なければpipelineはなくてもいい。
実行
例は実行して結果をjson形式に出力するコマンド
scrapy crawl MySpider -o output.json
CSVで出力するコマンド
scrapy crawl MySpider -o output.json
CSVに出力するやりかた。拡張子で勝手に判定してくれる
scrapy crawl MySpider -o output.csv
他にもログを残すやり方とか
scrapy crawl MySpider --logfile scrapy.log
スケジューリング
と、うまくいったら勝手に実行してほしいですよね。スケジューラはcrontabでもなんでもいいけど、実行するときのシェルスクリプトにちょっと手間取った。
export PATH=$PATH:/home/xxxx/.pyenv/shims cd tutorial scrapy crawl MySpider --logfile scrapy.log
こんな感じにした。うまくscrapyへのパスを指定しないと「scrapyなんてコマンド知りませんけど」ってなる。僕の場合はpyenvを使っているのでscrapyのパスも/home/xxxx/.pyenv/shimsにあったのでそれを指定した。which scrapyとかで探せばいい。あとはプロジェクトのホームディレクトリに移動して実行コマンドを打つ、といったスクリプト。実行権限も必要に応じて。
最後に
クローラは自動ゆえ便利だが、頻繁に実行すると当然相手サーバにアクセスすることになる。先方に迷惑がかからない程度に節度をもってやりましょう。こんな事件も昔にあった事ですし、、、
mysqlclientでCRUDする
というよりmysql-connector-pythonがインストールできなかった。
mysql-connector-pythonをpipからインストールしようとしたら下記のエラーが出た
Could not find a version that satisfies requirement mysql-connector-python(from versions: ) No matching distribution found for mysql-connector-python
残念だが君はバージョンを満たしてないようだね。というご宣託。
MySQL :: MySQL Connector/Python Developer Guide :: 3 Connector/Python Versions
公式リンクによるとpython3.3と書いてあるのでPython3.5の僕はアウトらしい。ということでmysqlclientをしばらく相棒にしようかと思う。インストールはpipで。
pip install mysqlclient
エラーがでるようならaptでライブラリを入れておく
sudo apt insatall libmysqlclient-dev
接続と終了
import MySQLdb con = MySQLdb.connect( user = "user", passwd = "pass", host = "yourhost", db = "yourdb") cur = con.cursor() cur.close con.close
以降はこの接続と変数を使うという前提です
Read(SELECT)
CRUDといいながらまずはセレクト
cur.execute("select * from tbl") for row in cur.fetchall(): print(str(row[0])) cur.close
Create(INSERT)
続いてINSERT
cur.execute("INSET INTO tbl(id, value) VALUES (1, 100)")
con.commit
cur.close
con.close
一括INSERTはこんな感じ。
cur.executemany("INSET INTO tbl(id, value) VALUES (%s, %s)", [(1, 100), (2, 200), (3, 300)]) con.rollback cur.close con.close
Update
なんかSQLさえ流せればという感じがしてきた。
cur.execute("UPDATE tbl SET value=400 WHERE id = 2")
con.commit
cur.close
con.close
Delete
結局これも。
cur.execute("DELETE FROM tbl WHERE id = 3")
con.rollback
cur.close
con.close
まとめ
途中でも書いたけど、SQLさえかければという感じがする。というよりRDBのドライバに求められているのって結局それなんでしょうね。あとはJavaでいうところのPreparedStatement#addBatch()みたいなやつが欲しいんだけどなぁ。どうだろ?Documentを探せばあるかな。
Welcome to MySQLdb’s documentation! — MySQLdb 1.2.4b4 documentation
Pythonのドライバがいくつもある件
どのドライバ使えばいいんだってばよ
なんでこんなにあるんだ
ここにいくつもある
で、日本語で情報が検索できたものとしてピックアップしたのがこのへん
- PyMySQL
- mysql-connector-python
- MySQL-Python
- mysqlclient
概要を表にしてみた
プロダクト | python2 | python3 | 備考 |
---|---|---|---|
PyMySQL | ○ | ○ | PyMySQL3ってのがあったけど今はこれ1本 |
mysql-connector-python | ○ | ○ | MySQL公式 |
MySQL-Python | ○ | × | Python3には使えない |
mysqlclient | × | ○ | 3を使えないMySQL-Pythonを3に対応したもの |
PyMySQL
PurePythonを謳うドライバ。ググるとだいぶ上位に出てくるので、まずは試そうかなという気持ちにさせられる。python2系とpython3系の両方に対応している。
mysql-connector-python
MySQL :: Download Connector/Python
公式によるドライバ。公式ってことはですよ、あのOracleのサポートでもあるんですよ。心強いですねぇ。これがドライバを試す初めの一歩にはいいと思います。
MySQL-Python
Index of Packages : Python Package Index
古株のドライバらしいんですけどね、python3には対応してないっていう。比較的新参pythonistaなので、僕はpython3を使っている。よってこれはお話になりませんという話。python3に対応するよって言いながらここ何年も進んでいない気がする。
mysqlclient
という事で業を煮やしたハッカーが、MySQL-Pythonからforkしていって、しまいにはpython3に対応したというオープンソースならではのプロダクト。WebフレームワークであるDjangoの推奨ドライバにもなっているので導入しておいて損はないかも。
まとめ
mysql-connector-pythonをメインに使って、適材適所で他のドライバを使うのがいいかと。サブとしてDjango用にmysqlclientも入れておくと隙が無い。
TBSラジオポッドキャストからTBSクラウドラジオへ
あーあ
Podcastを支えたTBSラジオ
これまでAppleはいろいろなサービスをiTunesをはじめとしたプロダクトに組み込んできたが、いくつか死んでいったサービスもある。その中でPodcastは死ななかった。なぜか。PodcastはTBSラジオがあったからこそ死にコンテンツにならなかったんだと思っている。だいぶ誇張してしまったけど、日本以外の事情はしらないので間違っているともいえる。そのTBSラジオがこのたびPodcastでの配信を停止してストリーミングサービスに移行することになった。確かに金も払わずにサービスだけを受けていたのでマネタイズできんと言われたらなんも言えない。
TBSの聴衆率を上げることが目的ではなかったのか
Podcastが始まった10年前に、TBSラジオがどのような目的でPodcastを始めたのかはわからない。ただ新しい波に乗っかってみただけなのかもしれない。タマフルなんかはプロデューサーの感覚が若かったのかいち早く導入し、初期の初期は全コンテンツに加えていまは特別なときにしかやらない放課後も毎週配信していた。Podcastではしきりに本放送も聞いてくださいねと言っていたのを覚えている。ラジオ本体を配るなんて事もやっていた。ラジオリスナーが減っている昨今で、Podcastをきっかけにしていかにしてリスナーを増やすかを試行錯誤していた。
タマフルや土曜日も含めたJunk、今は終わってしまったがキラキラといった日中のワイド番組をPodcastをきっかけに聞くようになったリスナーも少なからずいると思う。そういう意味で目的を果たしたから次のステージへという事だろうか?TBSクラウドラジオに移行することでこれまで積み上げてきたものが崩れてしまわないか心配してしまう。もちろんだれだって金は欲しいし、金にならないサービスを続ける意味を問われたら当然窮してしまう。この決断がラジオへの入り口を狭めてしまい、結果として将来のラジオリスナーを減らしてしまわないことを願う。
ラジオを聴くシチュエーションとPodcast
特別な事情が無い限り、ラジオは「ながら」で聞くものが一般的だと思う。勉強しながら、運転しながら、料理しながら。その中でも移動しながら、つまり通勤通学しながらというのがよくあるのではないだろうか?そしてその場面にマッチしたのがPodcastであった。radikoもそうだがストリーミングとなると通信料とか気になるし地下だったり新幹線だったりでまともに電波を拾えるかは保証できない。Podcastでダウンロードしておけばいつでもラジオを聴けるというのがリスナーにとって本当にいいサービスだったのだと思う。
TBSクラウドラジオはYouTubeになりえるか
ストリーミングサービスといえば言わずと知れたYouTube。ダウンロードできないとかそんな事で不満を言っている人はいない。電車の中でYouTubeを見ている人なんてちょっと探せばすぐに見つかる。TBSクラウドラジオもストリーミングサービスとしてその位置に並ぶようになれば安泰だ。きっとライフスタイルも変わっていいものになる。なんならradikoだってあるし。
さいごに
あまりにも僕の日常の一部だったので悲観的な見方しか今はできない。でもTBSクラウドラジオのアプリが出るようになったら変わってくるかな?それにしても東京ポッド許可局なんてどうするんだろ、ポッドキャスト関係なくなるじゃん。
Ubuntu15.10にScrapyをインストール
データがなければ自分で加工すればいいじゃない
Scrapyとは
Scrapy | A Fast and Powerful Scraping and Web Crawling Framework
ScrapyとはPythonのスクレイピングライブラリというかフレームワークで、Webサイトの情報を抽出することができる。要はFireFoxとかChromeといったWebブラウザを使ってWebサイトを見るのではなく、プログラムがWebサイトを見る事を可能にするものだ。Pythonにはいくつかスクレイピング用のライブラリがあるのだが、情報も多そうだしScrapyを使っていこうかと思う。
インストール
pipで一撃
pip install scrapy
といいたいところだけど、Ubuntu15ではライブラリがいくつか必要だった
sudo apt install libxml2-dev libxslt1-dev libffi-dev
これをした後にpipしたらできた。
何を得て、何を失ったか。映画「スリーデイズ」
いやー、こういう映画大好き。
- 出版社/メーカー: ジェネオン・ユニバーサル
- 発売日: 2012/03/02
- メディア: DVD
- クリック: 2回
- この商品を含むブログ (19件) を見る
リーアムニーソン映画ではない
繰り返す。これはリーアムニーソン映画ではない
リンク元と同じようにこの話のあらすじを知った時に「これはリーアムニーソンパターンだな」と勝手に思ってた。実際リーアムニーソンも出るし。ラッセルクロウはただのおっさんではなく本当は凄腕の元エージェントかなんかで、エンディングでは監獄が爆発して脱獄に成功した嫁とキスをしながら終わる映画だなとか云々かんぬん。
チンピラにボコボコにされたり、合鍵作戦に失敗して嘔吐したり、偽造パスポートを取得するときにも「焦りすぎ、あんたみたいなやつは失敗するよ」とか忠告されたりと、ハリウッド界隈でよく見かける超人とはかけ離れた存在となっている。そりゃそうだ、もし自分の奥さんが無実と思われる罪で投獄されても脱獄させようなんて思うだろうか?よしんば脱獄させようと決心したとして、平常心を保ち続けることができるだろうか?
何を得て何を失ったか
結果として脱獄は成功する。その過程でジョンは人を殺す。妻ララは人を殺していないのにだ。家族三人、新たな地で過ごすことができるようになりハッピーなはずだが、ジョンの表情がなんとも表現しがたい。
はたしてこれで良かったのだろうか?この家族のこの先を思うとハッピーエンドといっていいのだろうか?得たものと失ったものの評価がどうもできない。
ただ、脱獄させる過程は素晴らしく面白い。ここまで綿密な計画だったとはとうならされる。