PythonでAmazonのレビューをサーチ

#PythonでAmazonのレビューをサーチ
##はじめに
　今回が初投稿になります．至らない部分も多いかと思いますがご容赦ください．優しくご指導いただけると幸いです．
　今回はPythonでWebスクレイピングを行う方法について紹介します．使用する環境はPython3.7　使用するライブラリはbs4, requests, pyperclip, textwrapです．bs4, requestsはAnacondaの標準ライブラリに入っていますが，pyperclipは標準では入っておらず，pipコマンドを用いてもインストールできなかったため，Pycharmの仮想環境を使いました．Pycharmはpipコマンドを使わずにライブラリをインストールできるので初心者におススメです．Pycharmではbs4とrequestsは標準ライブラリではないため，これらのライブラリもインストールする必要があります．

##Webスクレイピングの基礎
　requestsを用いてWebページをダウンロードします．requests.get(url)を用いて任意のwebページをダウンロードできます．
　今回は[こちら](https://www.amazon.co.jp/Python%E3%81%A8Keras%E3%81%AB%E3%82%88%E3%82%8B%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-Francois-Chollet/dp/4839964262/ref=sr_1_1?ie=UTF8&qid=1544921610&sr=8-1&keywords=keras+python)の商品ページをダウンロードします．実際にコンソールに入力してみてください．

```python:requests.py
import requests
res = requests.get('http://amzn.asia/d/bMmWVHU')
res.text
```

　商品ページのHTMLがダウンロードできたかと思います．しかし，HTMLの内容がべた書きされており，このままでは解析しづらいです．そこで，解析しやすくするためにbs4を使います．先ほどの内容に続いて，次のようにコンソールに入力してください．

```python:beautiful_soup.py
import bs4
soup = bs4.BeautifulSoup(res.text, features='lxml')
print( soup.prettify() )
```

　bs4を用いることで，読みやすい形に整形されました．BeautifulSoupのキーワード引数に与えた「features='lxml'」は，なくても問題なく回りますが，私の使用している環境ではこれをつけないとworningが出ました．友達の環境では，features='lxml' がなくても問題なく実行できました．

　読みやすい形に整形することはできましたが，長すぎて全部確認するのが大変です．必要な個所だけをとるためには，bs4のselectメソッドを使います．selectメソッドはselect(selector)の形式で使用します．selectorはCSSのセレクターです．Google ChromeやMicrosoft edgeで見たい要素の上で右クリックし，検証を選択することでselectorを調べることができます．

　実際にAmazonのレビューを選択して内容を表示してみましょう．先ほどまでの手順でAmazonの商品ページをダウンロードし，bs4で解析できる形にした後，次のように入力します．

```python:select.py
rvws = soup.select('.a-expander-content')
for rvw in rvws:
    print(rvw.text)
```

　selectメソッドは条件に合致するものをリストにして出力します．'.a-expander-content'を指定すると，ページ内のレビューがリストになって出力されます．それをrvwsに代入し，全要素に対してその文章を表示させています．
  selectした対象の文章を表示させるには.textを使いました．URLなどタグの中身を知りたい場合にはattrsメソッドを使います．先ほどと同様に次はタグの中身を表示させます．

```python:attrs.py
rvws = soup.select('.a-expander-content')
for rvw in rvws:
    print(rvw.attrs)
```

 これを実行すると，タグの中身が辞書として表示されます．attrsメソッドを用いてタグを辞書形式にした後，キーワードを用いてタグの中身を取り出すことができます．

　ここまでがwebスクレイピングの基礎です．ここまでの知識を用いてAmazonのレビューを検索してみましょう．

##Amazonのレビューをサーチ
 実際にAmazonのレビューを検索します．実装する機能は以下の通りです．

- 商品トップページのURLをコピーした状態でプログラムを実行するとその商品のレビューを検索できる．
- 初めに検索キーワードを入力してもらう．
- キーワードが含まれるレビューの全文を表示する．

　まず，商品ページから全レビューのページに移動する必要があります．AmazonのURLの場合はdpをproduct-reviewsに置き換えることでレビューページに移動することができます．商品ページのURLをコピーした状態でコンソールに次のコードを入力してください．

```python:jump_page.py
import pyperclip
import webbrowser
url = pyperclip.paste()
new_url = url.replace('dp', 'product-reviews')
webbrowser.open(new_url)
```

　webbrowserを用いるとURLのページをブラウザで開くことができます．このコードを実行すると，商品レビューのページへ移動できると思います．今回実装する機能はレビュー検索ですので，レビューのページをスクレイピングします．

　早速コードを書いていきましょう．まず，全ページのレビューをリストにして取得する関数を定義します．

```python:get_all_reviews.py
def get_all_reviews(url):
    rvw_list = []
    i = 1
    while True:
        print(i,'searching')
        i += 1        
        res = requests.get(url)
        amazon_soup = bs4.BeautifulSoup(res.text, features='lxml')
        rvws = amazon_soup.select('.review-text') # レビューをリストにして取り出す
        for rvw in rvws:
            rvw_list.append(rvw)#レビューをリストに追加

        next_page = amazon_soup.select('li.a-last a')   # 次へボタン

        if next_page != []:     # 次へボタンがあれば
            next_url = 'https://www.amazon.co.jp/' + next_page[0].attrs['href']    # 次へボタンの中にあるURLを参照
            url = next_url         # URLを更新
        else:
            break

    return rvw_list
```

　まず，requestsを用いてページをダウンロードし，bs4を用いてレビューを取り出します．取り出したレビューはリストに追加します．これで１ページ分のレビューを取得できました．これを全ページに対して行います．
　全ページを走査するために次へボタンを使用します．次へボタンのリンク先を用いて，次のページのURLを取得しURLを更新します．これらの操作を次へボタンがなくなるまで繰り返します．
　最後に作成したレビューのリストを返り値とします．

　これで全レビューを取得することができました．この関数を用いてmainの処理を記述していきます．mainの処理は次のようになります．

```python:main.py
if __name__ == '__main__':
    print('Amazonのレビューを検索します\n検索ワードを入力してください')
    key_word = input('検索ワード:')      # 検索キーワードの入力
    url = pyperclip.paste()     # ペーストする。URLをコピーしておかないとエラー出る
    new_url = url.replace('dp', 'product-reviews')     # URLをレビューページのものに書き換える
    rvw_list = get_all_reviews(new_url)    # レビューの取得

    # 全データを表示
    for i in range(len(rvw_list)):
        if key_word in rvw_list[i].text:    # 検索ワードが含まれていたら
            rvw_text = textwrap.fill(rvw_list[i].text, 80)
            print('\nreview{} : '.format(i+1))
            print(rvw_text)
```

　はじめに検索キーワードを受け取ります．URLはクリップボードから取得します．商品ページのURLをレビューページのものに変換し，get_all_reviews関数を呼び出します．取得したデータを走査し，レビューの全文に検索キーワードが含まれていれば，レビューを整形して表示します．レビューの整形にはtextwrapを使用します．今回は80文字ごとに改行して表示しました．

##完成品
　作成したコードの全文を載せておきます．

```python:amazon_search.py
#! python3
# amazon_search.py
# 2018/12/16

import requests     # webデータダウンロード用
import bs4          # HTML解析用のライブラリ
import pyperclip    # コピー＆ペーストをするためのライブラリ
import textwrap     # 長い文字列を改行して表示

# 全ページ分リストにする
def get_all_reviews(url):
    rvw_list = []
    i = 1
    while True:
        print(i,'searching')
        i += 1
        res = requests.get(url)
        amazon_soup = bs4.BeautifulSoup(res.text, features='lxml')
        rvws = amazon_soup.select('.review-text') # レビューをリストにして取り出す
        for rvw in rvws:
            rvw_list.append(rvw)

        next_page = amazon_soup.select('li.a-last a')   # 次へボタン

        if next_page != []:     # 次へボタンがあれば
            next_url = 'https://www.amazon.co.jp/' + next_page[0].attrs['href']    # 次へボタンの中にあるURLを参照
            url = next_url         # URLを更新
        else:
            break

    return rvw_list


if __name__ == '__main__':
    print('Amazonのレビューを検索します\n検索ワードを入力してください')
    key_word = input('検索ワード:')      # 検索キーワードの入力
    url = pyperclip.paste()     # ペーストする。URLをコピーしておかないとエラー出る
    new_url = url.replace('dp', 'product-reviews')     # URLをレビューページのものに書き換える
    rvw_list = get_all_reviews(new_url)    # レビューの取得

    # 全データを表示
    for i in range(len(rvw_list)):
        if key_word in rvw_list[i].text:    # 検索ワードが含まれていたら
            rvw_text = textwrap.fill(rvw_list[i].text, 80)
            print('\nreview{} : '.format(i+1))
            print(rvw_text)
```

##おわりに
 以上でAmazonのレビューを検索できました．これを応用すれば，食べログのランキング機能や，＠cosmeのレビュー検索機能を実装できます．有料会員限定の機能を実装して公開するのはどうかと思うので私は解説ページを作りません．もし，作りたい方がおられましたら本ページを参考にチャレンジしてみてください．