有給医のライフハック記録

医師の語る人生最適化戦略

はてなブログ記事をテキストファイルに一括保存するプログラムを製造【pythonプログラミング】

はてなブログの月別の記事をテキストファイルに一括保存するプログラム

自然言語処理機械学習のために、普段書いている僕のブログ(まさにこのブログ)の記事を取得するpythonスクリプトを作成しました。精度のよい学習をさせるにも、大量のテキストデータが必要で。せっかくこうやってブログをやっていることですし、自分の著作物を使わない手はないわけです。

いままで、せっせと手作業でコピペして、ご丁寧に何故かWordファイルに蓄えていたのです。ですがWordファイルのままですと、のちのちpythonスクリプトでデータとして使用するのが一般的ではないため(出来ないこともないが)、改めてテキストファイル形式でデータが欲しくなりました。

最近はスクリプトを作る暇もなく多忙だったので、練習がてら、はてなブログをターゲットにHTML解析し、テキストを取得することにしました。

今回は大規模なスクリプトではなく、あくまで特定の月(2021年12月にしました)の特定量だけ、取得することにしています。そんなに大量のデータは欲していませんので。

もちろん、他の人のブログもベースは同じHTMLになっているので、コードのURLを変えれば、うまく取得できるハズです。


イメージする挙動

pythonのrequestsおよびbs4モジュールを使い、HTMLをパースする。
・特定の月のアーカイブであれば、その月の記事一覧を取得できる。
・h1タグをターゲットとし、記事リンクをたどる。
・記事リンクを個別にたどり、コンテンツを一括してテキストファイルに保存する。

ソースコード

import requests
import bs4

res = requests.get('https://kataroh.hatenablog.com/archive/2021/12')

try:
	res.raise_for_status()
except Exception as exc:
	print("問題あり:{}".format(exc))

page_soup = bs4.BeautifulSoup(res.text,'lxml')

h1_list = page_soup.find_all("h1") #h1タグをターゲットとした。

for list in h1_list[1:]:   #h1_list[0]はタイトルのため除外した。

	res_article = requests.get(list.a["href"])

	try:
		res.raise_for_status()
	except Exception as exc:
		print("問題あり:{}".format(exc))

	article_soup = bs4.BeautifulSoup(res_article.text,"lxml")
	print(article_soup.select(".entry-content")[0].text)

	with open("article.txt","a",encoding='UTF-8') as f:
		f.write(article_soup.select(".entry-content")[0].text)

	print("write success")

動作原理

上記コードの概要です。

ぶっちゃけ、僕のブログのURLは判明していますので、上記コード内のURLは隠していません。2021年12月のアーカイブのURLになっています。

前述のとおり、h1タグの要素を取得し、変数h1_listに代入しました。なお、やっていて判明したのですが、h1_list[0]は、まさに僕のブログのホームに飛んでしまい、イチイチ取得する意義に乏しいので、[1:]としてリスト0番を除外しています。

forループの内部で、取得したの"href"属性にアクセスし、記事の各ページに飛びました。

ややこしいのですが、さらにループ先でHTML解析し、コンテンツ内容を最終的にテキストファイルにまとめて保存しています。

上記のコードで、予定どおり12月の記事をすべて、一括保存できました。



これくらいの長さのコードで手作業を簡略化できるので、機械の言葉を使えると便利だな、と実感しました。



ぶっちゃけ、まったくコード自体に拡張性がなく、単純に保存するための目的で作りました。
暇が出来たら、もっと使いやすいように拡張するよう、改良します。

課題

・他の月への拡張
・次ページに渡るような量の月でも取得できるよう改造


語郎