ギャン・バギャム・ソルドン

一打粉砕に怒喝の心力を込め、万物を叩き割る剛剣の刃を生み出さん

はてなブログAPIを叩いて記事の本文をtxtに出力する(Python)

はてなブログAPIについてちょっとだけ学んだので備忘録を残しておきます。

自分のブログ記事全ての本文を「記事タイトル.txt」ファイルとして出力することを目指します。

簡単な処理の流れは以下。

APIのルートエンドポイントと認証のに必要なAPIキーを設定
APIを叩いて10記事分の記事情報をXML形式で取得
XMLだと扱いにくいので、辞書を経由してjsonに変換、一度ファイルとして出力
jsonファイルを読み込んで、必要な情報(タイトル、本文、カテゴリ)を取得
⇒カテゴリ名のフォルダを作成し、その配下に「タイトル.txt」を出力
⇒次の記事10件の情報を取得する為に、ルートエンドポイントを更新
⇒更新したエンドポイントを再び叩いて記事情報を取得、異常の手順でtxtに出力
⇒全ての記事を出力するまで繰り返す

 

という感じ。実際のコードは以下。

・コード

import requests
import json as js
import xmltodict
import os

# api のエンドポイントurl を引数にとってxmlを返す関数を定義
def get_hatena_response(url):
key = 'XXXXXXXXXX' #各自のapiキー
# Basic認証でapiを叩く為に、ログインidapiキーをタプルに格納
auth = ('kiui_4', key)
# apiを叩いて返ってきたxmlを返す
r = requests.get(url, auth=auth)
return r

# xml のデータを受け取ってjson ファイルを出力する関数を定義
def xml_to_json(xml):
# xmlを辞書に変換する
dict = xmltodict.parse(xml.text)
# 辞書データをjsonに変換する
json = js.dumps(dict, indent=1)
# 変換したjsonをファイルに書き込む
with open('hatena_response.json', 'w') as fw:
fw.write(json)
fw.close()

# json ファイルを見て記事を出力する関数を定義
def write_hatenablog():
# jsonファイルを開いて読み込む
json_open = open('hatena_response.json', 'r')
json_load = js.load(json_open)

# 次のapiエンドポイントを変数に格納する
next_url = json_load['feed']['link'][1]['@href']

# apiで返された10件の記事について、txtファイルに書き込む
for i in range(len(json_load['feed']['entry'])):
# タイトルと本文を変数にする。ファイル名に使えない記号は置換する
title = json_load['feed']['entry'][i]['title'].replace('/', '_').replace('\"','')
main = str(json_load['feed']['entry'][i]['content']['#text'].replace('<p>', '').replace('</p>', ''))
# カテゴリごとにファイルを生成する
try:
category = json_load['feed']['entry'][i]['category'][0]['@term']
os.makedirs(category, exist_ok=True)
# カテゴリの無い記事は その他 ディレクトリとする
except:
category = 'その他'
os.makedirs(category, exist_ok=True)

# カテゴリフォルダ配下に タイトル.txt ファイルを生成し、本文を書き込む
with open(category + '\\' + title + '.txt', 'w', encoding='UTF-8') as fw:
fw.write(main)
fw.close()
# 次のapiエンドポイントは必要なので返す
return next_url

# api のエンドポイントの url を受け取って、記事を出力する関数を定義
def all_process(url):
xml = get_hatena_response(url)
xml_to_json(xml)
next_url = write_hatenablog()

return next_url

#-------------------- メインの処理 ----------------------------------------
if __name__ == '__main__':
# 最初のapiエンドポイントを設定
first_url = 'https://blog.hatena.ne.jp/kiui_4/kiui-4.hatenablog.jp/atom/entry'
# 最初も10件をtxt化、次のエンドポイントを変数へ
next_url = all_process(first_url)

# 次のエンドポイントが出力できる限り繰り返す
while True:
next_url = all_process(next_url)
# 次のエンドポイントが出なくなったらプログラムを抜ける
if next_url == 'https://kiui-4.hatenablog.jp/':
break
# ---------------------- 終了 ------------------------------------------

・出力
f:id:kiui_4:20200919091351p:plain

f:id:kiui_4:20200919092046p:plain

f:id:kiui_4:20200919091856p:plain
いい感じにできた。