KURORO BLOGのロゴ

このエントリーをはてなブックマークに追加
【初心者向け】Python x bs4を使って小説情報を取得してみる

【初心者向け】Python x bs4を使って小説情報を取得してみる

今回はPython x bs4を用いて、小説情報をcsv形式で取得します。データの取得方法がわからない、情報分析したいのにうまく扱えない。。そんな方々におすすめです。ぜひ最後までお読みいただけますと幸いです。

目次
  1. 用意するもの
  2. アーキテクチャ
  3. 青空文庫とは?
  4. 実行手順
    1. ローカル環境上にファイルを置く
    2. Pythonを実行してみる
  5. よくわかるコード解説
  6. 今日のまとめ
  7. こんなことにもチャレンジしてみよう
  8. 参考文献
目次を開く⬇︎

執筆者 - おすすめの記事2選

用意するもの

  • ローカルにてPython環境が叩ける状態であること(ターミナルにてpython -Vでバージョンが表示されていること)
  • pipが入っていない場合はpipを入れておく(Python 3.4以降では標準で入っている。参考)
  • コードを編集する、個人に合うエディタが使える状態であること(おすすめはVsCode)

アーキテクチャ

青空文庫とは?

青空文庫は、図書館のような書籍の数々を「インターネットで公開できる本」に仕立て、コンテンツ制作を行っています。

著作権の消滅した作品と、「自由に読んでもらってかまわない」とされた作品を、電子化(インターネットで公開できる形)した上で揃えている。

今回は、こちらで掲載されている小説情報を取得させていただきます。

実行手順

上記のアーキテクチャを見ただけではわからない部分も多々あるかと思います。まずは以下の手順を踏まえて、ローカル環境(自身のパソコン)にて実装してみましょう。

ローカル環境上にファイルを置く

以下の作業は、私の方で実際に作成したコードを、自身のパソコンへファイルを置く作業になります。

  1. こちらのページに訪問ください。
  2. 緑の「Code」と書かれているボタンをクリックして、 「Download ZIP」をクリックください。
  3. ダウンロードしたZipファイルをドラック&ドロップを使って、デスクトップへファイル移動して下さい。
  4. Zipファイルを展開するために、デスクトップに置いた先ほどのファイルをダブルクリックして下さい。

Pythonを実行してみる

必要なパッケージ(Pythonを実行する際に汎用的に使われるコード群)をインストールして、Pythonを実行します。

  1. ターミナルを開いて、analyticsTakuboku-masterのディレクトリへ移動します。(cdを利用する。)
  2. ターミナル上でpip install -r requirements.txt と入力する。(analyticsTakuboku-masterディレクトリ内にrequirements.txtファイルを用意していて、ファイルを実行するために必要なパッケージ情報を記載しています。その情報を元に自身のパソコン内へパッケージを格納しています。)
  3. お好みのエディタを開いて、analyticsTakuboku-masterのディレクトリ内にあるsetData.pyファイルを編集します。最終行にあたるdfDoc.to_csv('./data.csv') の箇所をdfDoc.to_csv('./test.csv')へ変更ください。
  4. 最後にpython setData.pyを実行すると、少し時間がかかりますが石川啄木の小説情報を取得できます。処理が完了すると、analyticsTakuboku-masterのディレクトリ内にtest.csvファイルができるので、内容を確認ください。以下の表のような形式で表示されます。
作品名本文
0作品名1本文1
1作品名2本文2
2......

よくわかるコード解説

以下のコードは、作品のタイトル、本文を取得する関数です。

  • articleId : 作品IDを仮引数とする。
  • time.sleep(3) を使って、3秒間処理を遅延させる。これは用意されるAPIに対して集中的にアクセスし、提供者側のサービス運営を阻害する行為を防ぐためです。(DOS攻撃とは?)
  • 作品IDを使って、作品詳細ページへ訪問する。
  • bs4を活用して、htmlの切り出しを行う。
  • タイトル、本文を返却する。

で構成されています。

1# 作品詳細ページへアクセスして、html形式で情報を取得する
2def getText(articleId):
3    # api接続を頻繁に行うことで障害を与えないためにも一定時間を置きながら、アクセスする。
4    # DOS攻撃とは? : https://www.shadan-kun.com/blog/measure/2160/
5    time.sleep(3)
6    # 青空文庫APIについて : https://qiita.com/ksato9700/items/626cc82c007ba8337034
7    res = requests.get("http://pubserver2.herokuapp.com/api/v0.1/books/" + str(articleId) + "/content?format=html")
8    soup = BeautifulSoup(res.content, "html.parser")
9    title = soup.find("title").text
10    # div要素内のmain_textとして書かれている文章を抽出する。
11    doc = soup.find("div", {"class" : "main_text"}).text
12    return title, doc

以下のコードは、記事一覧情報から作品ID一覧を取得する関数です。作品一覧ページを確認するとわかりますが、同じ作品でも「新字旧仮名」、「旧字旧仮名」、「新字新仮名」として作品が紹介されています。今回は「新字新仮名」のみ扱うことにしました。

findall関数を使って、記事一覧情報内に含まれる新字新仮名、作品ID:{数字}に該当する値を全取得します。[新字新仮名、作品ID:111, 新字新仮名、作品ID:222, ...]形式で値が格納されるので、for文を回して文字列(新字新仮名、作品ID:{数字})に対してsplit関数を利用し、作品IDだけ抽出するようにします。

1# 記事一覧情報から作品IDを取得する
2def getArticleIdList(articleList):
3    # 新字新仮名のみを扱う。
4    # [新字新仮名、作品ID:111, 新字新仮名、作品ID:222]みたいな形で入ってくる。
5    idList = re.findall("新字新仮名、作品ID:[0-9]+", articleList)
6    # 配列内の作品IDだけを取得するために、:区切りで配列にしてindexが1番目の要素を取得するようにする。
7    # そして再度配列を生成して格納していく。
8    return [id.split(":")[1] for id in idList]

以下のコードは、PandasDataFrameを活用して、API経由で取得したデータを扱いやすい形式に変更して、to_csv関数を用いることでファイル名に合うcsvファイルを生成しております。

1if __name__ == "__main__":
2    # ...
3    # ...
4
5    # DataFrame : https://ai-inter1.com/pandas-dataframe_basic/
6    dfDoc = pd.DataFrame(docList, columns=["作品名", "本文"])
7    # data.csvとしてcsv吐き出し
8    # ※ data.csvに格納されているデータを、ローカルにて検証するために利用します。2次利用はしません。
9    dfDoc.to_csv('./test.csv')

今日のまとめ

  • bs4を活用することで、簡単に欲しい情報を整形できる。
  • サービス運営を阻害しないためにも、APIアクセス頻度に注意する。
  • Pandasのto_csv関数を活用することで、容易にcsvファイルを生成できる。

こんなことにもチャレンジしてみよう

  • その他のAPIも叩いてみよう。(NewsAPI, SpotifyApi)
  • bs4の整形方法を変えて、その他のhtml要素を取得してみよう。

参考文献

記事に関するお問い合わせ