In this Article
データは、単純なCSVテーブルやJSONオブジェクトから、より説明的で階層的なXMLドキュメントまで、さまざまな形式で存在します。XMLは少し時代遅れに見えるかもしれませんが、RSSフィード、API、ソフトウェア構成など、いたるところに今でも使われています。
XMLデータを使用する前に、それを解析する必要があります。言い換えれば、プログラムが中身を読み取れるようにすることです。ElementTree、minidom、lxmlなどのPythonのライブラリを使用すると、XMLの解析は明確で直感的なプロセスになります。
どのようなデータ形式に遭遇しても、特にXMLなどのデータ形式の操作方法を学ぶことは、開発者にとって必須のスキルです。 このガイドでは、XMLからデータを読み取り、要素をたどり、データを抽出する方法を段階的に解説します。
XMLの基本
XMLは「拡張可能マークアップ言語」の略で、データの保存と転送のための汎用形式です。その構造により、機械で処理しやすく、人間にも読みやすい構造になっています。この言語は、シンプルさ、拡張性、幅広い用途を重視して設計されています。
XMLはツリー構造として捉えると分かりやすいでしょう。枝と葉のある実際の木と同様に、ルートとネストされた子要素があります。この構造は、XMLがデータを階層的に整理する仕組みを表しています。Pythonは、XMLデータを処理するためのさまざまな方法を提供しており、ElementTreeモジュールは最も一般的な選択肢の 1 つです。ElementTreeモジュールには、ドキュメント全体を表すElementTreeと、個々のノードを表す Element という 2 つの主要なクラスが含まれています。
開発者がXMLを解析する方法: 主な手法
Pythonでは、 parse()関数は通常、XMLファイルを処理するための最初の手順です。XMLドキュメントを処理し、プログラムでナビゲートできるツリー構造に変換します。この関数は、ElementTree、lxml、または他のライブラリを利用しているかどうかに関係なく、さまざまな解析方法の基礎として機能します。
解析方法を理解するには、まずXMLファイルの要素を知る必要があります。
- 名前空間 – 要素と属性の名前を修飾することで、名前の競合を回避します。
- ルート要素 – 他のすべての要素を含む主要なコンテナ。
- 属性 – 要素に関する追加情報を提供するキーと値のペア。
- 子要素 – データを階層的に編成するネストされた要素。
- テキストの内容 – 要素内に含まれる実際の情報。
これらの要素は、プログラムが複雑なデータを保存および共有できるようにする構造化された形式を作ります。構造を理解した後、Pythonで使える主なXML解析手法を見ていきましょう。
1。ElementTreeモジュール
XMLツリーを探索するための使いやすいAPIを備えたPythonの組み込みライブラリ。使いやすさとパフォーマンスのバランスが取れているため、ほとんどのタスクに最適です。
2。lxml
XPath、XSLT、および検証のサポートを含むサードパーティライブラリ。ElementTreeよりも高速で、より多くの機能を備えています。複雑なXML処理に最適です。
3。DOM (ドキュメントオブジェクトモデル)
これにより、完全なXMLドキュメントがツリー構造としてメモリにロードされます。要素の操作や変更は簡単ですが、ファイルが大きい場合はメモリを大量に消費する可能性があります。
4。SAX (XMLの場合は単純なAPI)
XMLを順次処理するイベント駆動型パーサー。メモリ使用量の点では効率的で、大きなファイルの処理も高速ですが、複雑な処理にはやや扱いにくい場合があります。
5。Untangle
簡単にアクセスできるように、XMLデータをPythonオブジェクトに変換します。最小限のコードで素早い解析を行うのに最適です。ただし、複雑なXML構造にはあまり向きません。
このチュートリアルで必要なものは…
- PythonとRequests
Python3.xがコンピュータにインストールされていない場合は、次からダウンロードできます。 https://www.python.org/。ターミナルを開き、pip を使用してRequestsをインストールします。
pipインストールリクエスト または pip3 インストールリクエスト
- Visual Studio Code(VS Code)
必要なコマンドをすべて実行するには、Visual Studio Code(VS Code) のターミナルを使用できます。公式サイトからダウンロードし、 公式ウェブサイトの案内に従って、お使いのオペレーティングシステムにインストールしてください。
- RSSフィード
RSSフィードは、Web サイトからニュースや更新情報を自動的に配信するために使用される特別なXMLファイル形式です。簡単に言えば、プログラムが読み取れるように構造化された「最新の投稿のリスト」のようなものです。
たとえば、当社のWebサイトにはチュートリアルのセクションがあります。毎日サイトをチェックして新しいチュートリアルが公開されているかどうかを確認する代わりに、サイトはRSSフィード (最近のすべての投稿に関する情報を含むXMLファイル) を提供します。ここでは DataImpulseRSSフィード をチュートリアル用に使用します。必要なライブラリとコードを見ていきましょう。
ElementTree
Pythonの組み込みElementTreeモジュールを使用して、RSSフィードからのXMLデータを解析する方法を見てみましょう。
まず、xml.etree.ElementTreeをインポートします。GETリクエストをRSSフィードのURLに送信すると、サーバーはXMLデータで応答します。レスポンスの.content属性から、、ElementTreeが解析できる生のバイト データが得られます。ET.fromstring()を使うと、このXMLデータをツリー構造に変換し、ルート要素を取得します。RSSフィードでは、ほとんどのコンテンツが次の要素内に整理されています。 <channel> → <item> 要素。
の find() メソッドは最初に一致した要素を返しますが、findall() は指定されたタグを持つすべての子要素を返します。ここで、itemsはすべてのitem要素のリストであり、それぞれがチュートリアルまたは記事を表します。
コードの例:
import xml.etree.ElementTree as ET
import requests
# URL of the RSS feed (from DataImpulse site)
FEED_URL = "https://dataimpulse.com/tutorials-category/web-scraping-seo/feed/"
# Download the XML data
response = requests.get(FEED_URL)
xml_data = response.content
# Parse the XML
root = ET.fromstring(xml_data)
# In RSS feeds, items are inside -
channel = root.find("channel")
items = channel.findall("item")
# Print titles and links of the items
for item in items:
title = item.findtext("title")
link = item.findtext("link")
print(f"Title: {title}")
print(f"Link: {link}\n")
最後に、各項目のタイトルとリンクを findtext()で直接取得して出力します。スクリプトを実行すると、すべてのチュートリアルのタイトルとその URL が整然と表示されたリストが表示されます。
lxml
lxmlは、ElementTreeの機能を拡張し、XMLドキュメントをナビゲートするためのクエリ言語であるXPathのサポートを追加する外部ライブラリです。この例では、 lxml.etreeを使ってRSSフィードを解析し、投稿タイトルを抽出します。
まず、requests.get()を使って、先ほどと同様にRSSフィードを取得します。レスポンスの内容をetree.fromstring()に渡すと、XMLが解析され、、ルート要素を返します。lxmlでは、XPath式を使用して要素を検索できます。標準のElementTreeメソッドよりも柔軟に要素をたどれるためです。
import requests
from lxml import etree
# URL of the RSS feed
FEED_URL = "https://dataimpulse.com/tutorials-category/web-scraping-seo/feed/"
# Download the XML data
response = requests.get(FEED_URL)
xml_data = response.content
# Parse XML
root = etree.fromstring(xml_data)
items = root.xpath("//channel/item")
# Show list of titles with numbers
print("Available blog posts:\n")
for item in items:
title = item.findtext("title")
print(title)
最後に、 <item> 要素ごとにfindtext(“title”)を使って投稿タイトルを抽出し、出力します。
Minidom
この例では、MinimalDOMImplementation の略であるMinidomを使用しています。これはPythonの標準ライブラリの一部であり、XMLドキュメント全体をドキュメント オブジェクト モデル (DOM) としてメモリにロードすることで機能します。
ここでは、minidom.parseString()でXMLを解析し、DOMオブジェクトを構築します。 DOM。主に使うDOMメソッドは 2 つです。 1つ目は getElementsByTagName(“tag”,) は、指定したタグ名を持つすべての要素を検索します。もう一方の .firstChild.nodeValue ノードのテキストコンテンツを取得します。
最後に、私たちが使用するのは、 toprettyxml(). は、最初のitem要素を整形されたXMLとして出力するために使います。
Minidomを使用してRSSフィードのデータを解析する方法は次のとおりです。
import requests
from xml.dom import minidom
# URL of the RSS feed
FEED_URL = "https://dataimpulse.com/tutorials-category/web-scraping-seo/feed/"
# Download XML data
response = requests.get(FEED_URL)
xml_data = response.content
# Parse XML with minidom
doc = minidom.parseString(xml_data)
# Get all - elements
items = doc.getElementsByTagName("item")
print(f"Total articles found in feed: {len(items)}\n")
# Show titles with links
for i, item in enumerate(items, start=1):
title = item.getElementsByTagName("title")[0].firstChild.nodeValue
link = item.getElementsByTagName("link")[0].firstChild.nodeValue
print(f"{i}. {title}")
print(f" Link: {link}\n")
# Show raw XML of the first
- (just for demo)
print("First
- as raw XML:\n")
print(items[0].toprettyxml())
SAX
SAXは、XMLを要素ごとに順番に読み取ります。XMLの各部分に応じて特定のイベントを発生させます。
- startElement(name, attrs) →タグが始まるとき
- characters(content) → タグ間でテキストを読み込む場合
- endElement(name) →タグが終了したとき
コードをファイルに保存して実行します。
import requests
import xml.sax
# Custom handler for SAX parsing
class RSSHandler(xml.sax.ContentHandler):
def __init__(self):
super().__init__()
self.current_tag = ""
self.in_item = False
self.title = ""
self.link = ""
self.counter = 0
def startElement(self, name, attrs):
if name == "item":
self.in_item = True
self.title = ""
self.link = ""
self.current_tag = name
def characters(self, content):
if self.in_item:
if self.current_tag == "title":
self.title += content
elif self.current_tag == "link":
self.link += content
def endElement(self, name):
if name == "item":
self.counter += 1
print(f"{self.counter}. {self.title.strip()}")
print(f" Link: {self.link.strip()}\n")
self.in_item = False
self.current_tag = ""
# Download the XML feed
FEED_URL = "https://dataimpulse.com/tutorials-category/web-scraping-seo/feed/"
response = requests.get(FEED_URL)
xml_data = response.content
# Parse XML with SAX
print("Parsing RSS feed with SAX...\n")
handler = RSSHandler()
xml.sax.parseString(xml_data, handler)
print(f"Total items parsed: {handler.counter}")
この方法はドキュメント全体をメモリに保持しないため、メモリ効率に優れています。
Untangle
Untangleは、XMLをより手軽に処理できる方法です。Untangleライブラリは、XMLドキュメントをPythonオブジェクトに変換します。これは、手動による要素の走査やイベント処理が必要ないことを意味します。
untangle.parse()でXMLを解析すると、自動的にXMLファイルを読み取り、すべてのXMLタグをPythonオブジェクトに変換し、タグのデータを.cdata 属性から取得できます。ノードやイベントを操作する代わりに、通常のPythonオブジェクトのようにXML構造をナビゲートするだけです。
コードは次のとおりです。
import requests
import untangle
from io import BytesIO
# RSS feed from DataImpulse
FEED_URL = "https://dataimpulse.com/tutorials-category/web-scraping-seo/feed/"
# Download XML
resp = requests.get(FEED_URL)
resp.raise_for_status()
xml_bytes = resp.content
# Parse XML with untangle (use BytesIO for bytes input)
doc = untangle.parse(BytesIO(xml_bytes))
# Get all - elements
items = doc.rss.channel.item
print("Articles from DataImpulse RSS:\n")
# Print articles
for i, it in enumerate(items, start=1):
title = it.title.cdata if hasattr(it, "title") else ""
link = it.link.cdata if hasattr(it, "link") else ""
desc = it.description.cdata if hasattr(it, "description") else ""
print(f"{i}. {title}")
print(f" Link: {link}")
if desc:
print(f" Description: {desc}")
print()
いくつかの追加の推奨事項
- 解析時のエラーを確認する
フィードが利用できない場合や、予期しないタグが含まれている場合があります。このような場合は、XMLをダウンロードまたは解析するときに try/except を使用してください。
- .contentをXMLのダウンロードに使う
.content 属性は生のバイト データを返し、エンコードの問題を防ぎます。 .text 属性では文字エンコーディングの問題が起きる可能性があります。
- 要素が存在することを確認する
すべてのXMLファイルが同じ構造を持つわけではありません。タグにアクセスする前に、if item.find(‘title’) is not Noneのような条件で存在を確認してください。
- 大きなファイルのリソース使用量に注意する
巨大なXMLドキュメントの場合は、すべてをメモリにロードせずにデータを順番に読み取るSAXを使用します。
外部サイトからXMLを取得するのは面倒な場合があります。プロキシは、複数の地域から安定してアクセスし、プライバシーを保護するのに役立ちます。
主なハイライト
- XMLの解析は、XMLファイルを読み取り、構造化された利用しやすい形でデータを抽出するプロセスです。
- ElementTreeは、XML要素をナビゲートして抽出するためのツリー構造に基づく方法を提供します。
- lxmlは、XML解析を高速化するためのXPathクエリをサポートするライブラリです。
- Minidomは、XML全体をDOMツリーとしてロードし、構造化されたオブジェクトとしてノードとテキストにアクセスできるようにします。
- SAXは、メモリ内にすべてを保持せずにXMLを段階的に処理するため、大きなXMLファイルに最適です。
- Untangleは、タグとそのコンテンツに簡単にアクセスできるように、XMLをPythonオブジェクトに変換します。
関連記事
Pythonとプロキシを使用してeBayをスクレイピングする方法
