- ウェブサイトからデータを取得するスクレイピングが流行っているらしい。
- しかし、初心者の方にもわかりやすい説明がされている文献があまりない。
- そこで今回は、スクレイピング初心者の方にもわかりやすいように、ウェブサイトでスクレイピングしデータ取得するまでを丁寧に説明する。
これから説明するスクレイピングは、使い方によっては不正アクセスや偽計業務妨害に問われる可能性があります。これらの法律などを熟知してからこの先に進んでください(詳細はこちらのサイトを確認してください)。
またスクレイピングで得たデータを利用する際は十分に注意してください。
今後、このサイトで紹介したスクレイピングによって罪に問われた場合において、当サイトでは一切の責任は負いませんのであらかじめご承知おきください。
早速、今回使用するプログラムを紹介
では早速、今回使用するプログラムはこちらになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import requests import csv from bs4 import BeautifulSoup def main(): url = "https://www.hinatazaka46.com/s/official/news/list?ima=0000&dy=202203" response = requests.get(url) soup = BeautifulSoup(response.content, "html.parser") schedule = soup.find("ul", attrs={"class": "p-news__list p-news__list--long"}) entries = schedule.find_all("a") schedule_list = [] for i, entry in enumerate(entries): schedule_list.append([i+1, entry.get_text()]) with open("schedule_data.csv", "w", encoding="cp932") as f: writer = csv.writer(f, lineterminator="\n") writer.writerows(schedule_list) if __name__ == "__main__": main() |
では、ここからはより詳細にプログラムを見ていきましょう。
より詳細な説明

今回のプログラムの処理フローの説明
より詳細な説明をする前に、今回のプログラムでやっていることを簡単に説明します。
- 日向坂46のスケジュールが記載されている公式サイトを確認。
- 公式サイトのHTMLからスケジュールのタグを確認。
- BeautofulSoupを使ってスケジュールのテキストに変換。
- 取得したテキストをcsvファイルに書き込む。
こんな感じの流れになります。(あくまで勉強目的であって、決してストーキング目的ではないので、その辺は悪しからず。。。)
開発環境 & pythonライブラリインストール(Google Colab以外の場合)
今回はGoogle Colaboratoryを使用して説明していますが、AnacondaやVisual Studio Codeでも必要なライブラリをインストールすれば使えます。
csvライブラリは標準でインストールされているので、requestsとBeautifulSoupをまずはインストールしましょう。
Google Colaboratoryを使用しない方は以下のコマンドをコマンドプロンプト、またはターミナルで実行してください。
1 2 | python -m pip install --user requests python -m pip install --user beautifulsoup4 |
もしかしたら、Visual Studio Codeを使用したことがない方やライブラリのインストール方法がわからない方がいるかと思います。
そういう方は以下のサイトで詳しく説明しているので、そちらを参照してから先に進むことをおススメします。

requests.get(url)


requests.get(url)では、引数に与えられたurlのrequestsオブジェクトを取得することができます。
ここでrequestsオブジェクトとは、サイト内にある様々なデータのことです。これにはurl属性やステータスコード、さらにレスポンスヘッダ等、様々なものが含まれます。
BeautifulSoup(response.content, “html.parser”)


BeautifulSoupは、HTMLをタグ単位で解析するモジュールです。ここでいうタグ単位とは、divやli等のことです。指定したタグ内のデータを自動で取得することをスクレイピング、というイメージで良いです。
では、実際にHTMLタグを確認してみましょう。日向坂の公式サイトに行き、スケジュールというところをクリックすると以下のような画面になると思います。


この画面の状態から、デベロッパーツールを起動させます。chromeを使っている方は「Fキー」+「F12」で起動できます(↓のように)。


HTMLを見てみると、欲しいデータのタグは「ul」と「a」タグ内にあることが確認できました。


このようにして、欲しいデータをHTML内から探し出し、BeautifulSoupで解析するといった流れになります。
また、引数であるresponse.contentは、先ほど取得したresponseをバイナリーデータに変換します。
さらにhtml.parserは、HTMLの解析器のことです。バイナリ化されたHTMLを解析します。基本、html.parserで大丈夫ですが、このほかにもlxmlやxmlなどあるのでこちらも押さえておきましょう。
- lxml・・・高速に処理することが可能
- xml・・・XMLに対応。なおかつ高速に処理することが可能
- html5lib・・・最新バージョンのHTML5を処理する際に使用するパーサー
soup.find(“ul”, attrs={“class”: “p-news__list p-news__list–long”}) & soup.find_all(“a”)


