[Starter Kit No.2] Exposing general-purpose Web scraping tool with text analysis function (automatic tagging / visualization)
Tags: python, scrapy, gensim, scraping
Published: 2020-03-02 07:29:42

# Easy Customizable Scraper


## Concept

![screencapture-mockers-io-scanner-2020-02-29-15_20_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514619/c77b7b8f-2b77-d5ad-e2e1-a50af08f294b.png)

General-purpose Web scraping tool with text analysis function.

The following features help users start development.

- Easy settings
- Customizability
- Text analysis function (tagging / visualization)

Click here for source code
https://github.com/makotunes/easy-customizable-scraper


## Application example

- Collection of curated media articles and automatic tagging
- Recommendation engine

This algorithm is used for the functions of my personally developed products.
https://mockers.io/scanner

## Elemental technology

- Web scraping
- Automatic language detection
- Morphological analysis
- Feature tagging algorithm (original)
- 2D map visualization technology (original)



## Dependencies

- Docker

## Installation

It takes about 1-2 hours.

```Shell
docker build -t scanner .
```

or

```Shell
./build.sh
```

## Run

```Shell
docker run --rm -it -v "$PWD":/usr/src/app \
--name scanner --force scanner  \
-e 'ENTRY_URL=http://recipe.hacarus.com/' \
-e 'ALLOW_RULE=/recipe/' \
-e 'IMAGE_XPATH=//*[@id="root"]/div/div/section/div/div/div[1]/figure/img' \
-e 'DOCUMENT_XPATH=//td/text()|//p/text()' \
-e 'PAGE_LIMIT=2000' \
-e 'EXCLUDE_REG=\d(年|月|日|時|分|秒|ｇ|\u4eba|\u672c|cm|ml|g|\u5206\u679a\u5ea6)|hacarusinc|allrightsreserved' \
scanner:latest /usr/src/app/entrypoint.sh
```

or 

```Shell
./run.sh
```

## Parametes

Set Environment Variable of Docker Container.

If you have at least ENTRY_URL, it will automatically scan the page and pull out the text.
If no options are specified, it is optimized for curated media and can be fully automated, such as extracting the text of articles.

| Environment Variable | Description                                                                                  |
|----------------------|----------------------------------------------------------------------------------------------|
| ENTRY_URL            | (Required) Site top URL to start scanning. All the pages are automatically scanned.          |
| ALLOW_RULE           | Allow filter rule of target urls.                                                            |
| DENY_RULE            | Deny filter rule of target precedence overurls.                                              |
| IMAGE_XPATH          | Specify the image you want to get on the page with XPATH.                                    |
| DOCUMENT_XPATH       | XPATH of the top node in the page where text is to be extracted.                             |
| PAGE_LIMIT           | Scaned limittation of number of pages. -1 means unlimited number.                            |
| EXCLUDE_REG          | Regular expression of word rule not extracted by morphological analysis.                     |


## Result

result/res.json

## Project structure

| File                 | Description                                            |
|----------------------|--------------------------------------------------------|
| src/scraper.py       | Main scrapying logic                                   |
| src/categorizer.py   | Main algorithm to tag and visualize passages.          |
| src/tokenizer.py     | Main algorithm to do morphological analysis            |

## Customize

#### custom/_formatter.py

Edit XPATH for required HTML nodes like below.

```Python
def formatter(sel):
    res = {}

    n_howtomake = int(len(sel.xpath('//*[@id="root"]/div/div/section/div/div/div[2]/div[1]/table[2]/tbody/tr/td/text()').extract()) / 2)
    res["n_howtomake"] = n_howtomake

    return res
```


#### custom/_finalizer.py

Edit post-process to generate your expected output like below.


```Python
import pandas as pd

def finalizer(res):
    pages = res["scatter"]
    pages = list(map(lambda x: x["user_meta"], pages))
    df = pd.DataFrame(pages)

    corr_df = df.loc[:, ["time", "n_howtomake", "n_components"]].corr()

    res["analyzed"] = {}
    res["analyzed"]["correlation"] = {}
    res["analyzed"]["correlation"]["time-n_howtomake"] = corr_df.loc["time", "n_howtomake"]

    return res
```

## Example

Here is an example of using this tool for scraping and analysis.

Let's analyze [free cooking recipe site] (http://recipe.hacarus.com/).
** If you can't access it, try opening it in secret mode. **

All these results are stored in the "result" directory.

### Visualize distribution of cooking time, number of ingredients, number of recipes

