Pythonモジュールlxmlのxpathを使ってHTMLの要素取得する方法!【サンプルコード有り】

はじめに

前回はHTMLの内容から必要な要素を取り出す方法として正規表現を使う方法をご説明しました。正規表現は強力なマッチング機能で必要な内容を取り出せるのですが、記法が独特であり、正規表現を正しく覚えるだけでも一つのプログラミング言語を習得するのと同じくらいの労力を必要とします。

今回はPythonのモジュールであるlxmlに含まれるXpathを使ってHTMLから必要な要素を取り出す方法を考えます。Xpathとはマークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文です。詳しくは後ほどご説明しますが、HTMLの構造を例えばパソコンのファイルシステムのような階層構造と捉えて要素指定する方法です。

前回の正規表現と比べると、HTMLの階層構造を理解している人にとってはわかりやすいかもしれません。様々な方法を試して、自分に合う方法をぜひ見つけてください。

lxmlのxpathを使ってHTMLの要素取得する本記事の目的

HTMLはタグと呼ばれる<>←このような記法で階層を表現します。このタグの階層をたどって、目的の要素を取得するのが今回紹介するlxmlのxpathです。このタグは階層構造となっており、例えば、

<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>TITLE</title>
</head>
<body>
    <h1>見出し</h1>
    <p>コンテンツ</p>
    <a href="#">リンク</a>
  </div>
</body>
</html>

のようにhtmlタグの間にheadタグやbodyタグが挟まれる形となっており、またhead、bodyタグの間に各要素が挟まれる入れ子構造となっています。この構造を上からたどっていき目的の要素に到達するのがxpathです。本記事ではこのXpathを使ってHTMLからtitleの内容を取得するサンプルをご紹介いたします。

lxmlのxpathを使ってHTMLの要素取得する処理の流れ

それでは処理の流れを説明します!

lxmlからetreeをインポートする

まずはlxmlからetreeをインポートしましょう!同時にurllibからrequestもインポートしています。

指定のサイトからHTMLをダウンロードしてデコード

お決まりの処理です!

etreeのHTMLParserでHTMLを読み込んでxpathからtiteleを取得

本プログラムの本丸です!HTMLParserでHTMLを階層構造にして取り込みます。取り込んだ階層構造化したHTMLからXpathによってtitleを取得します。”./head/title”の部分がXpathの記法となりますが、これは 「一番上の階層→headタグ階層→title要素」 と、下の階層までたどっていることを意味します。

 

実行結果は以下です!

lxmlのxpathを使ってHTMLの要素取得するサンプルコード

それではサンプルコードです!

from urllib import request
from lxml import etree

html = request.urlopen('https://jidouka-labo.com/')
contents = html.read()

htmltxt = contents.decode()

et = etree.fromstring(htmltxt, parser=etree.HTMLParser())
title_element = et.xpath("./head/title")[0]
print(title)

おわりに

今回はXpathによる要素指定の方法をご紹介しました。前回の正規表現と比べると、階層構造を理解できる人なら早いかもしれません。HTMLの階層構造はそれほど複雑ではなく、比較的シンプルです。しかし、最近のWebサイトの構造の複雑化に伴い、シンプルであるはずのHTMLが複雑化しています。

複雑化の原因は、Webサイトをきれいに見せるために様々な修飾要素が入り交じる形となっているためです。例えばclassタグやdivタグと言ったcssによりWebサイトを修飾するタグが乱用され、一見ではよくわからない構造になっているサイトがたくさんあります。

これらのサイトから狙ったタグを見つけ出すのは至難の技ですが、chromeのデベロッパーツールなど、分析や検証のためのツールがありますので、これらの力を借りるとスクレイピングがよりスムーズに進むと思います。