Menu


Python BeautifulSoup を使い HTML を解析して結果を CSV に保存する

2021年07月28日
2022年11月22日

ホームページのHTMLを解析して、その結果をCSVで保存する方法をご紹介したいと思います。

今回HTMLの解析に使うホームページは当サイト「ICTよろず相談所」のトップページの新着情報一覧をサンプルとして解析に使用してみたいと思います(以下の画像赤枠箇所です)。

今回PythonでHTMLを解析する箇所

まずはPythonのプログラムファイルを作成しますので、どこか自分の都合の良い場所に python-kaiseki-ictyorozu.py というファイルを作成します(ファイル名は別名でもOKです)

python-kaiseki-ictyorozu.pyを任意の場所に作成

それでは早速ですがPythonのソースコードを記載します。

Pythonのソースコード

import requests
from bs4 import BeautifulSoup
import csv

dic = {}
num = 0

csv_midashi = ['日付', 'タイトル']
csv_export_path = '/path/to/python-kaiseki-ictyorozu_result_data.csv'

url = 'https://ict-yorozu.com/'
r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")

html_selects = soup.find('div', class_='css_tabs_body').find_all('div', class_='select')

for html_select in html_selects:
	
	html_as = html_select.select('.index_post > ul > li > a')
	column1 = column2 = ""
	for html_a in html_as:
		column1 = html_a.select('.index_post_date')[0].text
		column2 = html_a.select('.index_post_title')[0].text
		dic[num] = { csv_midashi[0]: column1, csv_midashi[1]: column2 }
		num+=1
				
with open(csv_export_path, 'w') as f:
	writer = csv.writer(f)
	writer.writerow(csv_midashi)
	for k in dic.values():
		writer.writerow(k.values())

result_message = str(len(dic)) + '件を処理しました。'
print(result_message)

ソースコードの解説

まず、今回 import にてライブラリとパッケージを読み込む宣言をします。

ライブラリのインポート

import requests
from bs4 import BeautifulSoup
import csv

今回使うライブラリは、requests、BeautifulSoup、csvとなりますが、お使いの環境にライブラリがインストールされていない場合は 「pip install ライブラリ」のようなコマンドでライブラリをインストールします。

ライブラリのインストール方法は公式のドキュメントをご確認ください。

変数定義

dic = {}
num = 0

csv_midashi = ['日付', 'タイトル']
csv_export_path = '/path/to/python-kaiseki-ictyorozu_result_data.csv'

今回は上記のように変数を定義しています。

  • dicは結果を入れるdictionary型の変数
  • numはdicに連番をつける際に使う変数
  • csv_midashiは今回取得する「日付」「タイトル」をあらかじめ入れておく配列を定義する変数
  • csv_export_pathはcsvデータを保存するcsvの絶対パスを定義する変数
    (csv_export_pathはcsvデータを保存する場所を絶対パスで指定してください)

となります。

requestsによるURLリクエストとBeautifulSoupオブジェクトの生成

url = 'https://ict-yorozu.com/'
r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")

一行目の url = ‘https://ict-yorozu.com/’ 解析するホームページのURLを指定し変数urlに格納します。

二行目のrequest.get(url)を 変数rに格納。

三行目で r.textを第一引数として、第二引数に”html.parser”を指定してBeautifulSoupオブジェクトを変数soupに格納します。

上記たったの三行で解析する準備は完了です。

変数soupをprint(soup)にて表示してみると、HTMLがパースされて表示されていると思います。

解析するHTMLを確認し結果を絞り込む

今回解析する箇所は「お知らせ」箇所ですので、その箇所のHTMLには「div.css_tabs_body」という親要素があり、子要素「div.select」が存在しますので、soup.findにて親要素css_tabs_bodyをclass指定し、さらにfind_allにてselectを指定して絞り込みました。

その結果をhtml_selectsに格納します。

html_selects = soup.find('div', class_='css_tabs_body').find_all('div', class_='select')

print(html_selects)にて確認すると、print(soup)した際のHTMLよりさらに絞り込んだHTMLの結果を確認する事ができます。

html_selectsに格納された結果をさらに絞り込んでいきます。

for html_select in html_selects:
	
	html_as = html_select.select('.index_post > ul > li > a')
	column1 = column2 = ""
	for html_a in html_as:
		column1 = html_a.select('.index_post_date')[0].text
		column2 = html_a.select('.index_post_title')[0].text
		dic[num] = { csv_midashi[0]: column1, csv_midashi[1]: column2 }
		num+=1

html_selects をforループにて繰り返し処理を行なっていきます。

お知らせ箇所は .index_post_date に日付、.index_post_titleにタイトルのそれぞれの内容が入っているのですが、それまでに親の階層があります。

その箇所までたどり着くのが html_select.select(‘.index_post > ul > li > a’) の箇所で絞り込み、html_asに格納しています。

さらに html_as をforループにて繰り返し処理して、お目当ての.index_post_date に日付、.index_post_titleにタイトルの内容をcolumn1、column2に格納します。

その内容をdic[num] = { csv_midashi[0]: column1, csv_midashi[1]: column2 }としてdictionary型の変数に格納していきます。

print(dic)を行うと、0 : {‘日付’ : ‘タイトル’ } … という形式で格納されているのがわかります。

CSVに書き出し

with open(csv_export_path, 'w') as f:
	writer = csv.writer(f)
	writer.writerow(csv_midashi)
	for k in dic.values():
		writer.writerow(k.values())

一行目の with open(csv_export_path, ‘w’) as f: にて(’w’を指定して)CSVファイルを書き込み用にオープンします。

二行目 writer = csv.writer(f) はCSVファイルに書き込むためのwriterオブジェクトを作ります。

三行目はwriter.writerow(csv_midashi)としてcsvファイルの一行目に日付、タイトルを追加しています。

四行目のdic.values()によるループ処理を行い、writer.writerow(k.values())として日付とタイトルをdictionary(配列)の数だけ書き込む処理をしています。

ここまでの内容を実行すると、csv_export_path にて設定した絶対パスに、csvファイルが生成されます。

生成されたpython-kaiseki-ictyorozu_result_data.csv

CSVデータをエクセルなどのファイル(今回はMacのNumbers)で開くと以下の通り、お知らせ箇所の内容がCSVとして書き出されました。

CSVに書き出されたお知らせ一覧

今回の例では日付とタイトルだけを抜き取りましたが、URLを追加するなどもできるでしょう。

一度BeautifulSoupでHTMLをパースするソースコードを作成しておくと、様々なHTML結果を絞り込みして取得する事ができるようになると思います。

ホームページから大量のデータを参照・取得している場合では特に便利になると思います。

以上ですが、PythonでHTMLを解析して結果をCSVに保存する方法をご紹介しました。

今回の例のように「データを取得・解析・結果の出力をしたい!」「業務の効率化を行いたい!」というご要望がございましたらご相談ください。よろしくお願い申し上げます。

広告