```Python
import matplotlib.pyplot as plt
import pandas as pd

def finalizer(res):

    pages = res["scatter"]
    pages = list(map(lambda x: x["user_meta"], pages))
    df = pd.DataFrame(pages)

    fig = plt.figure()
    x = df["time"]
    y = df["n_howtomake"]
    plt.scatter(x, y)
    plt.savefig('./result/time-n_howtomake.png')

    fig = plt.figure()
    x = df["time"]
    y = df["n_components"]
    plt.scatter(x, y)
    plt.savefig('./result/time-n_components.png')

    fig = plt.figure()
    x = df["n_howtomake"]
    y = df["n_components"]
    plt.scatter(x, y)
    plt.savefig('./result/n_howtomake-n_components.png')
    
    return res
```

#### Result

##### Cooking time: how to make

![time-n_howtomake.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514619/5a4c2010-a296-d344-1217-dd4778c5d162.png)

##### Cooking time: number of ingredients

![time-n_components.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514619/84e37f59-20fc-a40f-bb54-680509bd1701.png)

##### How to make: Number of ingredients

![n_howtomake-n_components.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514619/4fb6f67b-adbf-2c9c-52c0-f0580999a28f.png)


### Examine the correlation between cooking time, number of ingredients, and number of recipes

```Python
import matplotlib.pyplot as plt
import pandas as pd

def finalizer(res):
    pages = res["scatter"]
    pages = list(map(lambda x: x["user_meta"], pages))
    df = pd.DataFrame(pages)

    corr_df = df.loc[:, ["time", "n_howtomake", "n_components"]].corr()

    res["analyzed"] = {}
    res["analyzed"]["correlation"] = {}
    res["analyzed"]["correlation"]["time-n_howtomake"] = corr_df.loc["time", "n_howtomake"]
    res["analyzed"]["correlation"]["time-n_components"] = corr_df.loc["time", "n_components"]
    res["analyzed"]["correlation"]["n_howtomake-n_components"] = corr_df.loc["n_howtomake", "n_components"]

    fig = plt.figure()
    
    return res
```

#### Result

##### Cooking time: how to make

`0.30457219729662316`

##### Cooking time: number of ingredients

`0.3949520467754227`

##### How to make: Number of ingredients

`0.6869899620517819`

### Select about three keywords that can be used to characterize each Leshig

result/tagged.csv

