SlideShare a Scribd company logo
1 of 19
Download to read offline
東京スクレイピング勉強会#1 2014.6.22
ScrapyとPhantomJSを用いたスクレイピングDSL
Masayuki Isobe / 礒部 正幸 / @chiral
Adfive, Inc.
自己紹介
• 礒部正幸(いそべ まさゆき)
• 職業: ソフトウェアエンジニア
• 現在: アドファイブ(株) 代表 http://www.adfive.net
– 現体制: 代表1名 + 外注数名 : お問い合わせ
– 自社製品: モバイルO2Oアプリ/オウンドメディア/アドサーバ
– 受託業務: システムコンサルティング/システム開発/データ分析
• 東工大卒 (B:情報工学科、M:計算工学専攻)
• インターネット活動
– TwitterID: @chiral
– (ブログ:アドファイブ日記) http://d.hatena.ne.jp/isobe1978/
• 「機械学習ハッカソン」主催: http://mlhackathon.connpass.com/
• 近年作ったスクレイピング利用システム
– パケットデータから閲覧Webページの画面キャプチャ再構成
(PhantomJS+自作プロキシーサーバ)
– WebサイトのEPub電子書籍化ツール(Node.js/CasperJS)
– WebスクレイピングDSL( Scrapy/PhantomJS)
– Webスクレイピングジョブ管理システム(Django)
LTで発表
本資料
Scrapyとは
• Pythonで書かれたWebスクレイピングフレームワーク
• 2008年に初期リリース,比較的枯れていて安定動作
• Twisted(非同期イベント駆動処理ライブラリ)ベース
• XPATHやCSSでセレクタとスクレイピング処理を記述可能
• 欧米の大手企業の自社システムとして多数利用実績あり
• スケーラブル(例: EC2+Scrapyで2.5億ページを40時間で処理した天才科学者M.N)
• スクレイピングシステムにおける各機能単位がブラガブルに
設計されている → アジャイル開発にすごく合う(発表者の私見)
Scrapyのアーキテクチャ
・必要十分な機能分割がなされた綺麗な設計になっている。
① Spider
- 取得したいページのURLを
Schedulerにリクエスト
- 取得したページの内容をスクレイ
ピングしてItemとしItemPipelineへ
② Scheduler
- リクエストのトラフィック調整
(同一ドメインへのアクセス間隔等)
③ Downloader
- Webへのアクセス手段をフックする
④ Item Pipeline
- スクレイピングしたItemを出力
Storage(File, DB, ...), e-mail, … etc.①
②
④ ③
→ とりあえずSpiderを作れば動く。それ以外は必要に応じて追加する。
一般的なスクレイピング手順
対象ページのURLを生成
Webアクセス/HTMLのパース
セレクタ指定 & データ抽出
データの出力 / 保存
http://www.xxx.yyy/info?page=1
http://www.xxx.yyy/info?page=2
http://www.xxx.yyy/about
…
Scrapy作業ステップ (イメージ)
wget / curl …
Chrome / Firefox …
jQuery / css / xpath ..
JSONファイル,
MySQL, etc..
ScrapyでのPythonプログラムはなるべく共通に作って
サイトごとの違いを外部の設定ファイルで吸収したい。
(参考1)ドメイン特化言語
・ DSL : ドメイン特化言語
- あるドメインの課題を解くのに特化した
プログラミング言語。
- 汎用性に乏しい代わりに、「ドメイン知識の記述」
「効率的な動作」 「少ない記述量」 等が可能に
→ いわゆるアプリケーションの「設定ファイル」を
よりリッチにしてソフトウェアのインタフェースを
柔軟にするといったコンセプト
内部DSL 外部DSL
米国の著名なアーキテクト
マーティンファウラー御大は
近年、DSLを積極的に推進中
Webスクレイピング専用のDSLがあったら便利そう
(参考)DSLの大分類
・設定ファイルを、アプリケーションと同じ
言語で記述するというやり方
・例えば、Ruby on RailsにおけるRakefile
(メリット) 開発コストが低い
(デメリット) 記述方法がシステム開発者寄り
・専用の文法を持った設定ファイルを定
義して実装するというやり方
・例えば、Apacheの設定ファイル
(メリット)記述方法がドメイン従事者寄り
(デメリット)開発コストが高い
• 「WebスクレイピングDSL」 の検討
– 内部DSL案: Pythonのモジュールローダに則る必要があって大変 → 不採用
– 外部DSL案:専用の文法を作るとパーサー等が大変 → XML/JSON/YAMLなど既存の形式を利用
• XML / JSON / YAMLの特徴
– (当然ながら)いずれもパーサーがPythonライブラリとして存在する
– 再帰的な木構造を自由に表現可能 (一般にプログラムは内部的に木構造であり、表現力が高い)
– XML / JSONは普及しており、学習コストが低い
– XMLは人間が読み書きするのにあまり向いてない
– JSONは整形すれば読めるが、書くのが結構大変
– YAMLは人間が読み書きするのにより適している → 採用
(参考2) YAML ベースDSLのススメ
対象ページのURLを生成
Webアクセス/HTMLのパース
セレクタ指定 & データ抽出
データの出力 / 保存
作業ステップ YAMLファイル
各ステップに対応する処理をYAMLの項目として記述
スクレイピングDSLの仕様と実装
name: "yahoo_news"
url:
format:
- http://news.yahoo.co.jp/list/?p=%d
- { from: 1, to: 30 }
lis: "ul.list li ."
scr:
url: "a @href"
title: "span.ttl text()"
out:
file: data/yahoo_news.jsons
スクレイピングタスク名
対象ページのURL
ページ内のベースとなるセレクタ
抽出項目(ベースからの相対セレクタ)
データの出力/保存先
Scrapyの各パーツにて
上記の記述を解釈実行
する機能を実装
独自Spider
独自Downloader
独自Pipeline
Scrapyのsetting.py
URL指定部の仕様と実装
仕様
- http://aaa.bbb/
- { or: [taro,jiro] }
- /
- { from: 1, to: 3 }
実装
・配列=イテレータの積
* “http://aaa.bbb/taro/1”,
“http://aaa.bbb/taro/2”,
“http://aaa.bbb/taro/3”,
“http://aaa.bbb/jiro/1”,
“http://aaa.bbb/jiro/2”,
“http://aaa.bbb/jiro/3” +
・from/to=数イテレータ
{ from: 1, to: 5 }
[ 1,2,3,4,5 ]
・or=要素イテレータ
{ or: [apple,orange] }
* “apple”,”orange” +
・format=文字列生成
format:
- “%s?page=%d”
- hoge
- 777
*“hoge?page=777”+
これらを組み合わせて(多階層にネストも可能)、対象ページURL集合を指定する
・file=ファイル行イテレータ
, “title”:”hogehoge”, “url”:”http://a.b.c/def” }
, “title”:”fugafuga”, “url”:”http://g.h.i/jk” }
…
fileの例)/var/scrapy/data.jsons
file:
- /var/scrapy/data.jsons
- url
* “http://a.b.c/def”,
“http://g.h.i/jk”,
… +
・イテレータの積にはPythonのitertoolsパッケージにあるproduct()を用いる
・要素イテレータor、数イテレータfrom/toは、要素をforループで回してyield
・文字列生成formatは、1番目の要素 % (2番目以降) で生成してyield
・ファイル行イテレータは、ファイルを読み込んで行ごとにforループで回してyield
実装
データ抽出部の仕様と実装
url: http://abc.de/
lis: "ul li ."
scr:
url: "a @href“
label: “a text()”
title: { global: “title text()“ -
site: { quote: abc.de }
仕様
・ cssセレクタを並べて、最後に @属性, text(), ”.”
のいずれかを記述する。
・ データをリテラルとして埋め込みたい場合は
, quote: “埋め込む文字列” - 等とする。
・ベースセレクタより上のタグを参照したい場合は
, global: “title text()” - 等とする。
<html>
<head>
<title>hello</title>
<head>
<body>
<ul>
<li><a href=“/page/1”>page1
</a></li>
<li><a href=“/page/2”>page2
</a></li>
<li><a href=“/page/3”>page3
</a></li>
</ul>
</body>
</html>
取得ページの例 (http://abc.de/)
yamlファイルの例
yield Item(
url=“http://abc.de/page/1”,
label=“page1”,title=“hello”,
site=“abc.de” )
yield Item(
url=“http://abc.de/page/2”,
label=“page2”,title=“hello”,
site=“abc.de” )
yield Item(
url=“http://abc.de/page/3”,
label=“page3”,title=“hello”,
site=“abc.de” )
Itemの出力 (*)
class Spider(BaseSpider):
コンストラクタ:
コマンド引数からYAMLファイル名取得し読込
URLイテレータの生成
次のURL取得メソッド:
URLイテレータから次のURLを取得
HTTPレスポンスハンドラ:
セレクタの生成
YAMLに書いてあるベースセレクタを指定
forループ(抽出対象セレクタ):
YAMLの記述に従ってデータ取得しItem生成
quoteやglobalについての処理
Itemをyield (*)
URLイテレータから次を取得してRequest生成
(URLがなければ終了)
Requestをyield
Spider
Scrapy
Engine
Respons
Request
Item
web
独自Spider
project/app/spiders/yamlspider.py
データ出力/保存部の仕様と実装
実装仕様
(略)
out:
- { exists: [url,title,page,label] }
- { concat: url }
- { substr: [title,0,3] }
- { match: [label,“page([0-9.]+)",page_no] }
- { file: [data/abc_de.csv, site,title,page_no,url] }
exists : 抽出対象の存在チェック
concat: 改行の除去
substr: 文字列の一部を抜き出す
match: 正規表現マッチ&キーの生成
copy: Itemの複製(YAMLネスト用)
assign: キーの複製
replace: 文字列置換
file: 出力先ファイルと出力キーの指定
(Json,CSV,TSV,PlainTXTに対応)
fluentd(実装中): fluentd出力
例) 以下のyamlファイルに前スライドの抽出Itemを与える
Item
Pipeline
Scrapy
Engine
Spider
#label,title,page_no,url
abc.de,hel,1,http://abc.de/page/1
abc.de,hel,2,http://abc.de/page/2
abc.de,hel,3,http://abc.de/page/3
出力ファイルdata/abc_de.csv
class MyOutputPipeline:
各種のファイル出力処理
Itemの処理(item,spider):
spiderからyamlデータを取得しout部を参照
out部の処理を呼ぶ
out部の処理(item,out): # (*)
forループ(outの要素):
fileの場合、ファイル出力処理
copyの場合、item.copy()してメソッドを再帰呼び出し
existsの場合、指定キーが存在しなければ出力スキップ
以下、substrやmatchなどを処理
Item
ファイル
fluentd
(略)
ITEM_PIPELINES = {
‘app.pipelines.MyOutputPipeline': 100
}
(略)
設定ファイル(project/app/settings.py)
独自Pipeline
project/app/pipelines.py
PhantomJSを用いたAjaxページ遷移対応
・サイトによってはAjaxを使ってページをめくっていくものもある
・ScrapyのDownloaderは、Ajaxを使ったDOMの更新に対応していない
(なお、Basic認証やセッションクッキーの埋め込みには対応している)
・サーバサイドでajaxブラウジングする仕組みが必要
→ Selenium Python bindings を使って、Scrapy内でサーバサイドブラウジングを行う
Selenium Python bidingsの対応ブラウザ
- Chrome
- Firefox
- PhantomJS ← headless動作(仮想フレームバッファにレンダリング&DOMツリーを構築)
→ headless動作可能なPhantomJSを基本的に利用
url: (略)
js:
driver: phantomjs
wait: 5
page:
format:
-"__doPostBack('ctl00$ContentPlaceHolder1$pgTop$ctl01$ctl%02d','')“
- { from: 1, to: 10 }
lis: (略)
scr: (略)
out: (略)
とあるWebサイトのajaxページ遷移に対応するためのyaml記述
ブラウザの指定 (Firefoxも指定可)
ページ遷移用のwait時間(秒)
ページ遷移をキックするJavascriptコード
(URL生成部と同様の記述方法)
仕様
Download middleware部へのSeleniumDriverの埋め込み
ココに機能追加
実装
class YamlAjaxDownloader:
リクエストの処理(request,spider):
spiderからyamlデータを取得
yamlにajax対応の記述がある場合、
spiderからselenium webdriverオブジェクトを取得
yamlデータからページ遷移用のjsスニペットを取得
webdriverでjs実行
Responseオブジェクトを作って返す
そうでない場合、Noneを返し既存のDownloaderへ
独自Downloader
(略)
DOWNLOADER_MIDDLEWARES = {
'ittemi.downloaders.YamlAjaxDownloader': 100
}
(略)
設定ファイル(project/app/settings.py)
こうした処理を独自Spiderの内部で行うこともでき
るが、Scrapyの作法に則ることで
Scheculerのトラフィック調整やSpiderの並列実行
などの恩恵が受けられるようになる。
(あと、コードの見通しもよくなる)
このようにDownloaderでResponseを返せば
既存のDownloderをバイパスできる
project/app/downloaders.py
管理画面も作った
独自管理コマンド
管理コマンド
スクレイピングDSL
管理画面
MySQL
ジョブ管理部 タスク定義部
前スライドまで
で述べた処理
ポーリングループ
Scrapyタスク
Popen3
StdoutとStderr
をリダイレクト
ワークフロータスク
サイトごとのYAML記述をDBで管理.
管理画面上からスクレイピングの
ジョブを実行&結果の確認を可能に.
(管理コマンドの引数でyamlをべた書きするのは大変なので)
Spiderの仕組みを使ってまずdjangoから
yamlを取得し、それを見て動くように.
独自Spiderは最初に管理画面からYAMLを取得
管理画面スクリーンショット
タスク一覧、ジョブ実行
ジョブ一覧
Scrapy出力の確認
YAMLの登録
Demo1: Yahooニュースからの記事取得
name: "yahoo_news1"
url:
format:
- http://news.yahoo.co.jp/list/?p=%d
- { from: 1, to: 30 }
lis: "ul.list li ."
scr:
url: "a @href"
title: "span.ttl text()"
out:
file: data/yahoo_news1.jsons
(A)一覧ページ、(B)冒頭だけ表示するページ、(C) 全文表示(元記事)ページ
と3階層あるので、それぞれに対応するyamlファイルを3つ記述する
name: "yahoo_news2"
url:
file: [../data/yahoo_news1.jsons, url]
lis: ".newsLink ."
scr:
url: "a @href"
out:
file: data/yahoo_news2.jsons
name: "yahoo_news3"
url:
file: [../data/yahoo_news2.jsons, url]
lis: "#ynDetail ."
scr:
body: ".ynDetailText text()"
title: "h1.yjXL text()"
out:
file: data/yahoo_news3.jsons
取得した記事データ
現状、スクレイピング結果をさらにクローリングしていく動きには対応していないが、階層の分だけyamlを記述
しておけば対応する複数の記事を一気に処理できるのでオペレーションコスト的にはそれほど問題にならない
(A) (B) (C)
中間ファイル
http://news.yahoo.co.jp/list/
Demo2: 郵政公社からの住所-経度緯度データの取得
name: yubin_jusho1
url:
format:
- "http://map.japanpost.jp/pc/addrlist.php?code=%02d"
- { from: 1, to: 47 }
lis: "td span.mfont3 ."
scr:
name: { global: "title text()" }
url: "a @href"
addr: "a text()"
out:
- { exists: [url,addr] }
- { concat: url }
- { substr: [name,0,-10] }
- { file: data/yubin_jusho1.jsons }
name: yubin_jusho2
url:
file: [../data/yubin_jusho1.jsons, url]
lis: "td span.mfont3 ."
scr:
name: { global: "title text()" }
url: "a @href"
addr: "a text()"
out:
- { exists: [name,url,addr] }
- { concat: url }
- { substr: [name,0,-10] }
- { match: [url,"nl=([0-9.]+).*el=([0-9.]+)",lat,lon] }
- { exists: [lat,lon] }
- { file: [data/yubin_jusho2.tsv,name,addr,lat,lon] }
(A)都道府県直下の市町村 (B) 市町村内の地名、の2階層 → YAML2つ
http://map.japanpost.jp/pc/
(A) (B)
(20.5MB)
(230KB)
Demo3: ajax対応サイトからのデータの取得
(非公開:会場のみ実演)
まとめ
• 典型的なWebスクレイピングタスクをYAMLベースのDSLで定義した
• YAMLを解釈実行するWebスクレイピングプログラムをScrapyで作成
• Ajaxページ遷移に対応するためSeleniumWebDriverを組み込んだ
– PhantomJSのおかげでブラウザを立ち上げずに処理可能
• サイトごとのYAMLと実行の管理負担を減らす画面をDjangoで作成した
最後に宣伝を少し…
アドファイブ(株)では、本スクレイピングシステムの導入及びサポート、
またScrapyを用いたシステム開発の支援及びコンサルティングについての
事業を行っております。ご依頼ご質問等ありましたらぜひお問い合わせください。
あと、学生アルバイトさんも絶賛募集中です。よろしくお願いします。
→ こうしたYAMLでリッチな設定ファイルを作る、
ドメイン特化言語的アプローチはビッグデータ処理の
ベストプラクティスの一つではないかと考えています。
(というわけで弊社では現在、データのビジュアライズダッシュボードを作るDSLについても研究開発中です)

More Related Content

What's hot

ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けモノビット エンジン
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexprGenya Murakami
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織Takafumi ONAKA
 
研究分野をサーベイする
研究分野をサーベイする研究分野をサーベイする
研究分野をサーベイするTakayuki Itoh
 
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~Takuya Akiba
 
Active Learning 入門
Active Learning 入門Active Learning 入門
Active Learning 入門Shuyo Nakatani
 
近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer近年のHierarchical Vision Transformer
近年のHierarchical Vision TransformerYusuke Uchida
 
「速」を落とさないコードレビュー
「速」を落とさないコードレビュー「速」を落とさないコードレビュー
「速」を落とさないコードレビューTakafumi ONAKA
 
【メタサーベイ】基盤モデル / Foundation Models
【メタサーベイ】基盤モデル / Foundation Models【メタサーベイ】基盤モデル / Foundation Models
【メタサーベイ】基盤モデル / Foundation Modelscvpaper. challenge
 
最適化超入門
最適化超入門最適化超入門
最適化超入門Takami Sato
 
「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件についてTakayuki Yato
 
Transformerを多層にする際の勾配消失問題と解決法について
Transformerを多層にする際の勾配消失問題と解決法についてTransformerを多層にする際の勾配消失問題と解決法について
Transformerを多層にする際の勾配消失問題と解決法についてSho Takase
 
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリングmlm_kansai
 
MQTTとAMQPと.NET
MQTTとAMQPと.NETMQTTとAMQPと.NET
MQTTとAMQPと.NETterurou
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学MITSUNARI Shigeo
 
密度比推定による時系列データの異常検知
密度比推定による時系列データの異常検知密度比推定による時系列データの異常検知
密度比推定による時系列データの異常検知- Core Concept Technologies
 

What's hot (20)

ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
研究分野をサーベイする
研究分野をサーベイする研究分野をサーベイする
研究分野をサーベイする
 
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
 
Active Learning 入門
Active Learning 入門Active Learning 入門
Active Learning 入門
 
近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer
 
「速」を落とさないコードレビュー
「速」を落とさないコードレビュー「速」を落とさないコードレビュー
「速」を落とさないコードレビュー
 
自然言語処理の最新技術動向紹介
自然言語処理の最新技術動向紹介自然言語処理の最新技術動向紹介
自然言語処理の最新技術動向紹介
 
Oss貢献超入門
Oss貢献超入門Oss貢献超入門
Oss貢献超入門
 
Lucas kanade法について
Lucas kanade法についてLucas kanade法について
Lucas kanade法について
 
【メタサーベイ】基盤モデル / Foundation Models
【メタサーベイ】基盤モデル / Foundation Models【メタサーベイ】基盤モデル / Foundation Models
【メタサーベイ】基盤モデル / Foundation Models
 
最適化超入門
最適化超入門最適化超入門
最適化超入門
 
「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について
 
Transformerを多層にする際の勾配消失問題と解決法について
Transformerを多層にする際の勾配消失問題と解決法についてTransformerを多層にする際の勾配消失問題と解決法について
Transformerを多層にする際の勾配消失問題と解決法について
 
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
 
MQTTとAMQPと.NET
MQTTとAMQPと.NETMQTTとAMQPと.NET
MQTTとAMQPと.NET
 
Docker Compose 徹底解説
Docker Compose 徹底解説Docker Compose 徹底解説
Docker Compose 徹底解説
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
密度比推定による時系列データの異常検知
密度比推定による時系列データの異常検知密度比推定による時系列データの異常検知
密度比推定による時系列データの異常検知
 

Similar to ScrapyとPhantomJSを用いたスクレイピングDSL

CasperJSを使って任意のWebサイトを電子書籍化する方法
CasperJSを使って任意のWebサイトを電子書籍化する方法CasperJSを使って任意のWebサイトを電子書籍化する方法
CasperJSを使って任意のWebサイトを電子書籍化する方法Masayuki Isobe
 
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkSpring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkToshiaki Maki
 
JavaScriptテンプレートエンジンで活かすData API
JavaScriptテンプレートエンジンで活かすData APIJavaScriptテンプレートエンジンで活かすData API
JavaScriptテンプレートエンジンで活かすData APIHajime Fujimoto
 
ブラウザから飛び出すWeb技術とHTML5
ブラウザから飛び出すWeb技術とHTML5ブラウザから飛び出すWeb技術とHTML5
ブラウザから飛び出すWeb技術とHTML5Wakasa Masao
 
Power Appsで Excel関数を利用する3つの方法
Power Appsで Excel関数を利用する3つの方法Power Appsで Excel関数を利用する3つの方法
Power Appsで Excel関数を利用する3つの方法Nagao Hiroaki
 
jQuery Mobile 最新情報 & Tips
jQuery Mobile 最新情報 & TipsjQuery Mobile 最新情報 & Tips
jQuery Mobile 最新情報 & Tipsyoshikawa_t
 
ディレクションのフロントエンド開発 @JSオジサン 12/17
ディレクションのフロントエンド開発 @JSオジサン 12/17ディレクションのフロントエンド開発 @JSオジサン 12/17
ディレクションのフロントエンド開発 @JSオジサン 12/17Yosuke Doke
 
Djangoによるスマホアプリバックエンドの実装
Djangoによるスマホアプリバックエンドの実装Djangoによるスマホアプリバックエンドの実装
Djangoによるスマホアプリバックエンドの実装Nakazawa Yuichi
 
Rails初心者レッスン lesson3 3edition
Rails初心者レッスン lesson3 3editionRails初心者レッスン lesson3 3edition
Rails初心者レッスン lesson3 3editionSatomi Tsujita
 
jQuery Mobileカスタマイズ自由自在 v1.2
jQuery Mobileカスタマイズ自由自在 v1.2jQuery Mobileカスタマイズ自由自在 v1.2
jQuery Mobileカスタマイズ自由自在 v1.2yoshikawa_t
 
コピー自動生成プロダクトでDataflowを導入した話
コピー自動生成プロダクトでDataflowを導入した話コピー自動生成プロダクトでDataflowを導入した話
コピー自動生成プロダクトでDataflowを導入した話ShunyoKawamoto
 
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会Takayuki Shimizukawa
 
はじめよう Backbone.js
はじめよう Backbone.jsはじめよう Backbone.js
はじめよう Backbone.jsHiroki Toyokawa
 
ABEJAの デジタルトランスフォーメーション 〜AIが実現するプロセス⾰命〜
ABEJAの デジタルトランスフォーメーション 〜AIが実現するプロセス⾰命〜ABEJAの デジタルトランスフォーメーション 〜AIが実現するプロセス⾰命〜
ABEJAの デジタルトランスフォーメーション 〜AIが実現するプロセス⾰命〜日本ディープラーニング協会(JDLA)
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回Naoyuki Yamada
 
第二回機械学習アルゴリズム実装会 - LDA
第二回機械学習アルゴリズム実装会 - LDA第二回機械学習アルゴリズム実装会 - LDA
第二回機械学習アルゴリズム実装会 - LDAMasayuki Isobe
 
ROS JAPAN Users Group Meetup 03
ROS JAPAN Users Group Meetup 03ROS JAPAN Users Group Meetup 03
ROS JAPAN Users Group Meetup 03Daiki Maekawa
 

Similar to ScrapyとPhantomJSを用いたスクレイピングDSL (20)

CasperJSを使って任意のWebサイトを電子書籍化する方法
CasperJSを使って任意のWebサイトを電子書籍化する方法CasperJSを使って任意のWebサイトを電子書籍化する方法
CasperJSを使って任意のWebサイトを電子書籍化する方法
 
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkSpring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
 
JavaScriptテンプレートエンジンで活かすData API
JavaScriptテンプレートエンジンで活かすData APIJavaScriptテンプレートエンジンで活かすData API
JavaScriptテンプレートエンジンで活かすData API
 
ブラウザから飛び出すWeb技術とHTML5
ブラウザから飛び出すWeb技術とHTML5ブラウザから飛び出すWeb技術とHTML5
ブラウザから飛び出すWeb技術とHTML5
 
Power Appsで Excel関数を利用する3つの方法
Power Appsで Excel関数を利用する3つの方法Power Appsで Excel関数を利用する3つの方法
Power Appsで Excel関数を利用する3つの方法
 
jQuery Mobile 最新情報 & Tips
jQuery Mobile 最新情報 & TipsjQuery Mobile 最新情報 & Tips
jQuery Mobile 最新情報 & Tips
 
ディレクションのフロントエンド開発 @JSオジサン 12/17
ディレクションのフロントエンド開発 @JSオジサン 12/17ディレクションのフロントエンド開発 @JSオジサン 12/17
ディレクションのフロントエンド開発 @JSオジサン 12/17
 
Djangoによるスマホアプリバックエンドの実装
Djangoによるスマホアプリバックエンドの実装Djangoによるスマホアプリバックエンドの実装
Djangoによるスマホアプリバックエンドの実装
 
Rails初心者レッスン lesson3 3edition
Rails初心者レッスン lesson3 3editionRails初心者レッスン lesson3 3edition
Rails初心者レッスン lesson3 3edition
 
jQuery Mobileカスタマイズ自由自在 v1.2
jQuery Mobileカスタマイズ自由自在 v1.2jQuery Mobileカスタマイズ自由自在 v1.2
jQuery Mobileカスタマイズ自由自在 v1.2
 
コピー自動生成プロダクトでDataflowを導入した話
コピー自動生成プロダクトでDataflowを導入した話コピー自動生成プロダクトでDataflowを導入した話
コピー自動生成プロダクトでDataflowを導入した話
 
jQuery Mobileの基礎
jQuery Mobileの基礎jQuery Mobileの基礎
jQuery Mobileの基礎
 
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
 
はじめよう Backbone.js
はじめよう Backbone.jsはじめよう Backbone.js
はじめよう Backbone.js
 
APIMeetup 20170329_ichimura
APIMeetup 20170329_ichimuraAPIMeetup 20170329_ichimura
APIMeetup 20170329_ichimura
 
ABEJAの デジタルトランスフォーメーション 〜AIが実現するプロセス⾰命〜
ABEJAの デジタルトランスフォーメーション 〜AIが実現するプロセス⾰命〜ABEJAの デジタルトランスフォーメーション 〜AIが実現するプロセス⾰命〜
ABEJAの デジタルトランスフォーメーション 〜AIが実現するプロセス⾰命〜
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 
第二回機械学習アルゴリズム実装会 - LDA
第二回機械学習アルゴリズム実装会 - LDA第二回機械学習アルゴリズム実装会 - LDA
第二回機械学習アルゴリズム実装会 - LDA
 
Firefoxosハンズオン
FirefoxosハンズオンFirefoxosハンズオン
Firefoxosハンズオン
 
ROS JAPAN Users Group Meetup 03
ROS JAPAN Users Group Meetup 03ROS JAPAN Users Group Meetup 03
ROS JAPAN Users Group Meetup 03
 

More from Masayuki Isobe

オープンソースを用いたドローンの自律制御ソフトウェア技術
オープンソースを用いたドローンの自律制御ソフトウェア技術オープンソースを用いたドローンの自律制御ソフトウェア技術
オープンソースを用いたドローンの自律制御ソフトウェア技術Masayuki Isobe
 
関数型プログラミングとモナド
関数型プログラミングとモナド関数型プログラミングとモナド
関数型プログラミングとモナドMasayuki Isobe
 
ジャパンドローンセミナー
ジャパンドローンセミナージャパンドローンセミナー
ジャパンドローンセミナーMasayuki Isobe
 
AIBOX DroneBrain 製品パンフレット
AIBOX DroneBrain 製品パンフレットAIBOX DroneBrain 製品パンフレット
AIBOX DroneBrain 製品パンフレットMasayuki Isobe
 
ファイブソリューションズデベロッパーネットワーク
ファイブソリューションズデベロッパーネットワークファイブソリューションズデベロッパーネットワーク
ファイブソリューションズデベロッパーネットワークMasayuki Isobe
 
ドローン向けソフトウェア事業
ドローン向けソフトウェア事業ドローン向けソフトウェア事業
ドローン向けソフトウェア事業Masayuki Isobe
 
RDF/OWLの概要及びOSS実装、及び活用イメージについて
RDF/OWLの概要及びOSS実装、及び活用イメージについてRDF/OWLの概要及びOSS実装、及び活用イメージについて
RDF/OWLの概要及びOSS実装、及び活用イメージについてMasayuki Isobe
 
第三回機械学習アルゴリズム実装会イントロダクション
第三回機械学習アルゴリズム実装会イントロダクション第三回機械学習アルゴリズム実装会イントロダクション
第三回機械学習アルゴリズム実装会イントロダクションMasayuki Isobe
 
ブランディング指標の数値化について
ブランディング指標の数値化についてブランディング指標の数値化について
ブランディング指標の数値化についてMasayuki Isobe
 
TEDxTitech 2013 speech material
TEDxTitech 2013 speech materialTEDxTitech 2013 speech material
TEDxTitech 2013 speech materialMasayuki Isobe
 
Rec sys2013 reading_isobe
Rec sys2013 reading_isobeRec sys2013 reading_isobe
Rec sys2013 reading_isobeMasayuki Isobe
 
広告ナビゲータ・広告シミュレータ
広告ナビゲータ・広告シミュレータ広告ナビゲータ・広告シミュレータ
広告ナビゲータ・広告シミュレータMasayuki Isobe
 
Uuyアドテクセミナー
UuyアドテクセミナーUuyアドテクセミナー
UuyアドテクセミナーMasayuki Isobe
 
第12回モヤLT発表資料
第12回モヤLT発表資料第12回モヤLT発表資料
第12回モヤLT発表資料Masayuki Isobe
 
Tokyo.R #19 発表資料 「Rで色々やってみました」
Tokyo.R #19 発表資料 「Rで色々やってみました」Tokyo.R #19 発表資料 「Rで色々やってみました」
Tokyo.R #19 発表資料 「Rで色々やってみました」Masayuki Isobe
 

More from Masayuki Isobe (19)

オープンソースを用いたドローンの自律制御ソフトウェア技術
オープンソースを用いたドローンの自律制御ソフトウェア技術オープンソースを用いたドローンの自律制御ソフトウェア技術
オープンソースを用いたドローンの自律制御ソフトウェア技術
 
関数型プログラミングとモナド
関数型プログラミングとモナド関数型プログラミングとモナド
関数型プログラミングとモナド
 
ジャパンドローンセミナー
ジャパンドローンセミナージャパンドローンセミナー
ジャパンドローンセミナー
 
AIBOX DroneBrain 製品パンフレット
AIBOX DroneBrain 製品パンフレットAIBOX DroneBrain 製品パンフレット
AIBOX DroneBrain 製品パンフレット
 
ファイブソリューションズデベロッパーネットワーク
ファイブソリューションズデベロッパーネットワークファイブソリューションズデベロッパーネットワーク
ファイブソリューションズデベロッパーネットワーク
 
ドローン向けソフトウェア事業
ドローン向けソフトウェア事業ドローン向けソフトウェア事業
ドローン向けソフトウェア事業
 
RDF/OWLの概要及びOSS実装、及び活用イメージについて
RDF/OWLの概要及びOSS実装、及び活用イメージについてRDF/OWLの概要及びOSS実装、及び活用イメージについて
RDF/OWLの概要及びOSS実装、及び活用イメージについて
 
第三回機械学習アルゴリズム実装会イントロダクション
第三回機械学習アルゴリズム実装会イントロダクション第三回機械学習アルゴリズム実装会イントロダクション
第三回機械学習アルゴリズム実装会イントロダクション
 
ブランディング指標の数値化について
ブランディング指標の数値化についてブランディング指標の数値化について
ブランディング指標の数値化について
 
TEDxTitech 2013 speech material
TEDxTitech 2013 speech materialTEDxTitech 2013 speech material
TEDxTitech 2013 speech material
 
Rec sys2013 reading_isobe
Rec sys2013 reading_isobeRec sys2013 reading_isobe
Rec sys2013 reading_isobe
 
広告ナビゲータ・広告シミュレータ
広告ナビゲータ・広告シミュレータ広告ナビゲータ・広告シミュレータ
広告ナビゲータ・広告シミュレータ
 
rzmq
rzmqrzmq
rzmq
 
Uuyアドテクセミナー
UuyアドテクセミナーUuyアドテクセミナー
Uuyアドテクセミナー
 
第12回モヤLT発表資料
第12回モヤLT発表資料第12回モヤLT発表資料
第12回モヤLT発表資料
 
Tokyo.R 26 LT isobe
Tokyo.R 26 LT isobeTokyo.R 26 LT isobe
Tokyo.R 26 LT isobe
 
Tokyo r 25_lt_isobe
Tokyo r 25_lt_isobeTokyo r 25_lt_isobe
Tokyo r 25_lt_isobe
 
Tokyo.R #22 LT
Tokyo.R #22 LTTokyo.R #22 LT
Tokyo.R #22 LT
 
Tokyo.R #19 発表資料 「Rで色々やってみました」
Tokyo.R #19 発表資料 「Rで色々やってみました」Tokyo.R #19 発表資料 「Rで色々やってみました」
Tokyo.R #19 発表資料 「Rで色々やってみました」
 

Recently uploaded

PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdffurutsuka
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 

Recently uploaded (7)

PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdf
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 

ScrapyとPhantomJSを用いたスクレイピングDSL

  • 2. 自己紹介 • 礒部正幸(いそべ まさゆき) • 職業: ソフトウェアエンジニア • 現在: アドファイブ(株) 代表 http://www.adfive.net – 現体制: 代表1名 + 外注数名 : お問い合わせ – 自社製品: モバイルO2Oアプリ/オウンドメディア/アドサーバ – 受託業務: システムコンサルティング/システム開発/データ分析 • 東工大卒 (B:情報工学科、M:計算工学専攻) • インターネット活動 – TwitterID: @chiral – (ブログ:アドファイブ日記) http://d.hatena.ne.jp/isobe1978/ • 「機械学習ハッカソン」主催: http://mlhackathon.connpass.com/ • 近年作ったスクレイピング利用システム – パケットデータから閲覧Webページの画面キャプチャ再構成 (PhantomJS+自作プロキシーサーバ) – WebサイトのEPub電子書籍化ツール(Node.js/CasperJS) – WebスクレイピングDSL( Scrapy/PhantomJS) – Webスクレイピングジョブ管理システム(Django) LTで発表 本資料
  • 3. Scrapyとは • Pythonで書かれたWebスクレイピングフレームワーク • 2008年に初期リリース,比較的枯れていて安定動作 • Twisted(非同期イベント駆動処理ライブラリ)ベース • XPATHやCSSでセレクタとスクレイピング処理を記述可能 • 欧米の大手企業の自社システムとして多数利用実績あり • スケーラブル(例: EC2+Scrapyで2.5億ページを40時間で処理した天才科学者M.N) • スクレイピングシステムにおける各機能単位がブラガブルに 設計されている → アジャイル開発にすごく合う(発表者の私見)
  • 4. Scrapyのアーキテクチャ ・必要十分な機能分割がなされた綺麗な設計になっている。 ① Spider - 取得したいページのURLを Schedulerにリクエスト - 取得したページの内容をスクレイ ピングしてItemとしItemPipelineへ ② Scheduler - リクエストのトラフィック調整 (同一ドメインへのアクセス間隔等) ③ Downloader - Webへのアクセス手段をフックする ④ Item Pipeline - スクレイピングしたItemを出力 Storage(File, DB, ...), e-mail, … etc.① ② ④ ③ → とりあえずSpiderを作れば動く。それ以外は必要に応じて追加する。
  • 5. 一般的なスクレイピング手順 対象ページのURLを生成 Webアクセス/HTMLのパース セレクタ指定 & データ抽出 データの出力 / 保存 http://www.xxx.yyy/info?page=1 http://www.xxx.yyy/info?page=2 http://www.xxx.yyy/about … Scrapy作業ステップ (イメージ) wget / curl … Chrome / Firefox … jQuery / css / xpath .. JSONファイル, MySQL, etc.. ScrapyでのPythonプログラムはなるべく共通に作って サイトごとの違いを外部の設定ファイルで吸収したい。
  • 6. (参考1)ドメイン特化言語 ・ DSL : ドメイン特化言語 - あるドメインの課題を解くのに特化した プログラミング言語。 - 汎用性に乏しい代わりに、「ドメイン知識の記述」 「効率的な動作」 「少ない記述量」 等が可能に → いわゆるアプリケーションの「設定ファイル」を よりリッチにしてソフトウェアのインタフェースを 柔軟にするといったコンセプト 内部DSL 外部DSL 米国の著名なアーキテクト マーティンファウラー御大は 近年、DSLを積極的に推進中 Webスクレイピング専用のDSLがあったら便利そう (参考)DSLの大分類 ・設定ファイルを、アプリケーションと同じ 言語で記述するというやり方 ・例えば、Ruby on RailsにおけるRakefile (メリット) 開発コストが低い (デメリット) 記述方法がシステム開発者寄り ・専用の文法を持った設定ファイルを定 義して実装するというやり方 ・例えば、Apacheの設定ファイル (メリット)記述方法がドメイン従事者寄り (デメリット)開発コストが高い
  • 7. • 「WebスクレイピングDSL」 の検討 – 内部DSL案: Pythonのモジュールローダに則る必要があって大変 → 不採用 – 外部DSL案:専用の文法を作るとパーサー等が大変 → XML/JSON/YAMLなど既存の形式を利用 • XML / JSON / YAMLの特徴 – (当然ながら)いずれもパーサーがPythonライブラリとして存在する – 再帰的な木構造を自由に表現可能 (一般にプログラムは内部的に木構造であり、表現力が高い) – XML / JSONは普及しており、学習コストが低い – XMLは人間が読み書きするのにあまり向いてない – JSONは整形すれば読めるが、書くのが結構大変 – YAMLは人間が読み書きするのにより適している → 採用 (参考2) YAML ベースDSLのススメ 対象ページのURLを生成 Webアクセス/HTMLのパース セレクタ指定 & データ抽出 データの出力 / 保存 作業ステップ YAMLファイル 各ステップに対応する処理をYAMLの項目として記述
  • 8. スクレイピングDSLの仕様と実装 name: "yahoo_news" url: format: - http://news.yahoo.co.jp/list/?p=%d - { from: 1, to: 30 } lis: "ul.list li ." scr: url: "a @href" title: "span.ttl text()" out: file: data/yahoo_news.jsons スクレイピングタスク名 対象ページのURL ページ内のベースとなるセレクタ 抽出項目(ベースからの相対セレクタ) データの出力/保存先 Scrapyの各パーツにて 上記の記述を解釈実行 する機能を実装 独自Spider 独自Downloader 独自Pipeline Scrapyのsetting.py
  • 9. URL指定部の仕様と実装 仕様 - http://aaa.bbb/ - { or: [taro,jiro] } - / - { from: 1, to: 3 } 実装 ・配列=イテレータの積 * “http://aaa.bbb/taro/1”, “http://aaa.bbb/taro/2”, “http://aaa.bbb/taro/3”, “http://aaa.bbb/jiro/1”, “http://aaa.bbb/jiro/2”, “http://aaa.bbb/jiro/3” + ・from/to=数イテレータ { from: 1, to: 5 } [ 1,2,3,4,5 ] ・or=要素イテレータ { or: [apple,orange] } * “apple”,”orange” + ・format=文字列生成 format: - “%s?page=%d” - hoge - 777 *“hoge?page=777”+ これらを組み合わせて(多階層にネストも可能)、対象ページURL集合を指定する ・file=ファイル行イテレータ , “title”:”hogehoge”, “url”:”http://a.b.c/def” } , “title”:”fugafuga”, “url”:”http://g.h.i/jk” } … fileの例)/var/scrapy/data.jsons file: - /var/scrapy/data.jsons - url * “http://a.b.c/def”, “http://g.h.i/jk”, … + ・イテレータの積にはPythonのitertoolsパッケージにあるproduct()を用いる ・要素イテレータor、数イテレータfrom/toは、要素をforループで回してyield ・文字列生成formatは、1番目の要素 % (2番目以降) で生成してyield ・ファイル行イテレータは、ファイルを読み込んで行ごとにforループで回してyield
  • 10. 実装 データ抽出部の仕様と実装 url: http://abc.de/ lis: "ul li ." scr: url: "a @href“ label: “a text()” title: { global: “title text()“ - site: { quote: abc.de } 仕様 ・ cssセレクタを並べて、最後に @属性, text(), ”.” のいずれかを記述する。 ・ データをリテラルとして埋め込みたい場合は , quote: “埋め込む文字列” - 等とする。 ・ベースセレクタより上のタグを参照したい場合は , global: “title text()” - 等とする。 <html> <head> <title>hello</title> <head> <body> <ul> <li><a href=“/page/1”>page1 </a></li> <li><a href=“/page/2”>page2 </a></li> <li><a href=“/page/3”>page3 </a></li> </ul> </body> </html> 取得ページの例 (http://abc.de/) yamlファイルの例 yield Item( url=“http://abc.de/page/1”, label=“page1”,title=“hello”, site=“abc.de” ) yield Item( url=“http://abc.de/page/2”, label=“page2”,title=“hello”, site=“abc.de” ) yield Item( url=“http://abc.de/page/3”, label=“page3”,title=“hello”, site=“abc.de” ) Itemの出力 (*) class Spider(BaseSpider): コンストラクタ: コマンド引数からYAMLファイル名取得し読込 URLイテレータの生成 次のURL取得メソッド: URLイテレータから次のURLを取得 HTTPレスポンスハンドラ: セレクタの生成 YAMLに書いてあるベースセレクタを指定 forループ(抽出対象セレクタ): YAMLの記述に従ってデータ取得しItem生成 quoteやglobalについての処理 Itemをyield (*) URLイテレータから次を取得してRequest生成 (URLがなければ終了) Requestをyield Spider Scrapy Engine Respons Request Item web 独自Spider project/app/spiders/yamlspider.py
  • 11. データ出力/保存部の仕様と実装 実装仕様 (略) out: - { exists: [url,title,page,label] } - { concat: url } - { substr: [title,0,3] } - { match: [label,“page([0-9.]+)",page_no] } - { file: [data/abc_de.csv, site,title,page_no,url] } exists : 抽出対象の存在チェック concat: 改行の除去 substr: 文字列の一部を抜き出す match: 正規表現マッチ&キーの生成 copy: Itemの複製(YAMLネスト用) assign: キーの複製 replace: 文字列置換 file: 出力先ファイルと出力キーの指定 (Json,CSV,TSV,PlainTXTに対応) fluentd(実装中): fluentd出力 例) 以下のyamlファイルに前スライドの抽出Itemを与える Item Pipeline Scrapy Engine Spider #label,title,page_no,url abc.de,hel,1,http://abc.de/page/1 abc.de,hel,2,http://abc.de/page/2 abc.de,hel,3,http://abc.de/page/3 出力ファイルdata/abc_de.csv class MyOutputPipeline: 各種のファイル出力処理 Itemの処理(item,spider): spiderからyamlデータを取得しout部を参照 out部の処理を呼ぶ out部の処理(item,out): # (*) forループ(outの要素): fileの場合、ファイル出力処理 copyの場合、item.copy()してメソッドを再帰呼び出し existsの場合、指定キーが存在しなければ出力スキップ 以下、substrやmatchなどを処理 Item ファイル fluentd (略) ITEM_PIPELINES = { ‘app.pipelines.MyOutputPipeline': 100 } (略) 設定ファイル(project/app/settings.py) 独自Pipeline project/app/pipelines.py
  • 12. PhantomJSを用いたAjaxページ遷移対応 ・サイトによってはAjaxを使ってページをめくっていくものもある ・ScrapyのDownloaderは、Ajaxを使ったDOMの更新に対応していない (なお、Basic認証やセッションクッキーの埋め込みには対応している) ・サーバサイドでajaxブラウジングする仕組みが必要 → Selenium Python bindings を使って、Scrapy内でサーバサイドブラウジングを行う Selenium Python bidingsの対応ブラウザ - Chrome - Firefox - PhantomJS ← headless動作(仮想フレームバッファにレンダリング&DOMツリーを構築) → headless動作可能なPhantomJSを基本的に利用 url: (略) js: driver: phantomjs wait: 5 page: format: -"__doPostBack('ctl00$ContentPlaceHolder1$pgTop$ctl01$ctl%02d','')“ - { from: 1, to: 10 } lis: (略) scr: (略) out: (略) とあるWebサイトのajaxページ遷移に対応するためのyaml記述 ブラウザの指定 (Firefoxも指定可) ページ遷移用のwait時間(秒) ページ遷移をキックするJavascriptコード (URL生成部と同様の記述方法) 仕様
  • 13. Download middleware部へのSeleniumDriverの埋め込み ココに機能追加 実装 class YamlAjaxDownloader: リクエストの処理(request,spider): spiderからyamlデータを取得 yamlにajax対応の記述がある場合、 spiderからselenium webdriverオブジェクトを取得 yamlデータからページ遷移用のjsスニペットを取得 webdriverでjs実行 Responseオブジェクトを作って返す そうでない場合、Noneを返し既存のDownloaderへ 独自Downloader (略) DOWNLOADER_MIDDLEWARES = { 'ittemi.downloaders.YamlAjaxDownloader': 100 } (略) 設定ファイル(project/app/settings.py) こうした処理を独自Spiderの内部で行うこともでき るが、Scrapyの作法に則ることで Scheculerのトラフィック調整やSpiderの並列実行 などの恩恵が受けられるようになる。 (あと、コードの見通しもよくなる) このようにDownloaderでResponseを返せば 既存のDownloderをバイパスできる project/app/downloaders.py
  • 16. Demo1: Yahooニュースからの記事取得 name: "yahoo_news1" url: format: - http://news.yahoo.co.jp/list/?p=%d - { from: 1, to: 30 } lis: "ul.list li ." scr: url: "a @href" title: "span.ttl text()" out: file: data/yahoo_news1.jsons (A)一覧ページ、(B)冒頭だけ表示するページ、(C) 全文表示(元記事)ページ と3階層あるので、それぞれに対応するyamlファイルを3つ記述する name: "yahoo_news2" url: file: [../data/yahoo_news1.jsons, url] lis: ".newsLink ." scr: url: "a @href" out: file: data/yahoo_news2.jsons name: "yahoo_news3" url: file: [../data/yahoo_news2.jsons, url] lis: "#ynDetail ." scr: body: ".ynDetailText text()" title: "h1.yjXL text()" out: file: data/yahoo_news3.jsons 取得した記事データ 現状、スクレイピング結果をさらにクローリングしていく動きには対応していないが、階層の分だけyamlを記述 しておけば対応する複数の記事を一気に処理できるのでオペレーションコスト的にはそれほど問題にならない (A) (B) (C) 中間ファイル http://news.yahoo.co.jp/list/
  • 17. Demo2: 郵政公社からの住所-経度緯度データの取得 name: yubin_jusho1 url: format: - "http://map.japanpost.jp/pc/addrlist.php?code=%02d" - { from: 1, to: 47 } lis: "td span.mfont3 ." scr: name: { global: "title text()" } url: "a @href" addr: "a text()" out: - { exists: [url,addr] } - { concat: url } - { substr: [name,0,-10] } - { file: data/yubin_jusho1.jsons } name: yubin_jusho2 url: file: [../data/yubin_jusho1.jsons, url] lis: "td span.mfont3 ." scr: name: { global: "title text()" } url: "a @href" addr: "a text()" out: - { exists: [name,url,addr] } - { concat: url } - { substr: [name,0,-10] } - { match: [url,"nl=([0-9.]+).*el=([0-9.]+)",lat,lon] } - { exists: [lat,lon] } - { file: [data/yubin_jusho2.tsv,name,addr,lat,lon] } (A)都道府県直下の市町村 (B) 市町村内の地名、の2階層 → YAML2つ http://map.japanpost.jp/pc/ (A) (B) (20.5MB) (230KB)
  • 19. まとめ • 典型的なWebスクレイピングタスクをYAMLベースのDSLで定義した • YAMLを解釈実行するWebスクレイピングプログラムをScrapyで作成 • Ajaxページ遷移に対応するためSeleniumWebDriverを組み込んだ – PhantomJSのおかげでブラウザを立ち上げずに処理可能 • サイトごとのYAMLと実行の管理負担を減らす画面をDjangoで作成した 最後に宣伝を少し… アドファイブ(株)では、本スクレイピングシステムの導入及びサポート、 またScrapyを用いたシステム開発の支援及びコンサルティングについての 事業を行っております。ご依頼ご質問等ありましたらぜひお問い合わせください。 あと、学生アルバイトさんも絶賛募集中です。よろしくお願いします。 → こうしたYAMLでリッチな設定ファイルを作る、 ドメイン特化言語的アプローチはビッグデータ処理の ベストプラクティスの一つではないかと考えています。 (というわけで弊社では現在、データのビジュアライズダッシュボードを作るDSLについても研究開発中です)