【Python基礎】BeautifulSoup:xmlの解析

  • URLをコピーしました!
目次

BeautifulSoup

前回、Webページ解析ライブラリBeautifulSoupを使って、本文の取得を行いました。

今回はhtmlファイルではなく、たまに出てくる「xmlファイル」を解析する方法を試していきましょう。

まずは試しに用いるxmlファイルを用意します。

xmlファイルはあまり聞き慣れないので、どこにあるのか知らない方も多いかもしれませんが、例えばブログではRSS(Rich Site Summary)として、ウェブサイトの要約や記事の見出しなどを配信するために用いられています。

つまりxmlファイルが解析できれば、そのサイトの新着の情報を解析できるようになるわけです。

例えば3PySciの場合は右上のWiFiマークが横になったようなマークがRSSのページです。

開いてみるとこんな感じのページになります。

このxmlファイルにはブログ全体の概要と新着10件の記事の情報が記載されています。

このページを手動でダウンロードしてもいいですし、urllibを使ったこんな感じのプログラムでダウンロードしてもいいでしょう。

import urllib

url = 'https://3pysci.com/feed/'
html_out = './feed.xml'

urllib.request.urlretrieve(url, html_out)

とりあえずローカル(PC上)にダウンロードできれば準備完了です。

今までの方法を試してみる

ダウンロードしたファイルは「xmlファイル」なのですが、まずはそれを意識せず、これまでやってきたBeautifulSoupの使い方で解析してみましょう。

from bs4 import BeautifulSoup
import os

inputfile = './feed.xml'

with open(inputfile, 'r') as f_in:
    soup = BeautifulSoup(f_in)
    print(soup)

実行結果
<?xml version="1.0" encoding="UTF-8"?><html><body><rss version="2.0" 
xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" 
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" 
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" 
xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<title>3PySci</title>
<atom:link href="https://3pysci.com/feed/" rel="self" type="application/rss+xml"></atom:link>
<link/>https://3pysci.com
	<description>大人のためのSTEM遊び場〜Python、3Dプリンタ、ガジェット〜</description>
<lastbuilddate>Thu, 14 Apr 2022 12:39:45 +0000</lastbuilddate>
<language>ja</language>
<sy:updateperiod>
	hourly	</sy:updateperiod>
<sy:updatefrequency>

普通に読み込んで、BeautifulSoupに渡した状態では問題なく読めているように見えます。

ここでfind_all関数を使って、xmlでのリンクの要素である「<link>」を探してみましょう。

from bs4 import BeautifulSoup
import os

inputfile = './feed.xml'

with open(inputfile, 'r') as f_in:
    soup = BeautifulSoup(f_in)
    for link in soup.find_all('link'):
        print(link)

実行結果
<link/>
<link/>
<link/>
<link/>
<link/>
<link/>
<link/>
<link/>
<link/>
<link/>
<link/>
<link/>

「link」という文字を検索しただけのようにも見えますが、実際はそうでもなく、「<link/>」を一つのタグとして認識してしまっている、すなわち認識が間違っている状態で検索しています。

このままではちゃんと解析できないので、まずは読み込むファイルをxmlファイルだと認識させてみましょう。

ファイルフォーマットの指定

ファイルフォーマットの指定はBeautifulSoupで解析する際にオプションとして指定します。

つまり「soup = BeautifulSoup(f_in)」で「soup = BeautifulSoup(f_in, ‘lxml-xml’)」というように「’lxml-xml’」をオプションに追加してやることで読み込むファイルはxmlファイルだと認識させることができます。

試してみるとこんな感じです。

from bs4 import BeautifulSoup
import os

inputfile = './feed.xml'

with open(inputfile, 'r') as f_in:
    soup = BeautifulSoup(f_in, 'lxml-xml')
    for link in soup.find_all('link'):
        print(link)

実行結果
<atom:link href="https://3pysci.com/feed/" rel="self" type="application/rss+xml"/>
<link>https://3pysci.com</link>
<link>https://3pysci.com</link>
<atom:link href="https://pubsubhubbub.appspot.com" rel="hub"/>
<atom:link href="https://pubsubhubbub.superfeedr.com" rel="hub"/>
<atom:link href="https://websubhub.com/hub" rel="hub"/>
<link>https://3pysci.com/bootstrapstudio-21/</link>
<link>https://3pysci.com/bootstrapstudio-20/</link>
<link>https://3pysci.com/bootstrapstudio-19/</link>
<link>https://3pysci.com/dx-1/</link>
<link>https://3pysci.com/bootstrapstudio-18/</link>
<link>https://3pysci.com/bootstrapstudio-17/</link>
<link>https://3pysci.com/bootstrapstudio-16/</link>
<link>https://3pysci.com/python-matplotlib-34/</link>
<link>https://3pysci.com/bootstrapstudio-15/</link>
<link>https://3pysci.com/bootstrapstudio-14/</link>