|title                           |tag1  |tag2     |tag3    |
|--------------------------------|------|---------|--------|
|なすとトマトの中華和え(１５分)                |なす    |トマト      |大葉      |
|ぶりの照り焼き(45分)                    |両面    |照り焼き     |水気      |
|おでん風煮(2時間)                      |大根    |こんにゃく    |竹輪      |
|大根とツナのサラダ(15分)                  |ツナ    |大根       |わかめ     |
|鶏の照り焼き丼(20分)                    |片栗粉   |にんにく     |れんこん    |
|筑前煮(６０分)                        |れんこん  |ごぼう      |こんにゃく   |
|白菜とわかめの酢の物(15分)                 |白菜    |わかめ      |しめじ     |
|鮭のホイル焼き(25分)                    |玉ねぎ   |しめじ      |ピーマン    |
|キャベツとハムの粒マスタード和え(１５分)           |キャベツ  |しめじ      |ハム      |
|えのきとワカメの和え物(15分)                |えのき   |わかめ      |きゅうり    |
|里芋のおやき(３０分)                     |里芋    |片栗粉      |桜えび     |
|鶏肉と里芋の煮物(60分)                   |里芋    |鶏肉       |相性      |
|焼き万願寺唐辛子(10分)                   |万願寺唐辛子|かつお節     |作り方     |
|肉じゃが(45分)                       |玉ねぎ   |牛肉       |じゃがいも   |
|鰆の幽庵焼き(１５分(漬け込む時間は省く))          |冷蔵庫   |鰆        |ゆず      |
|オクラの煮びたし(１０分(冷やす時間は除く))         |オクラ   |しょうが     |オクラ     |
|春菊と油揚げの煮びたし(15分)                |春菊    |油揚げ      |春菊      |
|しいたけのツナマヨ焼き(１０分)                |マヨネーズ |塩コショウ    |しいたけ    |
|コールスロー(15分)                     |キャベツ  |マヨネーズ    |きゅうり    |
|じゃがいもとタコのガーリック炒め(２０分)           |にんにく  |じゃがいも    |タコ      |
|棒棒鶏(３０分)                        |しょうが  |トマト      |きゅうり    |
|アボカドのチーズ焼き(15分)                 |アボカド  |ハム       |チーズ     |
|キャベツと大葉のさっぱり和え(１０分)             |大葉    |キャベツ     |大葉      |
|カニカマサラダ(10分)                    |レタス   |きゅうり     |サラダ     |
|ズッキーニともやしのナムル(１５分)              |ズッキーニ |もやし      |粗熱      |
|春雨サラダ(１５分)                      |春雨    |きゅうり     |ハム      |
|白菜と油揚げのみぞれ煮(３０分)                |大根    |白菜       |油揚げ     |
|牛肉とれんこんの甘辛炒め(30分)               |れんこん  |にんにく     |牛肉      |
|豚丼(30分)                         |しょうが  |しめじ      |レタス     |
|紅白なます(30分)                      |ゆず皮   |大根       |部分      |
|里芋のガーリック焼き(３０分)                 |里芋    |にんにく     |香り      |
|ブロッコリーのごまみそ和え(10分)              |ブロッコリー|和風       |みそ      |
|ブロッコリーのゴマ和え(１５分)                |ブロッコリー|出汁醤油     |粗熱      |
|かぶの甘酢漬け(１時間)                    |ゆず    |甘酢       |昆布      |
|さんまのしょうが煮(３０分)                  |さんま   |しょうが     |圧力      |
|スパゲティーサラダ(２０分)                  |大根    |きゅうり     |スパゲッティ  |
|切り干し大根の煮物(２５分)                  |切り干し大根|油揚げ      |短冊      |
|なすとオクラの和え物(１０分)                 |なす    |オクラ      |出汁醤油    |
|なすと厚揚げのおろしあん(30分)               |厚揚げ   |なす       |片栗粉     |
|ごぼうのごまマヨサラダ(15分)                |ごぼう   |好み       |一味      |
|水菜と長いものわさび和え(１５分)               |水菜    |長いも      |わさび     |
|ピーマンのじゃこ炒め(１５分)                 |ピーマン  |雑魚       |顆粒和風だし  |
|なすと豚肉のごまみそ丼(20分)                |なす    |丼        |ピーマン    |
|ピリ辛豆腐ステーキ(30分)                  |豆腐    |しょうが     |白ネギ     |
|白菜とハムの青じそサラダ(20分)               |白菜    |大葉       |ハム      |
|鮭のシャリアピンソースがけ(30分)              |鮭     |にんにく     |ソース     |
|白菜のさっぱりサラダ(15分)                 |白菜    |きゅうり     |サラダ     |
|かぶと肉団子の煮物(30分)                  |しょうが  |鶏ミンチ     |片栗粉     |
|ごぼうの梅おかか煮(４５分)                  |ごぼう   |かつお節     |圧力鍋     |
|切り干し大根とほうれん草の和え物(20分(水に戻す時間は除く))|ほうれん草 |切り干し大根   |熱湯      |
|かぼちゃと揚げの煮物(20分)                 |かぼちゃ  |油揚げ      |揚げ      |
|さつまいものレモン煮(30分)                 |さつまいも |レモン汁     |レモン     |
|菜の花の辛子和え(15分)                   |菜の花   |練りからし    |長さ      |
|かぼちゃとこんにゃくの煮物(30分)              |こんにゃく |かぼちゃ     |熱湯      |
|ゆず入り湯豆腐(１時間)                    |豆腐    |春菊       |好み      |
|大根と厚揚げの煮物(６０分)                  |厚揚げ   |大根       |彩り      |
|小松菜ぎょうざ(45分)                    |小松菜   |にんにく     |しょうが    |
|水菜と油揚げの煮びたし(15分)                |油揚げ   |水菜       |食感      |
|ふろふき大根(３０分以上)                   |大根    |味噌       |いりごま    |
|春菊の白和え(１５分)                     |春菊    |豆腐       |白和え     |
|なすのホイル焼き(15分)                   |なす    |生姜       |ホイル     |
|えびとニラの中華風卵炒め(30分)               |玉ねぎ   |ニラ       |えび      |
|ししゃもの南蛮漬け(３０分)                  |ししゃも  |南蛮漬け     |ピーマン    |
|八宝菜(３０分)                        |豚肉    |白菜       |玉ねぎ     |
|ブロッコリーのわさマヨ和え(１５分)              |ブロッコリー|食感       |わさび     |
|鶏のすき煮(30分)                      |鶏肉    |鶏もも肉     |しいたけ    |
|里芋の梅おかか和え(35分)                  |里芋    |梅干し      |かつお節    |
|ブロッコリーの磯和え(15分)                 |ブロッコリー|出汁醤油     |焼き海苔    |
|焼き鳥丼(20分)                       |鶏肉    |鶏もも肉     |白ネギ     |
|ほうれん草のお浸し(10分)                  |かつお節  |ほうれん草    |10分     |
|さんまの梅しそロール(45分)                 |片栗粉   |さんま      |大葉      |
|きゅうりとトマトの土佐酢和え(３０分)             |トマト   |きゅうり     |かつお節    |
|さばの味噌煮(30分)                     |さば    |味噌       |しょうが    |
|エリンギのバター炒め(15分)                 |エリンギ  |バター      |エリンギ    |
|さつまいもとクリームチーズのサラダ(２0分)          |さつまいも |マヨネーズ    |塩コショウ   |
|薄揚げの納豆キムチ詰め(15分)                |キムチ   |納豆       |長ネギ     |
|鮭の味噌ヨーグルト漬け(１５分(漬け込む時間は除く))     |味噌    |鮭        |ヨーグルト   |
|五目豆(４５分)                        |ごぼう   |れんこん     |こんにゃく   |
|新生姜と水菜の肉巻き(３０分)                 |新生姜   |水菜       |肉       |
|小松菜とツナの和え物(１５分)                 |小松菜   |ツナ       |水気      |
|手羽中と大根の煮物(４５分)                  |大根    |手羽中      |弱火      |
|手羽先の照り焼き(60分)                   |表面    |手羽先      |にんにく    |
|ほうれん草の梅和え(15分)                  |ほうれん草 |梅        |梅干し     |
|なめこおろし(１５分)                     |なめこ   |大葉       |かつお節    |
|簡単タンドリーチキン(１時間以上)               |1時間   |塩コショウ    |タンドリーチキン|
|あさりの酒蒸し(15分)                    |あさり   |にんにく     |みじん切り   |
|ピーマンの肉詰め(３０分)                   |玉ねぎ   |ピーマン     |肉       |
|ちくわの磯辺揚げ(15分)                   |竹輪    |青のり      |衣       |
|長いもの梅和え(10分)                    |長いも   |かつお節     |梅干し     |
|水菜とアボカドのサラダ(１５分)                |アボカド  |水菜       |豆腐      |
|酢鶏(20分)                         |鶏肉    |鶏がらスープの素 |一口      |
|鯛の西京焼き(１５分(漬け込む時間は除く))          |鯛     |冷蔵庫      |魚       |
|きゅうりの塩昆布和え(10分)                 |きゅうり  |塩昆布      |乱切り     |
|なすの煮びたし(20分)                    |なす    |しょうが     |作り方     |
|ごぼうと人参の肉巻き(30分)                 |ごぼう   |肉        |にんにく    |
|大根・里芋・イカの煮物(40分)                |イカ    |大根       |里芋      |
|回鍋肉(30分)                        |豚肉    |にんにく     |片栗粉     |
|ほうれん草と干しえびのゴマ和え(１５分)            |ほうれん草 |干しエビ     |干しえび    |
|里芋のそぼろ煮(３０分)                    |里芋    |片栗粉      |鶏ミンチ    |
|三度豆と人参のおかか和え(１０分)               |三度豆   |湯        |出汁醤油    |
|中華丼(30分)                        |チンゲン菜 |しめじ      |豚肉      |
|きゅうりとたこの酢の物(20分)                |きゅうり  |たこ       |わかめ     |
|新玉ねぎのコンソメ煮込み(45分)               |片栗粉   |鶏ミンチ     |新玉ねぎ    |
|れんこんのきんぴら(１５分)                  |れんこん  |いりごま     |中火      |
|野菜たっぷり牛丼(20分)                   |玉ねぎ   |ニラ       |しめじ     |
|ホタテとチンゲン菜のクリーム煮(２０分)            |片栗粉   |にんにく     |チンゲン菜   |
|ほうれん草とごぼうの白和え(60分)              |ごぼう   |豆腐       |ほうれん草   |
|さんまの蒲焼き(３０分)                    |さんま   |ごま       |大葉      |
|ひじきの炒め煮(６０分)                    |ひじき   |油揚げ      |大豆      |
|オクラの納豆和え(１０分)                   |かつお節  |オクラ      |納豆      |
|じゃこのサラダ(１０分)                    |縮緬雑魚  |貝割れ大根    |水菜      |
|里芋のホットサラダ(45分)                  |里芋    |ほうれん草    |ベーコン    |
|かぼちゃのサラダ(１５分)                   |かぼちゃ  |ヨーグルト    |きゅうり    |
|豆腐のきのこあんかけ(１０分)                 |豆腐    |しめじ      |えのき     |
|春巻き(60分)                        |しょうが  |春雨       |ニラ      |
|れんこんのはさみ焼き(３０分)                 |れんこん  |しょうが     |鶏ミンチ    |
|高野豆腐の含め煮(30分)                   |高野豆腐  |竹串       |水気      |
|豚ミンチと白菜の炒め物(15分)                |春雨    |白菜       |にんにく    |
|いわしのさっぱり煮(４５分)                  |いわし   |しょうが     |長ネギ     |
|れんこんのカレー炒め(１５分)                 |れんこん  |OLIVE OIL|カレー粉    |
|ささみの中華風サラダ(25分)                 |ささみ   |もやし      |きゅうり    |
|茄子と豚肉のピリ辛味噌炒め(30分)              |豚肉    |茄子       |豆板醤     |
|ささみのから揚げ(30分)                   |ささみ   |にんにく     |しょうが    |


## Call for ideas

What do you want to do with this tool?
If there is a need, it may be addressed in a future update.
We look forward to your comments.