【Pythonスクレイピング】Google検索結果TOP3を自動抽出する


*  プログラミング歴45日の素人が書いています。ご注意ください。

#注意

**スクレイピングは利用方法によってはスクレイピング先のサーバに異常な負荷がかかります。
場合によってはグレー、違法となる可能性がありますのでご注意ください。**



#はじめに

【想定】WEBメディア運営の一貫として、あるキーワードに対してどんな記事が人気があるのかを調べます。


* 「goodkeyword」（https://goodkeyword.net） を使うと、あるキーワードに関連する検索ワードが100件出てきます。

* 100件の検索キーワードについて、Googleで検索した時のhit上位3件を自動で取得して、CSVにまとめます。


##環境

* MacBookAir-mid2014

* macOS-Mojave

* Python 3.7.4


#Googleキーワードで人気のありそうな関連キーワードを調べる

「goodkeyword」（https://goodkeyword.net） を使うと、あるキーワードに関連する検索ワードが100件出てきます。

コピーしてCSVにまとめます。

![スクリーンショット 2019-07-25 20.32.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452235/e984de06-117b-40ad-f2da-af5c437cd565.png)



CSVにコピペする。

![スクリーンショット 2019-07-25 20.34.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452235/6186ba17-0e24-723f-0cfc-f083e347e2f1.png)



#Pythonでスクレイピングする

```python
import requests
from bs4 import BeautifulSoup

with open('keys.csv', encoding='shift_jis') as csv_file:
    with open('result.csv','w') as f:

        for keys in csv_file:
            result = requests.get('https://www.google.com/search?q={}/'.format(keys))
            soup = BeautifulSoup(result.text, 'html.parser')
            list = soup.findAll(True, {'class' : 'BNeawe vvjwJb AP7Wnd'})
            
            for i in range(3):
                a = str(list[i]).strip('<div class="BNeawe vvjwJb AP7Wnd">')
                result_title = a.strip('</')
                keyword = keys.rstrip("\n")
                f.write('{0},{1}\n'.format(keyword, result_title))

---
#target divs example
    # <div class="BNeawe vvjwJb AP7Wnd">フィリピン人女性5つの特徴
    # <div class="BNeawe vvjwJb AP7Wnd">フィリピン人 - Wikipedia
```

コードが汚いのは素人なのでかんべんしてください。


##ライブラリのimport

```python
import requests
from bs4 import BeautifulSoup
```

「requests」と「BeautifulSoup」をインポートします。


##CSVファイルの準備

```python
with open('keys.csv', encoding='shift_jis') as csv_file:
    with open('result.csv','w') as f:
```

* `keys.csv`には、検索キーワードが１行づつ入っています。

* `result.csv`は、ディレクトリに存在しなければ自動で作成されます。


##HTMLデータの取得

```python

for keys in csv_file:
    result = requests.get('https://www.google.com/search?q={}/'.format(keys))
    soup = BeautifulSoup(result.text, 'html.parser')
    list = soup.findAll(True, {'class' : 'BNeawe vvjwJb AP7Wnd'})
```

* CSVファイルの中身を１行づつ取り出して、変数`keys`に格納します。（これが検索キーワード）

* GoogleのURL末尾に検索キーワードを代入して、getリクエストを送ります。

* 取得したデータをBeautifulSoupがHTMLとして扱えるようにしてくれます。

* さらにそこから、ターゲットとなるクラスをもつdivとクラスを指定して抜き出します。



###複数のクラスを指定して`findAll`する

複数のクラスを指定して`findAll`するためには、

```python
soup.findAll(True, {'class' : 'BNeawe vvjwJb AP7Wnd'})
```

のように書きます。
`True`指定して、第二引数にリストを渡すと、`&&`指定になります。



###クラスが変わる？

同じURLでアクセスしているにも関わらず、ブラウザに表示されるHTMLと、requestsで取得するHTMLが違っていました。


*↓ブラウザでは、`<h3 class="LC20lb">`が検索結果のタイトルになっている*

![スクリーンショット 2019-07-25 20.51.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452235/34d47a40-6c20-494b-31bd-e528b6ce99e7.png)


ターミナルで確認すると、`<div class="BNeawe vvjwJb AP7Wnd">`に変わっている
（わかるかた教えていただきたいです）

![スクリーンショット 2019-07-25 20.57.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452235/3afff353-684a-e404-90c0-7577229e5aba.png)


##加工してCSVに書き込む

```python
for i in range(3):
      a = str(list[i]).strip('<div class="BNeawe vvjwJb AP7Wnd">')
      result_title = a.strip('</')
      keyword = keys.rstrip("\n")
      f.write('{0},{1}\n'.format(keyword, result_title))
```

* 今回は上位3件だけを抽出するので、`range(3)`で設定して各キーワードについて３回づつループを回してCSVに出力します。

![スクリーンショット 2019-07-25 21.02.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452235/3eb4e673-5f16-ad67-3ebb-bd0c90d51076.png)


* `find_all`メソッドで抜き出したデータには`div`タグが含まれていますので、これを`strip`メソッドで取り除きます。

* `keys.csv`にもともと入っている検索キーワードには、不要な改行`\n`が含まれているので、これも`rstrip`メソッドで取り除きます。`rstrip`メソッドは文字列を右から削除するメソッドです。

* `write`メソッドで`result.csv`に書き込んで終了です。


#エクセルなどで確認する

以下のように出力されています。

![スクリーンショット 2019-07-25 21.07.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452235/012209e0-378e-d1ad-da4e-87184b34ae41.png)


テキストエディタでみると、1行につき、コンマで区切られた状態になっています。

![スクリーンショット 2019-07-25 21.08.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452235/48686eb0-fb8f-527d-bfe7-22bebe616b95.png)



#まとめ

* CSVファイルに入っている検索キーワード100件で検索し、各検索結果のTOP3を新しいCSVファイルにまとめました。

*　複数のクラスを指定して`findAll`することもできます。

* CSVファイルは１行ごとに改行が入る（当たり前だけど）ので、`rstrip`で取り除く。