Python3系で Webスクレイピング 入門

# Introduction

## きっかけ
webスクレピングを習得する必要があったので、Googleで検索してみたところ、今の自分の状態(beautifulsoup4をPython3で使う)とマッチするものが見当たらなかったので、備忘録としてまとめておきます。[参照サイト](https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406)は、Python2系での実装なので、初心者の僕にはPython3系に直すのは大変でした…きっと同じ人はいると思いましたので最初のチュートリアルのみpython3系で実装してみましょう！
自己紹介→[いつものやつ](https://qiita.com/Senple/items/b47374e68e4d8d26d0cb)

Cf.)Webスクレイピングに関しての注意点
[参照サイト](https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406)にも記載されていたので、まるまる引用させてもらいます。
・[岡崎市立中央図書館事件(Librahack事件) - Wikipedia](https://ja.wikipedia.org/wiki/岡崎市立中央図書館事件)
・[Webスクレイピングの注意事項一覧](https://qiita.com/nezuq/items/c5e827e1827e7cb29011)

「岡崎市立中央図書館事件(Librahack事件) - Wikipedia」に関しては**シャレにならない**ので不安しかないです。


## 問題点
参照サイトのほうでは、python2系で実装して使われています。バージョン情報は以下に示します。ちなみにライブラリの紹介もしていましたので、引用しました。

>
urllib2はURLにアクセスするために必要です。
BeautifulSoupはアクセスして取得したファイルを開くxmlパーサー的なものです

```参照サイト.ver
Python:2.7.12
ライブラリ:urllib2、BeautifulSoup
```

```当記事.ver
Python:3.6.5
ライブラリ：
BeautifulSoup4==4.6.1
certifi==2018.4.16
urllib3==1.22
```
Python2系・3系問題以外にも、URLのルールが変わっている(http→https)関係で、urllib自体のコードにもいくつか変更が加わっていました。

### 対象者
・Python3系を使っているユーザー(Anacondaでインストール)
・Webスクレイピングの初心者の方
・1を聞いて10を理解できるエンジニア
・**Windows**の人

### 非対象者
・Python2系を使っているユーザー
・Webスクレイピングが超お得意な人
・説明下手な筆者を攻撃しようとするエンジニア
・**Mac**の人

Cf.)Python2系とかPython3系の意味が分からない人へ！
Pythonには2系と3系があって、最近始めた人ならほとんどPython3系だと思います。一応バージョンを確認する方法を記載しておきます。
コマンドプロンプトでPythonのインタラクティブ(対話)モードを起動すればバージョン情報が表示されます。

```
$ Python
>Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
インタラクティブモードを辞めるには*exit()*を入力しましょう！



# Let's Start
~~何度も紹介している気もしますが、~~こちらの[参照サイト](https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406)にお世話になりました。
上記のサイトを軸にわからないとこなどで適宜調べたもの、エラー対処などをまとめておきます。
それでは張り切ってまいりましょう。
とりあえず説明は後にして、うまくいったコードを先に紹介します。

```Python:getNikkei.py

# coding:utf-8
import urllib3
from bs4 import BeautifulSoup
import certifi

# アクセスするURL
url = "https://www.nikkei.com/"

# httpsの証明書検証を実行している
http = urllib3.PoolManager(
    cert_reqs='CERT_REQUIRED',
    ca_certs=certifi.where())
r = http.request('GET', url)

soup = BeautifulSoup(r.data, 'html.parser')

# タイトル要素を取得する → <title>経済、株価、ビジネス、政治のニュース:日経電子版</title>
title_tag = soup.title

# 要素の文字列を取得する → 経済、株価、ビジネス、政治のニュース:日経電子版
title = title_tag.string

# タイトル要素を出力
print(title_tag)

# タイトルを文字列を出力
print(title)

```

コメントなどはほとんど参照サイトのままです。
変更点を解説していきます。

### 1、importについて
```
変更:
urllib2⇒urllib3
BeautifulSoup⇒BeautifulSoup4
追加:
certifi
```
変更したライブラリは、Python3系のスタンダードらしいです。
pip installしたのは、**BeautifulSoup4**だけです。
追加したcertifiは**3、httpについて**で解説します。

### 2、urlについて
参照サイトのほうでは、"https://www.nikkei.com/" の**https**部分は**http**となっています。そのままでも検索エンジン側で上手に変更してくれるんですが、たまたま気づいたので変更しておきました。
**https**と**http**の違いについては、端的に述べれば安全性の問題です。Googleの推奨する安全レベルが**https**ですが、かといって**http**が危険と短絡的に決めつけてはだめですよー。

わかりやすい感じの記事を見つけたので、紹介しておきます。
https://www.bloom-promotion.jp/journal/web-knowledge/http-https-ssl-difference.html
>
httpsは、httpにセキュリティ機能を追加したもので、Webページとの通信を暗号化したものです。

### 3、httpについて
Python2系のurllib2ではurlopen()というコードでhtmlを取得できるわけだけど、Python3系のurllib3にはurlopenはないので、似たような機能を持つPoolManager()を利用しましょう。
参考：
https://teratail.com/questions/84432
https://pypi.org/project/urllib3/
urllib3の場合を引用

```Python:getNikkei.py
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
import urllib3

url = "http://www.nikkei.com/"

http = urllib3.PoolManager()
r = http.request('GET', url)

soup = BeautifulSoup(r.data, 'html.parser')

# タイトル要素を取得する → <title>経済、株価、ビジネス、政治のニュース:日経電子版</title>
title_tag = soup.title

# 要素の文字列を取得する → 経済、株価、ビジネス、政治のニュース:日経電子版
title = title_tag.string

# タイトル要素を出力
print(title_tag)

# タイトルを文字列を出力
print(title)
```
このコードで実行したところエラーコードではないですが、注意！みたいなコードが出ました。

```
$ python getNikkei.py
(一部省略)\lib\site-packages\urllib3\connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
```
とのWarningが出てきたので調べてみると、WarningコードでGoogle検索をしました。
日本語の記事は[Warningを無視する記事](http://73spica.tech/blog/requests-insecurerequestwarning-disable/)が出てきましたが、意味を知りたかったので仕方なく英語記事を探しまくったところ以下のような意味だと~~推測しま~~思います。

これは、証明書検証が有効になっていないHTTPS URLに対して要求が行われたときに発生します。この警告を解決するには、証明書の確認ガイドに従ってください。
つまりhttpsにはsslの証明書がついてて、その証明書を確認できるようなコードを付け足さないと、危険だぞーとかいうwarningなので、証明書を確認するコードを付せば解決するらしいです。

```
http = urllib3.PoolManager(
    cert_reqs='CERT_REQUIRED',
    ca_certs=certifi.where())
```

このコードのために**1、importについて**でcertifiをimportしました。
最下部**その他参照サイト**に英語版ですが、リンクを置いておきます。
意味が違ったらその旨コメントいただけると幸いです。


### 4、printについて
Python2系ではprintには()を付けません。
Python3系ではprint()を付けます。

ものすごく簡単でわかりやすい違いなので、個人的にはコードが2系か3系か判断しづらい時のチェックポイントにしています。

## さいごに…
以上コードの変更点と補足の説明でした。
少しでも古い記事だと、環境・バージョンが変わってコードが動かなくてパニックになるので、~~(個人の意見です)~~気づいた時には今回のようにうまくまとめていこうと思います。
少しでも自分と同じような状況の人の助けになればうれしいです。
なお参照サイトではこの先、実践プログラムについての説明を続けていますが、もともとの目的であるPython3でのBeautifulSoup4の動かし方がわかったので、~~面倒だし…~~省略します。


## その他参照サイト
https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl