今日はPythonで実際に有名なWebサイトをスクレイピングしてみたいと思います。
Contents
Requestsとは
Requestsは、PythonのHTTP通信ライブラリです。Requestsを使うとWebサイトの情報取得や画像の収集などを簡単に行えます。
Python には標準で urllib というライブラリが存在しますが、 Requests はそれよりもシンプルに、人が直感的に分かりやすいプログラムを記述できます。Requests ライブラリは、他のライブラリと組み合わせて使用できます。
例えば Beautiful Soup と組み合わせると、Webサイトを解析して必要な情報だけを抜き出すことができます。また、BytesIO と Pillow と組み合わせて、Webサイト上の画像URLをもとに、画像ファイルを取得することもできます。
関連記事:【Python】requestsで画像・動画ファイルをスクレイピングしてダウンロードするサンプルプログラム
BeautifulSoupとは
BeautifulSoupはスクレイピングのコードを書いているPythonユーザーの中で最も使われている有名なモジュールです。BeautifulSoupはカンタンな書き方で特定の要素をカンタンに取り出せるのがとても魅力的です。
関連記事:【Python】requestsとBeautifulSoupでウェブサイト内の画像データをスクレイピングで自動収集する
RequestとBeautifulSoupでWebサイトをスクレイピングするサンプルコード
今回はウェキペディアの記事(https://ja.wikipedia.org/wiki/ONE_PIECE)をスクレイピングしてみます。
# requestsをpipからインストール pip install requests pip install beautifulsoup4
Requestでhtmlを取得する
まずはrequestsで情報を取得します。具体的にはrequest.get() というメソッドを使用します。そしてrequest.get()の引数としてスクレイピングしたいサイトのURLを指定します。
import requests r = requests.get('https://ja.wikipedia.org/wiki/ONE_PIECE') print(r.text)
<実行結果>
<!DOCTYPE html>\n<html class=”client-nojs” lang=”ja” dir=”ltr”>\n<head>\n<meta charset=”UTF-8″/>\n<title>ONE PIECE – Wikipedia</title>\n<script>document.documentElement.className=”client-js”;RLCONF={“wgBreakFrames”:false,”wgSeparatorTransformTable”:[“”,””],”wgDigitTransformTable”:[“”,””],”wgDefaultDateFormat”:”ja”,”wgMonthNames”:[“”,”1月”,”2月”,”3月”,”4月”,”5月”,”6月”,”7月”,”8月”,”9月”,”10月”,”11月”,”12月”],”wgRequestId”:”958e57e0-752f-4ac4-a1e8-11b5d125aa61″,”wgCSPNonce”:false,”wgCanonicalNamespace”:””,”wgCanonicalSpecialPageName”:false,”wgNamespaceNumber”:0,”wgPageName”:”ONE_PIECE”,”wgTitle”:”ONE PIECE”,”wgCurRevisionId”:91284935,”wgRevisionId”:91284935,”wgArticleId”:1470219,”wgIsArticle”:true,”wgIsRedirect”:false,”wgAction”:”view”,”wgUserName”:null,”wgUserGroups”:[“*”],”wgCategories”:[“Webarchiveテンプレートのウェイバックリンク”,”外部リンクがリンク切れになっている記事/2018年3月”,”編集半保護中のページ”,”出典を必要とする記述のある記事/2016年2月”,”無効な出典が含まれている記事/2017年”,”ONE PIECE”,”漫画作品 わ”,”1997年の漫画”,\n”週刊少年ジャンプの漫画作品”,”海賊を題材とした漫画作品”,”冒険漫画”,”ハイファンタジー漫画”,”アクション漫
この実行結果がサイトのhtmlデータになります。サイトのhtmlデータはgoogleChromeのデベロッパーツールを使って確認することができます。デベロッパーツールはサイト上の右クリック→「検証」をクリックすると起動します。
BeautifulSoupでhtmlからほしい情報を抽出する
サイトのHTMLが取得できたら次はそこからほしい情報を抽出します。r.textのhtmlデータは文字型(str)ですが、タグに囲まれたHTMLの中から必要な情報を抽出するわけですが、そのままだと正規表現などを使用する必要があり非常に手間がかかります。そんなときに便利なのがBeautifulSoupです。
というわけで文字型のデータをBeautifulSoupの型に変換します。
from bs4 import BeautifulSoup soup = BeautifulSoup(r.content)
タグ名でHTML要素を検索する
まずBeautifulSoupでサイトのタイトルを抽出します。基本的にwebサイトはHTMLのheader(ブラウザ上からは見えない部分)にtitleタグでサイトのタイトルを表示しているのでそれを確認します。このtitleタグの情報を取得したい場合はいろいろ方法がありますが、まずタグ名を指定して検索します。
title = soup.find('title') print(title)
<実行結果>
<title>ONE PIECE – Wikipedia</title>
前後の<title>~<title>タグが不必要で中身のテキストだけほしい場合は以下のように記述します。
print(title.text)
このタグ名での検索はtitleタグのようにwebサイトに基本的に一つしかないタグの検索には便利ですが、pタグやdivタグのような頻繁に使われるタグに囲まれた情報を抽出したい場合には不向きです。そんなときはタグの中に記載されているクラス名やid名を使って要素を抽出します。
クラス名による要素抽出
また、html class でデータを絞ることもできます。例えば、このサイトのトップページにおいて、
テーブル部分は class=”infobox bordered”という html class が付けられているので、以下のように _class で指定して find() することで指定したクラスを含むタグを抽出できます。
table = soup.find('table',class_='infobox bordered') print(table)
<実行結果>
<table class=”infobox bordered”> <tbody><tr> <th colspan=”2″ style=”background-color:#ccf; text-align:center;”>ONE PIECE </th></tr> <tr> <th style=”background:#e6e9ff”>ジャンル </th> <td><a href=”/wiki/%E5%B0%91%E5%B9%B…
.find_allでまとめて取得する
Webサイトのhtmlでは同じタグ名。クラスのものが複数回使用されるケースがあります。そんなときにfindだけでは一つしか取得できないので肝心の情報を取得できない、なんてケースがあります。そんな場合はfind_all()というメソッドを使用します。例えばサイト内のtableタグの情報をすべて取得したい場合は以下のように記述します。
h4s = soup.find_all('h4') print(h4s)
<実行結果>
[<h4><span id=”.E6.9D.B1.E3.81.AE.E6.B5.B7.E7.B7.A8″></span><span class=”mw-headline” id=”東の海編”>東の海編</span></h4>, <h4><span id…
このままだと各要素ごとにリストに入っているので処理をする際はfor文もしくはインデックスを指定して要素を取りだす必要があります。
例)
for h4 in h4s: print(h4.text) #.textとすることでタグの中のテキストのみを取得できる
<実行結果>
東の海編
アラバスタ編
空島編
ウォーターセブン編
スリラーバーク編
頂上戦争編
魚人島編
パンクハザード編
ドレスローザ編
ホールケーキアイランド編
ワノ国編
集英社マンガ総集編シリーズ
集英社ジャンプリミックス
ノベライズ作品
その他の小説作品
家庭用ゲーム
モバイルゲーム
アーケードゲーム
アミューズメントマシン
ヨーロッパ
北アメリカ
アジア
週刊少年ジャンプ関連
またリンクを取得した場合はHTMLではリンクはaタグで囲まれているので以下のように検索することで取得できます。
a_tags = soup.find_all('a') print(a_tags) for a_tag in a_tags: print(a_tag['href'])
こんな感じにRequestとBeautifulSoupを使用すればWebサイトをスクレイピングが簡単にできるので皆さんもぜひ試してみてください
コメント
[…] 例外処理でエラーメッセージ出力 例外処理でエラーが発生した際にログを残す方法は以下の2つが一般的です。 traceback Exception サンプルコード Exceptionを使う … RequestsとBeautifulSoupでWikipediaをスクレイピングするサンプルコード […]