soup.find()は、引数1に指定されたタグをHTML内から探し、一番最初に見つかったタグについてデータを返します。引数2は欲しいデータのclass名とIDを指定します。
一方、soup.find_all()は引数に指定されたタグと一致するタグ内データをすべて取得します。
soup.find()とsoup.find_all()の違いは、最初に見つかったタグ内のデータを取得するか、一致するすべてのタグ内データ全てを取得するかどうか
entry.get_text()


enumerate(entries)で取得したデータを、テキストファイルとしてリストに格納します。
with open(“schedule_data.csv”, “w”, encoding=”cp932″) as f:


これまでに取得してきたデータをcsvファイルとして書き出すために、with open関数を利用しています。
既にいろんなサイトで紹介されているので、あえてここで紹介しませんが、引数1でファイル名を指定、引数2で書き込みモード”w”を指定、引数3はエンコーディングを指定します。
私の環境では「shift_jis」がうまく使えなかったので、「CP932」を使用しています。詳しく知りたい方は、こちらのサイトを参照してください。
すべての開設を反映させた結果
さて、これまで説明してきたプログラムをコメント付きで再度確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import requests import csv from bs4 import BeautifulSoup def main(): url = "https://www.hinatazaka46.com/s/official/news/list?ima=0000&dy=202203" # requests.get(url) -> 引数に入力されたurlのrequestオブジェクトを取得できる。 # requestsオブジェクトとはサイトの中の様々な情報(url属性、ステータスコードやレスポンスヘッダ等)。 response = requests.get(url) # BeautifulSoup(response.content, "html.parser") -> url先のHTMLをタグ単位(divやli等)で解析する。出力はHTMLデータを返す(print(soup))。 # (引数1)response.content -> responseをバイナリーデータにする。 # (引数2)html.parser -> HTMLの解析器。responceでバイナリ化されたHTMLを解析する。基本これでOK。 # 他にも"lxml", "xml"や"html5lib"がある。それぞれの説明は省略。 soup = BeautifulSoup(response.content, "html.parser") # soup.find(引数1, attrs=引数2).text -> HTMLから引数1に入力された一番最初のタグを検索、引数2のclass名の中にあるデータを返す。 # (引数1)"ul" -> HTMLから一番最初に出てくるulタグを検索。 # (引数2)attrs={"class": "p-news__list p-news__list--long"} -> HTML内のclass = p-news__list p-news__list--long内のデータを取り出す。 schedule = soup.find("ul", attrs={"class": "p-news__list p-news__list--long"}) # schedule.find_all(引数1) -> 引数1に入力されたタグと一致するものデータをすべて取得する。 # (引数1) -> HTML内の取得したいデータがあるところのタグ。今回の場合は"a"。 entries = schedule.find_all("a") schedule_list = [] # enumerate -> インデックス番号(i)とデータ(entry)を一緒にgetできる関数。 # entry.get_text() -> entryの中にあるデータをテキストとして取得する。 for i, entry in enumerate(entries): schedule_list.append([i+1, entry.get_text()]) # with open(引数1, 引数2, encoding=引数3) as f: -> これまでに取得したデータを引数1の名前でcsvファイルに保存する。 # (引数1) -> 保存するファイル名を入力する。 # (引数2) -> 書き込みモード。新規作成なら"x", 末尾に追記なら"a"。 # (引数3) -> エンコード。windowsだと"cp932"じゃないとエラーが出る。原因は不明。 with open("schedule_data.csv", "w", encoding="cp932") as f: writer = csv.writer(f, lineterminator="\n") writer.writerows(schedule_list) if __name__ == "__main__": main() |
そして、csvファイルに出力されたデータを確認してみます。ここまで問題なくできると以下のようにデータが出力されます。


これで終了です。お疲れ様でした。
さいごに
今回は、スクレイピング初心者の方にもわかるように、BeautifulSoupを使ってウェブサイトからデータスクレイピングする方法を紹介しました。
副業でデータ分析や企業案件でスクレイピングをする機会は増えていますので、他の人に負けないように、基礎を身に着けておくようにしましょう。
今回スクレイピングについて紹介しましたが、クローラーを言うものも頻繁に使用されます。こちらについては後日記事を書きたいと思いますので待っていていください。
また、今回参考にした書籍を以下に貼っておきますので、気になる方はぜひ読んでみてください。


それでは~