# biz clawler - ワークフロー説明書 ###### tags: `こまーず` ## 前提 以下のような一覧ページと詳細ページで構成されるWebページを例に、 ワークフロー定義の方法を説明する。 ![](https://i.imgur.com/Ks0WL6u.png) ※ 詳細ページ(右) ## ワークフロー定義の詳細 ワークフロー定義のため、以下2種類のjsonファイルを作成する。 |jsonファイル名|説明|備考| |-|-|-| |base.json|起点URLやクローリング間隔などを指定|1ワークフローにつき1ファイル| |parse.json|起点URLからの巡回・抽出アクションを定義|1ワークフローにつきnファイル(上記例だと2ファイルで記述可能)| ### 参考:本ページにて定義するワークフローの動作イメージ ![](https://i.imgur.com/xtVQUux.png) ### base.json 起点URLとクエリパラメタ、クローリング時のコンフィグを設定する。 以下の例では、`1日間隔`で次の2ページを起点として巡回する。 - `http://hoge.com/?q="ラーメン 東京"` - `http://hoge.com/?q="ラーメン 千葉"` ```json= { # オリジナル起点URL "base_url":"http://hoge.com/", # クエリ "query":{ "q":[ "ラーメン 東京", "ラーメン 千葉" ] } # クローリング間隔(以下は1日毎にクロールする) "interval":{ "day": "1", } } ``` ### parse.json クローリングおよびスクレイピング方法を記述する。 #### 前提:jsonの構成 `parse.json`には、 keyは任意の名前、valueは以下の要素を持つdictを指定する。 |key|valueの型|説明|デフォルト値|必須| |-|-|-|-|-| |selector|str|cssセレクタ|None|○| |type|str|ノードの処理方法を定義する。詳細は以下。|None|○| |attribute|str|`type`が`attribute`ならば指定<br>どの属性を抽出するかを指定。|None|☓| |multiple|boolean|`true時`: 複数ノードから情報を抽出する。|false|☓| #### typeで指定できる値 |値|対応する処理| |-|-| |link|ノードから"href"の属性値(=URL)を抽出する。<br>抽出したURLは、親dictデータのkeyと対応する`parse.json`に渡される。| |text|ノードから`<tag>`の内側のデータを抽出する。| |attribute|ノードから属性値を抽出する。(属性名は親dictの`attribute`で指定する。)| <補足> `type`として、`text`か`attribute`を指定すると、 抽出した結果をスクレイピング結果として出力する。 `link`の場合、スクレイピング結果として出力はせず、クローリング処理においてのみ利用する。 ### ユースケース:一覧ページに対する`parse.json` ```json= # main.json { # selectorを用いてURLを取得。 # URLは`shousai_page.xml`で処理する。 "shousai_page":{ "selector":"BODY > ... > a.contents", "type":"link", "multiple": "true" }, # `$next_page`のみ、再帰的に処理を行う。 # (selectorにより得られたURLは、同jsonファイルで処理される)。 "$next_page":{ "selector":"BODY > ... > a.next", "type":"link", }, } ``` ### ユースケース:詳細ページに対する`parse.json` ```json= # shousai_page.json { # 以下、全てデータ抽出処理 "shop":{ "selector":"BODY > ... > div.shop", "type":"text", }, "grade":{ "selector":"BODY > ... > div.grade", "type":"text", }, "desc":{ "selector":"BODY > ... > div.desc", "type":"text", }, "link":{ "selector":"BODY > ... > a.link", "type":"attribute", "attribute":"href", }, # 以下は残課題 "comment":{ "body": { "selector":"BODY > ... > p.comment-body", "type":"attribute", "attribute":"text", }, "author": { "selector":"BODY > ... > p.comment-author", "type":"attribute", "attribute":"text", }, "multiple": "true" } ``` #### 補足:ScrapyのItem生成について `type`の値が`attribute`か`text`のdictデータを用いることで、 Item(=テーブル)を生成する。 (1つの`parse.json`ファイルから、原則1つのItemを生成する) 例えば、上記`shousai_page.json`からは`shop`, `grade`, `desc`, `link`の要素を持つItemが生成される。 上記`main.json`では、全てのdictデータの`type`が`attribute`のため `main.json`からはItemが生成されない。 ## 参考 - https://selectorlib.com/scrapy.html ## 1205 - 将来的な拡張性として、後処理方法追加する