SlideShare uma empresa Scribd logo
1 de 19
Baixar para ler 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についても研究開発中です)

Mais conteúdo relacionado

Mais procurados

爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話Kentaro Yoshida
 
Unified JVM Logging
Unified JVM LoggingUnified JVM Logging
Unified JVM LoggingYuji Kubota
 
PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったことPHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったことgree_tech
 
.NET 7期待の新機能
.NET 7期待の新機能.NET 7期待の新機能
.NET 7期待の新機能TomomitsuKusaba
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...NTT DATA Technology & Innovation
 
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) Hironobu Isoda
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜Megagon Labs
 
比較サイトの検索改善(SPA から SSR に変換)
比較サイトの検索改善(SPA から SSR に変換)比較サイトの検索改善(SPA から SSR に変換)
比較サイトの検索改善(SPA から SSR に変換)gree_tech
 
日本語テストメソッドについて
日本語テストメソッドについて日本語テストメソッドについて
日本語テストメソッドについてkumake
 
webSocket通信を知らないiOSエンジニアが知っておいて損はしない(経験談的な)軽い話
webSocket通信を知らないiOSエンジニアが知っておいて損はしない(経験談的な)軽い話webSocket通信を知らないiOSエンジニアが知っておいて損はしない(経験談的な)軽い話
webSocket通信を知らないiOSエンジニアが知っておいて損はしない(経験談的な)軽い話Yuhei Miyazato
 
FastAPIを使って 機械学習モデルをapi化してみた
FastAPIを使って 機械学習モデルをapi化してみたFastAPIを使って 機械学習モデルをapi化してみた
FastAPIを使って 機械学習モデルをapi化してみたSho Tanaka
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメYoji Kanno
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホンYou_Kinjoh
 
こわくない Git
こわくない Gitこわくない Git
こわくない GitKota Saito
 

Mais procurados (20)

爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話
 
Unified JVM Logging
Unified JVM LoggingUnified JVM Logging
Unified JVM Logging
 
PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったことPHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったこと
 
SpringBootTest入門
SpringBootTest入門SpringBootTest入門
SpringBootTest入門
 
.NET 7期待の新機能
.NET 7期待の新機能.NET 7期待の新機能
.NET 7期待の新機能
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
 
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
 
ゼロから始める転移学習
ゼロから始める転移学習ゼロから始める転移学習
ゼロから始める転移学習
 
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajpAt least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
GiNZAで始める日本語依存構造解析 〜CaboCha, UDPipe, Stanford NLPとの比較〜
 
比較サイトの検索改善(SPA から SSR に変換)
比較サイトの検索改善(SPA から SSR に変換)比較サイトの検索改善(SPA から SSR に変換)
比較サイトの検索改善(SPA から SSR に変換)
 
日本語テストメソッドについて
日本語テストメソッドについて日本語テストメソッドについて
日本語テストメソッドについて
 
webSocket通信を知らないiOSエンジニアが知っておいて損はしない(経験談的な)軽い話
webSocket通信を知らないiOSエンジニアが知っておいて損はしない(経験談的な)軽い話webSocket通信を知らないiOSエンジニアが知っておいて損はしない(経験談的な)軽い話
webSocket通信を知らないiOSエンジニアが知っておいて損はしない(経験談的な)軽い話
 
FastAPIを使って 機械学習モデルをapi化してみた
FastAPIを使って 機械学習モデルをapi化してみたFastAPIを使って 機械学習モデルをapi化してみた
FastAPIを使って 機械学習モデルをapi化してみた
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホン
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
 

Semelhante a 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
 

Semelhante a 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
 

Mais de 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
 

Mais de 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で色々やってみました」
 

Último

TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfMatsushita Laboratory
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~arts yokohama
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)ssuser539845
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見Shumpei Kishi
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdfAyachika Kitazaki
 
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦Sadao Tokuyama
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor arts yokohama
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-LoopへTetsuya Nihonmatsu
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法ssuser370dd7
 

Último (12)

TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf
 
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor
 
2024 03 CTEA
2024 03 CTEA2024 03 CTEA
2024 03 CTEA
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
 
What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
 
2024 04 minnanoito
2024 04 minnanoito2024 04 minnanoito
2024 04 minnanoito
 

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についても研究開発中です)