ファイルフォーマットを指定しなかった時とは違いリンクの情報を取得できました。

ちなみに取得できた要素は「link」と「atom:link」の2種類があるようで、違いはよくわかりませんが、「atom:link」は埋め込み(表示されない)型のリンクで、「link」は通常の表示されるリンクではないかと思われます。

ちなみに「<link>…</link>」で囲まれた中身(上記の場合はリンク先のURL)を取得したい場合は、htmlファイルを解析した時と同様「getText関数」が使用できます。

from bs4 import BeautifulSoup
import os

inputfile = './feed.xml'

with open(inputfile, 'r') as f_in:
    soup = BeautifulSoup(f_in, 'lxml-xml')
    for link in soup.find_all('link'):
        print(link.getText())

実行結果

https://3pysci.com
https://3pysci.com



https://3pysci.com/bootstrapstudio-21/
https://3pysci.com/bootstrapstudio-20/
https://3pysci.com/bootstrapstudio-19/
https://3pysci.com/dx-1/
https://3pysci.com/bootstrapstudio-18/
https://3pysci.com/bootstrapstudio-17/
https://3pysci.com/bootstrapstudio-16/
https://3pysci.com/python-matplotlib-34/
https://3pysci.com/bootstrapstudio-15/
https://3pysci.com/bootstrapstudio-14/

xmlファイルの癖

上記のように解析できたら後はhtmlファイルと同じ感覚で解析できると思いますが、ちょっと癖があるなと思ったのは繰り返しの情報に関してです。

今回解析に用いているRSSのxmlファイルでは10件の新着記事が記載されています。

そしてこれらの情報はまず「item要素」でそれぞれ囲まれています。

つまりこんな感じです。

<item>
記事1の情報
</item>
<item>
記事2の情報
</item>
<item>
記事3の情報
</item>
...

そのため各記事の情報を取得するにはまずitem要素を取得し、そこから詳細の情報を取得することになります。

そのため各記事のタイトルを取得するとこんな感じになります。

from bs4 import BeautifulSoup
import os

inputfile = './feed.xml'

with open(inputfile, 'r') as f_in:
    soup = BeautifulSoup(f_in, 'lxml-xml')
    item_list = soup.find_all('item')
    for item in item_list:
        print(item.title.getText())

実行結果
Bootstrap Studioを使って作成した漢字間違い探しクイズのページをDjangoに移植してみる その19:Djangoで作成したフォームのサイズを揃える
Bootstrap Studioを使って作成した漢字間違い探しクイズのページをDjangoに移植してみる その18:make.htmlの数字と文字入力用フォームの修正
Bootstrap Studioを使って作成した漢字間違い探しクイズのページをDjangoに移植してみる その17:make.html用のforms.pyの作成とviews.pyの修正
Pythonで始めるなんちゃってDX その1:表の項目を抽出するプログラム
Bootstrap Studioを使って作成した漢字間違い探しクイズのページをDjangoに移植してみる その16:play.htmlでランダムな問題が出題されるようにする
Bootstrap Studioを使って作成した漢字間違い探しクイズのページをDjangoに移植してみる その15:index.htmlの動画と背景画像のリンクの修正
Bootstrap Studioを使って作成した漢字間違い探しクイズのページをDjangoに移植してみる その14:準備編
Matplotlibのグラフ表示に日本語を使えるようにしてみる
Bootstrap Studioを使って、漢字間違い探しクイズのHTMLを作成してみる その13:SEOの設定
Bootstrap Studioを使って、漢字間違い探しクイズのHTMLを作成してみる その12:about.htmlの作成

前回までにやってきたhtmlファイルだと例えば見出しタグを取得して、そこから選別することになるでしょう。

ですがxmlファイルだと特定の情報がまとまっている(上記の場合だと記事毎)ため、解析がしやすいと感じました。

また特定のサイトではサイト内の検索結果がxmlファイルでダウンロードできるようになっており、情報の受け渡しがしやすいファイル形式であるようです。

例えばデジタル庁が運営している「e-Govポータル」にある「法令検索」では法令データがxmlファイルでダウンロードできるようになっています。

また気象庁では防災情報を、国土交通省では国土の数値データをそれぞれxmlファイルでダウンロードできるようです。

ということでxmlファイルの解析方法を知っておくと、こういった情報を独自に解析できるので、知っておくといざという時に役立ちそうです。

ということでBeautifulSoupの使い方に関してはこんな感じで、また役に立ちそうなことがあれば随時記事にしていこうと思います。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次