業務改善のためにPHPでWEBスクレイピングをやってみた

# はじめに
現在[あなたのマイスター](https://yourmystar.jp/)では一部サイトデザインリニューアルを行なっています。
8月頃までスマホページのリニューアルを行ない、現在はPCページの一部リニューアルを行なっています。今回WEBスクレイピングを行い、**文言チェックツールを作成し業務改善**を行いました。その時学んだことをメモとして残したいと思います。

## 背景
現在、リニューアルしているのは注文できるサービスのカテゴリーについてのページを行なっています。ただ、全部で70~80カテゴリー以上あり、デザインを統一したHTMLの雛形に、既存のページの文言を挿入するということを行なっています。
ただ、人間にはやはりミスがあるので、ソースコードレビューをする際に不備が見つかり、修正依頼をもらうことが起きています。そこで、主に起こったのは以下の通りです。

1. 実装者自身が文言のミスに気づかない
2. レビュワーがソースコードではなく、文言に重点を置いてレビューをしなければならない

ということが発生しました。

### 実装者自身が文言のミスに気づかない
これに関しては誤字や脱字、文言のコピペミス等様々な要因がありますが、実装段階では気づかないミスが多発しました。多いカテゴリーだと、日本語の文字だけで1000文字近くありその全てに目を通したつもりであっても、チェックが甘くなってしまいました。また、文言が似たような文言が多いというのがミスを誘発する原因になりました。
`PHPを私は学んでいます。`
`私はPHPを学んでいました。`
実際の文言も同じように、似ているんだけど微妙に違う文言が多数あるとミスが多発します。

### レビュワーがソースコードではなく、文言に重点を置いてレビューをしなければならない
先述した通り、HTMLの雛形に文言をはめ込んでいったものをレビューする際に、重点的に日本語をミスがないかくまなくチェックする必要があるため、レビューに多くの時間を割く必要がありました。その結果として、他のタスクを一旦ストップしてレビューに集中していかなければならないということが起きました。

## 今回やること
[[phpQuery] を使ってwebサイトをスクレイピングする](https://qiita.com/nadonado/items/0ac037d90c5248b7eac3)
という記事を発見したので、スクレイピングでこの課題を解決しようと考えました。

### 具体的な施策
1. すでにリリース済みのスマートフォンサイトのソースコードから文言をスクレイピングを使用し、抽出する
2. 今回リニューアルため実装中のPCサイトのソースコードから文言をスクレイピングを抽出する
3. 1と2で抽出した文言を比較し、文言が正しいかを比較する

スマートフォンページリニューアルのタイミングで、サイト内の文言を正しいものに修正しているため、今回のPCサイトリニューアルも**基本的にスマートフォンサイトの文言に統一する**という要件がありました。

### PHPでスクレイピングを行う理由
現在、`Vagrant + VirtualBox` で開発環境を構築し、フレームワークとして、 **CakePHP3** を使用しています。今回作成した文言チェックツールはあくまで、個人のマシンの開発環境内で使用するため、すでにPHPでの環境を構築しているためPHPで行おうと考えました。
また、今回はスピード重視のため、自分自身にとってすでにある程度学習したPHPで作成して見ようと考えました。
実行に当たって、MAMPやXAMPPでの環境でも実行可能です。

## 実際にやってみる
まずはじめに、`phpQuery`をダウンロードする。
phpQuery
https://code.google.com/archive/p/phpquery/downloads

今回は

```
wordCheck
- index_pc.html
- index_sp.html
- word_check.php
- phpQuery-onefile.php
```

のように`wordCheck`ディレクトリ内に比較するPC用のソースコードとスマートフォン用のソースコードを先ほどダウンロードした`phpQuery`のファイルと同じ階層に配置します。また、文言をチェックするコードも配置します。

今回比較するPCとスマートフォンのコードは以下の通り

```html:index_pc.html
<html>
    <head>
        <title>word_check</title>
    </head>
    <body>
        <h1>hoge</h1>
        <div>
            <p class="category-name">カテゴリー名</p>
            <p class="category-description">カテゴリーに関する説明文</p>
        </div>
    </body>
</html>
```

```html:index_sp.html
<html>
    <head>
        <title>word_check</title>
    </head>
    <body>
        <h1>hoge</h1>
        <div>
            <p class="category-name">カテゴリー名</p>
            <p class="category-description">カテゴリに関する説明文</p>
        </div>
    </body>
</html>
```

続いて、実際にスクレイピングを行い文言をチェックするコードは以下の通りです。

```php:word_check.php
<?php
    // 必要なライブラリを読み込む
    require_once("./phpQuery-onefile.php");

    $fileNamePC = "user/wordCheck/index_pc.html";
    $fileNameSP = "user/wordCheck/index_sp.html";

    // PCSPのファイルを読み込む
    $htmlPC = file_get_contents($fileNamePC);
    $htmlSP = file_get_contents($fileNameSP);

    $contentsPC = phpQuery::newDocument($htmlPC)->find(".category-description")->text();
    $contentsSP = phpQuery::newDocument($htmlSP)->find(".category-description")->text();

    if (strcmp($contentsPC, $contentsSP) == 0) {
      echo "チェックOKです\n\n";
    } else {
      echo "文言が違っている可能性があります。お手数ですが確認お願いします。「.category-description」です\n\n";
    }

?>
```

ファイルの作成が終わったら、ターミナルの`wordCheck`ディレクトリで実行します。

```
$ php word_check.php
```

今回で言えば比較対象はPCでは`カテゴリーに関する説明文`となり、スマートフォンサイトでは`カテゴリに関する説明文`となってしまっているため、文言が間違っています。実際にはもう少し階層構造が複雑ですが、class名や階層構造さえわかれば、任意の位置から文言を抜き出すことが可能です。

## やってみての感想
スクレイピングということに対して難しいと勝手に思っていましたが、今回実際にやってみて思っていたよりは取り掛かりやすい印象でした。工夫次第で、取れない情報は無いと感じました。
また、業務改善という面では、特に実装者の文言ミスが減りソースコードレビューの指摘回数を減らすことに成功しました。
何か不備があれば指摘していただけると幸いです。