Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Webスクレイピング用の言語っぽいものを作ったよ

15,761 views

Published on

Webスクレイピング用の言語っぽいものを作ったよ。
その仕様と解説。

Published in: Technology
  • Login to see the comments

Webスクレイピング用の言語っぽいものを作ったよ

  1. 1. Rawlerフレームワーク XAMLで自己完結するwebスクレイピングフレームワーク 伊藤貴一(@kiichi54321)
  2. 2. Webスクレイピングとプログラミング技術  Webにはテキストマイニングの対象になる、大量の情報があ る。  Webは人々の書き込みで満ち溢れている。  しかし、そのデータを取ってくるためには、プログラミングの習 得が必要。  いまどきのどの言語もWebスクレイピングできるライブラリーはある。  しかし、プログラミング内で使うため、言語の習得とライブラリーの 習得をしないといけない。  プログラムはいろいろなことができるけど、できすぎて大変。  通信から文字列処理、入出力関係までやらないといけないから躓く。  いきなりの素人には敷居が高い。  素人が、データを取りたいと思った時取れない。  できたらすごいよなぁと、ぼんやり考えて過ごすことになる。(アカン)
  3. 3. Webスクレイピングのプログラマー側の事情  Webスクレイピングは、同じことの繰り返しで楽しくない。  結局はパラメータの調整だけなので。  どこの部分を取ってきて・・・の繰り返しなので。  その割には、いろいろ書かないといけない。  変数の宣言、データの一時格納、関数の作成、ループ処理、後処理、 データの入出力関係などなど。  対象のサイトに合わせて作るので、毎回違うものになる。  共通部分はそのまま使いまわしたい。  コピペプログラムサイコー  でも、コピペはバグの発生もとでよくない。危険!  デザインの変更で取得不能になったりする。  そのため、外部化できれるとうれしい。  後に保守しやすいように、見通しの良いものがいい。
  4. 4. データフロープログラミング  データの流れを記述することでプログラミングをする手法  データ中心にプログラミング  関数の合成によってプログラミング  UNIXのパイプもその一種。  メソッドチェーンもある意味そう。ちょくちょく使われてはいる。  関数型言語の一種。  LISP,Haskellなどの系統。C,Javaなど多くは手続き型。  記述が美しい、と言われながら、マイナーだったが、大規模並列処理関 係で注目を集め始めている。  ビジュアルプログラミングとの相性がいい。  データの流れを機能間の有向グラフで表現すればいいから  テキストを中心としたデータフロープログラミング言語を作れば、 webスクレイピングを簡単にできる!  関数の記述とパラメータの設定だけでいいから、使いまわしやりやすい。  ドメイン特定型言語(DSL)
  5. 5. Rawlerフレームワーク  オープンソースで公開  https://github.com/kiichi54321/Rawler  C#で作成  XAMLで記述するフレームワーク。  XMLのMS拡張。オブジェクトがXMLのタグになる。  手順の木構造を作るだけのプログラミング。  木構造なので、一つのテキストに対して複数の処理ができる。  子は親のテキストを使用してテキストを生成することの連鎖。  再利用性を高める  変数、ループ記述を追い出している。関数型言語っぽいつくり。  これだけで自己完結することを目指す。  XAMLの記述だけでwebスクレイピングが完結する。  通信、テキスト処理、繰り返し処理、データの構造化、ファイルの入出力、エ ラー処理ができる。  プログラミング(C#)との連携もできる。  コードビハインドが使え、イベント処理の追加ができる。  DBとの連携はこれを使うことで可能。
  6. 6. XAML (Extensible Application Markup Language)  XAMLとは、MSの開発した、多数のオブジェクトの状態と関係をテキスト で記述するためのXMLみたいなもの。  主に、UIのデザインで使われる。(WPF, Silverlightなど)  複数のオブジェクトの記述をコピペできるのが強み。  親子関係の入れ替えとか、コードとして書くとすごく面倒。それがコピペで済むなんて!  C#4.0からSystem.XAML空間が追加され、UIだけのものでもなくなった。 (はず)  そんなに使われていない?オブジェクトの状態保存には便利。  開発動機的にはこれが大きい。  Webスクレイピングは動作の組み合わせなので、XAMLとの相性はいい。  Visual Studioは優秀なXAML編集ソフトである。インテリセンスも使える。  そのため、 このフレームワークには、Visual Studioが必要。優秀なXAML編集 コントロールがあれば、不要になるのだけど…  また、 Visual Studioでは、単純なXAMLだけではなく、コードビハインドとして コードも書けるので拡張性がよすぎる。  コピペ以上の優秀なUIを用意することが難しいので、XAMLの記述で満 足しちゃった。
  7. 7. XAMLの具体例 木構造XAML 上の等価なコード •XAMLの記述は木構造を作る。 •XAMLはタグがクラス名なので、コー ド的には、クラスをNewして、インスタ ンスを作り、それから木構造を作ること と同じことである。 •子要素がChildrenの要素になる ことは別のところで指定してある。 •XAMLは木構造とインスタンスのパラ メータを見やすくしている。 •木構造の入れ替え、追加は、コピペで すむ。実際のコードでは書き変え箇所 が多くて面倒な作業である。 XAMLはオブジェクトと 対応している。
  8. 8. Rawlerはほんとに関数型言語?  おそらくは、関数型言語っぽいにとどまる。  理由  メソッドチェーン的な世界は表現できているので、関数型言語っぽ いとはいえる。  とはいえ、副作用がなんだかんだいろいろある。  関数自体に状態を持つものがある。(DataやPageなど)  Tree構造の、親子関係、祖先関係を利用しているので、どこで切り 取っても同じ挙動ができるとは限らない。  Dataを格納するために、子孫のDataWriteからDataの呼び出し。  再帰的にページ取得を行うためのNextPage(祖先のPageにURLを投 げる)  Tree構造の親子、祖先関係を利用するのは、手続き言語的発想w  記述の簡単さ故に作ったGlobalVar。  Tree構造無しで、一時変数や、固定変数などを扱えて便利。  でも実装は静的変数の読み書きなので、staticおじさんである。(並列化 危険)
  9. 9. 導入方法
  10. 10. RawlerTreeの作成と実行環境  XAMLのコードの作成は、 VisualStudioを使うのが望ま しい。  DLLを読み込み、その情報から入力補助をしてくれるので。  XAMLは型制約が強いので、入力補助が効果的で、それと比 べるとただのエディタでは作りにくい。  実行環境は、RawlerToolを使う。(下の図)  http://goo.gl/Mm58cY  コードをコピペして使用。  実行、キャンセル、一時停止  Dataクラスの中身表示  下のテキストボックスに レポート・エラーを表示 RawlerTool の画面
  11. 11. 導入方法1  VisualStudioをインストール  MSのアカウントを作る。スカイプIDと一緒。  Visual Studio Online Basic(無償)から、 Visual Studio Express for Desktopを選択、ダウンロード&インストール  WPFアプリケーションを作成  VisualStudio起動後、メニューの「ファイル」→「新規作成」→ 「プロジェクト」から、WPFアプリケーションを選択し、名前とか 適当につけ、作成する。  NugetからRawlerを導入。  ソリューションエクスプローラーから、プロジェクトを選択後、右 クリック。Nugetパッケージ管理を選択。  オンラインを選択し、検索窓から、「rawler」と打ち込む。  そして、「Rawler」を選択し、インストール。
  12. 12. 導入方法2  RawlerTree1.xamlを選択  選択すると右のようなものになる。  デザインビューは不要なので、ド ラッグでXAML部分のみを表示す るようにする。  水色のところをからプログラムを 記述していく。 ここを中心に編集していく
  13. 13. 具体的なRawlerTree
  14. 14. 具体的なRawlerTree  パターン 基本的に上から順番 に進む 複数の出力があるも のは、複数回実行さ れる。
  15. 15. 具体的なRawlerTree  ブログ記事のコメントを取ってくる例  コメント内容、書いた人のペアの情報のすべてがDataに蓄積 される。 PageでHTMLの取得、 Tagsで範囲の指定。 Comments-bpdyは複数ある ので複数取得 Comments-bpdy内から、コメ ント内容の取得。 DataWriteでDataに書き込み。 同様に、名前のところを取得 し、書き込み。 一つの組が終わる時、 NextDataRowで次の塊に移 行。 NextPageで次のページに移 動し、Pageが繰り返し。
  16. 16. 具体的なRawlerTree  TSVファイルからの読み込みとファイルへの書き込み機 能の追加。 前と同じ ファイル名、ブログ記事URL という列名をもつTsvファイル を作り、実行すると、ダイアロ グが開き、そのファイルを指 定すると、その内容に沿って 実行が行われる。 Pageで囲まれるところは前の スライドのものと同じである。 コピペした。 このような形で機能拡張が行 える。
  17. 17. 具体的なRawlerTree  Pageは親がURLならそのページを読み込む。  そのため、ページをたどっていくこともこんな感じで書ける。  一覧ページ、詳細ページの構成のサイトではこれが威力 を発揮する。
  18. 18. 具体的なRawlerTree  ログイン必要なPixivにログインして取得 ヒント:ブラウザゲームは、POSTを多用しています
  19. 19. Rawlerの基本設計 超プログラマより
  20. 20. 基底クラス(RawlerBase)の設計  XAMLで書けるようにするために一番根っこのクラス、 RawlerBaseクラスを設計した。  すべてはこれを継承している。  オブジェクト指向言語のポリモーフィズム(多態性)  木構造を表現するためにRawlerBase自身一つの親、多数の子を もつ(Parent,Children)  XAMLは木構造。  木構造にそって、親のTextを 参照して、自身のTextを作る  Run()から深さ優先で実行  前処理のPreTree  木構造が深くなると可読性が 落ちるので親テキストの前処理を RawlerBaseで記述する。  Run()とTextを継承時、 override 。 •RawlerBase •プロパティ •Parent( RawlerBase ) •Childern ( RawlerBase ) •Text(String) •PreTree ( RawlerBase ) •メソッド •Run
  21. 21. 繰り返し処理のRawlerMultiBase  例えばLinkの取得のように一つのテキストから複数の結 果を得られるものがある。これを扱えるようにしたい。  そのため、RawlerBaseを継承したRawlerMultiBaseを 作り複数処理の時はこれを継承する。  命名規則としては単複を意識させるため、複数形にして ある。 (Links、Tags、ReadLines)  クエリー機能(RawlerQuery)  集合に対しての処理をしたい。  重複削除、フィルタ処理、 n番目の取得などができる。  C#のLINQ相当  複数の組み合わせができる。 重複削除(Distinct)して ソート(Orderby)して 初めから20個取る(Take)
  22. 22. 複数の変数の指定  RawlerTreeの設計上、親の一つ のテキストしか入力に持てない。  これはこれで不便だ。複数の入力 をしたい。  XAMLのプロパティの中まで XAMLで記述できる機能を使う。  ルールは、対象のオブジェクトを 親としたRawlerTree  そのため、祖先をさかのぼって扱 える。  命名規則としては、Treeと名前の つくフィールドは、RawlerTreeで、 XAMLで記述できます。  通常のフィールドよりも、Treeが 存在したらそちらを優先します。 HTMLのTableタグのTHタグを動 的な変数として、DataWriteを使う 例。 DataWrite.AttributeTreeで変数を 指定する。 対象HTML
  23. 23. よく使う機能紹介
  24. 24. 目次  ページ取得  HTML解析  データ蓄積  テキスト処理  ファイル入出力  繰り返し処理  条件分岐  ユーティリティ  簡易自然言語処理  拡張  YahooAPIを使ってキーフ レーズ分析
  25. 25. ページ取得  Page  親テキストをURLとして、そのURLにアクセスし、HTMLを自身のTextにもつ  POSTもできるようになって無敵。  InputParameterTreeからAddInput系コマンドを配置。  一応、祖先のPageのURLをReferenceに加えるとかの処理もしている。  GetPageHtml (祖先のPageのHTMLを取得)  GetPageUrl (祖先のPageのURLを取得)  WebClient  Pageなどで、URLを読み込むとき使う。  WebClientを宣言しなくても動きます  クッキーなどを保持する。そのため、ログインするページには必須。  UserAgentの指定などができる。  NextPage  親テキストのURLとして、祖先のPageに次に読むページを加え、Page以下の Treeを再実行される。  作った人の良心として、デフォで3秒ほど停止します。(変更可)
  26. 26. HTML解析  Tags  指定したTagで囲まれたものを複数取得する。  ClassNameでクラスの指定、IdNameでIdの指定ができる。(完全マッチ)  ParameterFilter,ContextFilterで大雑把な絞り込みができる。(部分マッチ)  TagVisbleTypeで、子に渡すテキストをタグ全体、タグ内部、タグだけを指定で きる。  Links  リンクを複数取得する。  各種フィルタがある。  UrlFilter(URL) TagFilter(タグ) LabelFilter(中身) これらは部分マッチ  VisbleTypeで、子に渡すテキストを、URL,中身,全体かを指定できる。  XPath  xPathを使う。これも該当するのを複数取ってくる。  ClipText  StartとEndで挟んだ文字列を取ってくる。最終手段。  XAMLの性質上、特殊文字の扱いが面倒なので使いづらい。
  27. 27. データ蓄積  Data  データを蓄積する所。内部的に一つのデータの塊を表す、DataRowを持ってい る。  ファイル名を指定すると、完了時Saveが行われる。(蓄積型)  複数の配置をすると複数テーブルに対応する。  DataWrite  親のテキストを祖先のDataに属性付きで追加する。上書きではなく追加なので、 一つの属性に付き、複数のデータが入る。  AttributeTreeを使うと、動的な属性名をつけられる。表の一括取得に使う。  NextDataRow  これの実行時、次の塊に移る。これが発動時のイベントも拾えてそれを使うと DBとの連携ができる。  FileSave (名前変更あるかも・・・)  Dataを継承したクラス。結果をファイルに書き込む。(逐次型)  大量のデータの取得にはDataよりこちらを使う。  ファイルの指定がない時、ダイアログがひらく。
  28. 28. テキスト処理  ApendText  親テキストの前と後ろに文字列の追加。  Replace (置換処理)  TagClear(タグをすべて消す。)  Trim(前後の空白削除)  StringFormat  複数のテキストをテンプレートの中に落としこむ。超便利。  ReadLines  テキストを改行で分ける。  Split  テキストを指定の区切りで分ける。  RemoveWordByRegular  正規表現に基づいて文字列の取り除き
  29. 29. ファイル入出力  FileReadLines(ファイルから一行づつ読む)  ファイルの指定がない時、ダイアログが開く  TsvReadLines(Tsvファイルを読む)  子孫に GetTsvValue があると、その指定した列名の文字列 を取得する。(便利)  対象のTSVファイルは、UTF8エンコード。  ContainTextInFile(指定したファイルの中に親の文字列 が含まれているか?改行区切り)  すでに取得したデータのチェック用に。  これを使うと、続きから実行可能になる。  ContainTextInFileAddTextで、親のテキストを祖先の ContainTextInFileが指定したファイルに追加する。
  30. 30. 繰り返し処理  Iterator (繰り返し処理)  Textsに繰り返す内容の直書き  SourceTreeで柔軟な繰り返す内容を記述できる。  Range (数字の連続を作り出す。扱いは文字列)  URLのパラメータの生成や、繰り返し回数の指定に使う。  Loop(子のツリーを無限に繰り返す)  Bot用かなぁ・・・  ランダムにSleepしてくれるという無駄機能付き。  Break?なんですか?ソフトを落とせばいいんじゃないですか ねぇ・・。
  31. 31. 条件分岐  Contains  指定したのが含まれている)  Equal  指定したのと同じ  ChangeText  以前のテキストと違う  Switch  複数の条件分岐を行う。  これにより、構造化プログラミングの順列、繰り 返し、分岐のすべてを満たすことになる。  順列  ツリー構造での実行  繰り返し  RawlerMultiBaseを継承したクラス群  分岐  条件分岐機能群。 Switch構文例
  32. 32. 画像のダウンロード  ImageLinksとDownloadを組み合わせる。らくちん。  ImageLinks  Imgタグの取得。子には、URLを返す。  Download  親をURLとしてダウンロードして、ローカルに保存。  フォルダの変更やファイル名の変更などいろいろやれる。  拡張子の変更は行いません。(つまり気にしなくていい)
  33. 33. ユーティリティ  Sleep(一時停止)  過アクセスはやめましょう\(^o^)/  Report  親のTextを出力する。デバック、動作監視用。  SetWorkFolder  作業フォルダの指定。指定したところにファイルが作られます。  必ず指定しましょう。フルパスもできます。  KeyValueStore  変数を格納する場所。SetKeyValueで格納。GetKeyValueで呼び 出す。  SetGlobalVar、GetGlobalVar  KeyValueStoreなしで呼び出せるもの。Static変数なので、わりと危 険だが、楽ちんに変数を扱える。
  34. 34. 簡易自然言語処理  テキストを変数としてテキストを返すのがRawlerなので、自然言語処理も やれる。  名前空間はNPL  NPL:PreprocessingForJapanese  前処理。半角、全角を揃えるなどの文字種の統一をやってくれる。  NPL:TinySegmenter  辞書を使わないフリーの軽量形態素解析器。  Mecabの工藤さん作(元はJS)  NPL:GetWordsInSouce  ソースに指定した単語のみを返す。  抽出したいものが予めあるときに  顔文字の抽出などに。 「適当なテキスト」を前処理をして 形態素解析し、標準出力する例
  35. 35. 拡張:YahooAPIのキーフレーズ分析を使う  YahooAPIの使用登録をする。  http://developer.yahoo.co.jp/  Gitから、Rawlerのソースコードを落とす。  RawlerYahooAPIをプロジェクトに追加。コンパイルする。  下の感じでTreeを組み立てる。  KeyPhreseはJsonを複数返します。 追加 書き換える そのうちNuget化します
  36. 36. Rawlerの拡張性  C#のプロジェクト内で使うとコードビハインドが使えて、イベン ト処理の追加が行える。  DBとの連携処理がこれで行える。  クロール部分とDB処理がわかれるので可読性がいい。  RawlerBaseを継承すればこのフレームワークに乗っかる。  テキストを引数で、テキスト(単複)を返す関数であればいい。  WebAPIを使うもの作ると便利かも  Twitter、Facebook、googleなど  他の処理と組み合わせが可能となり、利便性が増す。  複数の検索語で検索したのをファイルに書き込むとか  テキスト分析と組み合わせる  形態素解析(実装済み)、テキスト分類、プラス表現マイナス表現・・  分析処理の可視化、データの前処理ツールになるかも。  このような拡張性があるためオープンソースで公開している。
  37. 37. Rawlerまとめ  XAMLで記述するwebスクレイピングフレームワーク作った。  変数、ループを排除して、やりたいことを中心とした見通しのいい記述  これだけで自己完結できる仕組みになっている。  VisualStudioからNugetを使うと簡単に導入できる。  すでに多数のサイトでデータ取得経験あり。  さくさくっと手早く作れます。30分程度。  対象のHTMLの分析のみに集中できる。  機能拡張も基底クラスを継承したものをつくればいいだけ  そのため、オープンソースにしている。  課題・問題点  ドキュメントが不足。ソースコードがドキュメント・・  人に作り方を教えるより、自分がやった方が圧倒的に速い。  ドメイン特定型言語のため、本当に教えていいものかとも思う。  XMLって結局冗長じゃね?  今のところWindows専用。  Mono(cross-platform用C#)でもたぶん動きそうだけど。やったことない。
  38. 38. FAQ  過去の記事を見つけてそれをコピペしたのですが、動きませ ん  名前を弄っています。そのため同じ機能でも動きません。  ドメイン特定言語に期待すんな。  ソースコードが一番のドキュメントだ(あかん)  このサイトでの取得の仕方がわかりません。  頭の体操でなんとかなるよ。(たぶん)  俺に聞け。(@kiichi54321)  挙動がよくわかりません。  ReportかViewTextを使い、表示させよう。  タグの入れ子関係が多くなると読みにくい  そうだね。PreTreeを使うとちょっとはましになる。  XAMLエディタの折りたたみ機能を使うとよい。
  39. 39. FAQ  クロールしていたら垢バンくらいました。  しりません。  遅いんじゃないですか?  対象のサーバが遅い場合もあるし、早過ぎると相手のサーバ から切られることがあるかものよ。  一応、NextPageに、Sleep時間がデフォで入っているから、そ れを小さくすれば、早くはなるよ。  Mac版はないのですか?  Monoで動くらしいよ?(未確認)
  40. 40. 今後の予定  簡単な自然言語処理関係の命令の追加  TFIDFくらい何とかならんかな。  TwitterAPIを使う命令群のNuget化  今まで使っていたライブラリが更新停止のようなので、使用ライブラ リを変更する予定。  データバインディング  できたら記述力が上がるけどどう実装したらいいかわからない。  並列実行  ぶっちゃけ複数クライアントを立ち上げればできるけどねぇ・・・。  もうちょっと、露出を増やしていきたい・・  いや、前書いたドキュメントが2年前でさ・・・・。

×