スクレイピングをご存知でしょうか?
スクレイピングはインターネット上のWebサイトから情報を引っ張り出すための方法のことです。
ここでは「スクレイピングって何?」「どうやってスクレイピングするの?」「スクレイピングするためのライブラリが知りたい」といった疑問に対して、Pythonのライブラリを紹介する形で解説します。
スクレイピングができるようになると、インターネットがもっと楽しくなるかもしれません(^^♪
スクレイピングとは
スクレイピングとは「Webスクレイピング」の略で、Webサイトから情報を収集することを指します。
例えば複数のニュースサイトのヘッドラインを見たい場合、普段通りなら一つ一つサイトを見て回ると思います。スクレイピングができるようになると、他のWebサイトから情報を集めるのが容易になります。
スクレイピングする際のルール
スクレイピングは他者が著作権を有するWebサイトから情報を取得する処理であることから、著作権法に違反するようなことはできません。
しかし、日本でスクレイピングを行う場合の著作権の取り扱いは「データ分析や教育目的、引用目的等であれば、そのスクレイピングは著作権法上認められる範囲」となっています。
参考サイト:https://www.itmedia.co.jp/news/articles/1710/10/news040.html
例えば、深層学習で猫の画像を判別できるボットを作る場合、猫の画像を大量にインプットする必要がありますが、データ分析や学習のためであれば画像をスクレイピングして利用したり、作成したボットを公開することは特に問題ないようです。
しかし、スクレイピングで得た情報をそのまま公開したり、取得したデータを直接利用して金銭を得るといった行動は違反となるので、注意しましょう。
※法律の専門家ではありませんので、情報が間違っている可能性があることをご了承ください。また、法律が改正されて、利用できなくなる場合もありますのでご注意ください。詳しくは専門家にご相談ください。
Pythonでスクレイピングするためのライブラリ
次にPythonでスクレイピングするために必須なライブラリを見ていきましょう。
また、ここでは各ライブラリの紹介の他に簡単な使い方も解説しています。動作を確認しながら読み進めたい場合は以下のコマンドを実行してライブラリを事前にインストールしておくと後々はかどります。
$ pip install requests beautifulsoup4
urllib
urllibは最も基本的なPython標準のスクレイピングライブラリです。
あとで解説するrequestsの方が使いやすさはありますが、サードパーティ製のライブラリを使えない等の縛りがある場合はurllibを使うことになるでしょう。
urllibは4つのモジュールを集めたパッケージですが、ここでは使用頻度の高いurllib.request()を使って、urllibの使い方を解説します。
urllibを使ってhtmlを取得する
では、urllib.request()を使ってhtmlを取得してみましょう。なお、ここではPython3を使った場合を想定しています(Python2とPython3ではimportの仕方が異なります)。
import urllib.request, urllib.error
url = 'https://myafu-python.com/basic/'
response = urllib.request.urlopen(url) #urlopen()で指定したurlのサイトを開く
data = response.read() #read()で読み込む
html = data.decode() #そのままだとマルチバイト文字がエスケープされているので、decode()する
print(html)
[出力結果]
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
---以下省略---
url変数は読み込むページのurlです。今回は当サイトのPython入門ページのhtmlを取得してみます。
htmlを取得するにはまずページを開く必要があります。urlopen()にurlを渡してページを開きます。
次にread()を使ってページの読み込みを行います。読み込んだらdata変数にhtmlが格納されます。
ですが、そのままだとマルチバイト文字がエスケープされているので、decode()を使ってデコードします。ここまですると結果のようなhtmlを取得できます(長すぎるのでここでは省略しています)。
requests
requestsはurllibの代わりとなるサードパーティライブラリです。
urllibよりも直感的でシンプルにコードを書けることが特徴で、使うと可読性が上がりますので、サードパーティ製ライブラリが使えるならurllibよりこちらを使った方が良いかもしれません。
requestsを使ってhtmlを取得する
では、今度はrequestsを使って同じようにhtmlを取得してみます。
import requests
url = 'https://myafu-python.com/basic/'
response = requests.get(url) #get()で指定したurlのサイトの情報を取得
print(response.text) #取得したhtmlを出力
[出力結果]
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
---以下省略---
明らかにurllibの時よりも記述量が減ったのがお分りいただけるかと思います。
urllibではurlopen()でwebサイトを開き、read()で読み込み、さらにdecode()でデコードするというつの処理が必要でしたが、requestsではget()だけでデコードされたhtmlを取得することができました。
requestsについては、以下の記事もご覧ください。
Beautiful Soup
さて、ここまではwebサイトからhtmlを取得するライブラリを見てきました。
しかし、htmlを取得するだけでは、そのサイトから必要な情報を取得したり、サイトを操作することができません。htmlを解析・分解して、サイト内の情報に簡単にアクセスできるようにする必要があります。
ここで登場するのがBeautiful Soupです。Beautiful Soupはhtmlを渡すことで構造を解析し、要素にアクセスしやすくします。
Beautiful Soupを使ってhtmlを参照する
では実際にBeautiful Soupを使ってみましょう。htmlの取得にはrequestsを使います。
今回は、「python入門ページ内の全ての記事のタイトルを取得」しています。
import requests
from bs4 import BeautifulSoup
url = 'https://myafu-python.com/basic/'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser') #Beautiful Soupにhtmlを渡してパース(解析)する
h2_ary = soup.find_all('h2', class_ = 'entry-card-title') #htmlの中からh2タグでクラスが「entry-card-title」の要素を全て引っぱってくる
for h2 in h2_ary:
print(h2.contents[0]) #h2のコンテンツ(ここでは記事のタイトル)を順に出力する
[出力結果]
Pythonの特徴・基本の書き方
型(数値や文字列など)
定数と変数
条件分岐(if)
例外処理(try~except)
リスト(list)の使い方
辞書(dict)型の使い方
繰り返し処理(while文)
繰り返し処理(for)
関数の使い方
タプル(tuple)の使い方
文字コードの基本(エンコードやバイナリーなど)
ほんの数行追加するだけで、記事のタイトル一覧を取得することができました。
さて、ここでは参照先のpython入門サイトの各記事のタイトルを取得する、というのが目的です。
ここで重要なのは「タイトルのタグやクラス」の情報です。
実際にサイトの構造を見てみましょう。
1番目の記事のタイトル

2番目の記事のタイトル

記事のタイトルは「h2」タグで「entry-card-title」というクラスが付与されているようです。
これを踏まえてソースコードを追ってみましょう。
requestsを使ってhtmlを取得するところまでは、Beautiful Soupをインポートする以外に変更点はありません。
htmlを取得したらそれをBeautiful Soupに渡します。第二引数に html.parser を渡すことで、第一引数をhtmlとして解釈して解析してくれます。
次に解析した結果であるsoupの中から「タグがh2、かつクラスがentry-card-title」である要素をfind_all()で全て取得します。
h2タグを取得したら、それをfor..inで繰り返し処理します。最後にh2タグ内のコンテンツ(記事タイトルのテキスト)をcontents()で取得しています。
Beautiful Soupを使うことで、html内の要素に簡単にアクセスできました。
今回はタグとクラスを使ってタイトルを取得しましたが、Beautiful SoupではCSSのセレクタとほぼ同じレベルで要素の抽出が可能です。