Edited at

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


Introduction


きっかけ

webスクレピングを習得する必要があったので、Googleで検索してみたところ、今の自分の状態(beautifulsoup4をPython3で使う)とマッチするものが見当たらなかったので、備忘録としてまとめておきます。参照サイトは、Python2系での実装なので、初心者の僕にはPython3系に直すのは大変でした…きっと同じ人はいると思いましたので最初のチュートリアルのみpython3系で実装してみましょう!

自己紹介→いつものやつ

Cf.)Webスクレイピングに関しての注意点

参照サイトにも記載されていたので、まるまる引用させてもらいます。

岡崎市立中央図書館事件(Librahack事件) - Wikipedia

Webスクレイピングの注意事項一覧

「岡崎市立中央図書館事件(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

何度も紹介している気もしますが、こちらの参照サイトにお世話になりました。

上記のサイトを軸にわからないとこなどで適宜調べたもの、エラー対処などをまとめておきます。

それでは張り切ってまいりましょう。

とりあえず説明は後にして、うまくいったコードを先に紹介します。


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となっています。そのままでも検索エンジン側で上手に変更してくれるんですが、たまたま気づいたので変更しておきました。

httpshttpの違いについては、端的に述べれば安全性の問題です。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の場合を引用


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を無視する記事が出てきましたが、意味を知りたかったので仕方なく英語記事を探しまくったところ以下のような意味だと推測しま思います。

これは、証明書検証が有効になっていない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