---
# System prepended metadata

title: biz clawler - ワークフロー説明書
tags: [こまーず]

---

# 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
- 将来的な拡張性として、後処理方法追加する