HTMLパース完全ガイド!初心者も分かりやすい解説とサンプルコード10選

HTMLパースの基本を学ぶイメージ HTML
この記事は約20分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

HTMLパースは、ウェブ開発やデータ分析で欠かせない重要なスキルです。

この記事では、HTMLパースの基礎から応用まで、詳しく解説していきます。

初心者の方でも理解しやすいよう、段階的に説明していきますので、最後まで読み進めることで、実践的なHTMLパースのスキルを身につけることができるでしょう。

●HTMLパースとは?

HTMLパースは、ウェブ上で重要な役割を果たす技術です。

HTMLという言語で書かれたウェブページを、コンピュータプログラムが理解しやすい形に変換する過程を指します。

この技術は、ウェブスクレイピングやウェブページの分析、さらにはウェブアプリケーションの開発など、様々な場面で活用されています。

HTMLパースを使うことで、ウェブページの中から必要な情報だけを取り出したり、ページの構造を詳しく調べたりすることができます。

例えば、ニュースサイトから最新の記事タイトルを集めたり、オンラインショップの商品価格を比較したりする際に、HTMLパースが大きな力を発揮します。

●HTMLパースの基本

HTMLパースの基本を理解することは、ウェブ開発者にとって重要なステップです。

ここでは、HTMLパースの目的と仕組みについて詳しく見ていきましょう。

○HTMLパースの目的

HTMLパースの主な目的は、ウェブページから特定の情報を抽出したり、ウェブページの構造を分析したりすることです。

例えば、ある企業のウェブサイトから全ての従業員の名前を抽出したい場合や、ブログサイトの記事の構造を調べたい場合に、HTMLパースが役立ちます。

また、ウェブページをカスタマイズする際にも、HTMLパースは重要な役割を果たします。

既存のウェブページの内容を変更したり、新しい要素を追加したりする際に、HTMLパースを使って既存の構造を解析し、必要な修正を加えることができます。

○HTMLパースの仕組み

HTMLパースの仕組みは、人間が文章を読む過程に似ています。

まず、HTMLのタグや属性を一つずつ読み取り、それぞれの要素の関係性を理解します。

そして、それらの情報を木構造(DOMツリー)に変換します。

DOMツリーは、Document Object Model(文書オブジェクトモデル)と呼ばれる形式で、ウェブページの構造を表現します。

この形式に変換することで、プログラムがウェブページの内容を効率的に操作できるようになります。

HTMLパースを行うには、JavaScriptやPythonなどのプログラミング言語と、それに対応するライブラリを使用します。

これらのツールを使うことで、複雑なHTMLの構造を簡単に解析し、必要な情報を取り出すことができるのです。

●HTMLパースの作り方とサンプルコード

HTMLパースを実際に行うには、プログラミング言語とそれに対応したライブラリを使用します。

ここでは、JavaScriptとPythonを使ったHTMLパースの基本的な方法とサンプルコードを紹介します。

○JavaScriptを使ったHTMLパース

JavaScriptでHTMLをパースするには、DOMParserというオブジェクトを使用します。

DOMParserは、HTMLの文字列をDOMツリーに変換してくれる便利なツールです。

次のサンプルコードを見てみましょう。

const htmlString = `
  <div>
    <h1>タイトル</h1>
    <p>本文です。</p>
  </div>
`;

const parser = new DOMParser();
const doc = parser.parseFromString(htmlString, "text/html");

console.log(doc.querySelector("h1").textContent); // "タイトル"
console.log(doc.querySelector("p").textContent); // "本文です。"

このコードでは、まずHTMLの文字列を定義しています。

次に、DOMParserオブジェクトを作成し、parseFromStringメソッドを使ってHTMLをパースします。

パースされたDOMツリーから、querySelectorメソッドを使って特定の要素を選択し、その内容を取得しています。

○Pythonを使ったHTMLパース

PythonでHTMLをパースする際には、BeautifulSoupというライブラリがよく使われます。

BeautifulSoupは、HTMLやXMLの解析を簡単に行うことができる強力なツールです。

次のサンプルコードを見てみましょう。

from bs4 import BeautifulSoup

html_string = """
  <div>
    <h1>タイトル</h1>
    <p>本文です。</p>
  </div>
"""

soup = BeautifulSoup(html_string, "html.parser")

print(soup.find("h1").text)  # "タイトル"
print(soup.find("p").text)   # "本文です。"

このコードでは、まずBeautifulSoupをインポートし、HTMLの文字列を定義しています。

BeautifulSoupオブジェクトを作成してHTMLをパースし、findメソッドを使って特定の要素を選択しています。

選択した要素のテキスト内容は、textプロパティで取得できます。

これらのサンプルコードは、HTMLパースの基本的な使い方を表しています。

実際のウェブページを解析する際には、より複雑な処理が必要になることもありますが、基本的な考え方は同じです。

●HTMLパースの使い方

HTMLパースは、ウェブ開発やデータ分析の様々な場面で活用されています。

ここでは、HTMLパースの代表的な使用方法について、詳しく解説します。

○ウェブスクレイピングでの応用

ウェブスクレイピングは、HTMLパースの最も一般的な応用例の一つです。

ウェブページから自動的に情報を収集し、分析や再利用を行うために使われます。

例えば、ニュースサイトから最新の記事タイトルを収集したり、Eコマースサイトから商品情報を抽出したりする際に、HTMLパースが重要な役割を果たします。

ここでは、JavaScriptを使ってニュースサイトから記事のタイトルを抽出するサンプルコードを紹介します。

const axios = require("axios");
const { JSDOM } = require("jsdom");

async function fetchNewsTitles() {
  const response = await axios.get("https://example.com/news");
  const dom = new JSDOM(response.data);
  const titles = [...dom.window.document.querySelectorAll(".news-title")].map(
    (title) => title.textContent
  );
  console.log(titles);
}

fetchNewsTitles();

このコードでは、axiosライブラリを使ってウェブページを取得し、JSDOMを使ってHTMLをパースしています。

querySelectorAllメソッドを使って、ニュース記事のタイトルを含む要素を全て選択し、そのテキスト内容を配列として取得しています。

○ウェブページの分析

HTMLパースは、ウェブページの構造やコンテンツを分析する際にも重要です。

例えば、SEO(検索エンジン最適化)の観点からウェブページの構造を分析したり、ウェブサイトのリンク構造を調べたりする際に使用されます。

ここでは、Pythonを使ってウェブページのリンク情報を取得するサンプルコードを紹介します。

import requests
from bs4 import BeautifulSoup

url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")

links = [a["href"] for a in soup.find_all("a", href=True)]
print(links)

このコードでは、requestsライブラリを使ってウェブページを取得し、BeautifulSoupを使ってHTMLをパースしています。

find_allメソッドを使って、ページ内の全てのリンク(aタグ)を取得し、そのhref属性の値を抽出しています。

これらの例は、HTMLパースの基本的な使い方を示していますが、実際の応用場面では、より複雑な処理が必要になることもあります。

例えば、複数ページにわたる情報の収集や、動的に生成されるコンテンツの解析などが挙げられます。

●HTMLパースの対処法と注意点

HTMLパースを効果的に行うためには、いくつかの注意点があります。

ここでは、HTMLパースを行う際によく遭遇する問題とその対処法について説明します。

○エンコーディングに関する注意点

HTMLパースを行う際、最も注意すべき点の一つが文字エンコーディングです。

ウェブページは様々な言語で書かれており、それぞれ異なるエンコーディングを使用していることがあります。

適切なエンコーディングを指定しないと、文字化けや解析エラーが発生する可能性があります。

例えば、日本語のウェブページを解析する際には、UTF-8やShift_JISなどのエンコーディングを正しく指定する必要があります。

Pythonで適切なエンコーディングを指定してHTMLをパースする例を見てみましょう。

import requests
from bs4 import BeautifulSoup

url = "https://example.com"
response = requests.get(url)
response.encoding = response.apparent_encoding  # 自動的にエンコーディングを推測

soup = BeautifulSoup(response.text, "html.parser")
print(soup.title.string)

このコードでは、requestsライブラリのapparent_encodingプロパティを使用して、ウェブページのエンコーディングを自動的に推測しています。

これで、多くの場合で適切なエンコーディングを使用してHTMLをパースすることができます。

○ウェブページ構造の変更への対応

ウェブページの構造は常に変化する可能性があります。

ウェブサイトのデザインが更新されたり、HTMLの構造が変更されたりすると、それまで正常に動作していたHTMLパースのプログラムが突然動かなくなることがあります。

この問題に対処するには、定期的にパースプログラムをチェックし、必要に応じて更新することが重要です。

また、できるだけ柔軟性のあるセレクタを使用することも有効です。

例えば、クラス名やID名が変更される可能性が高い場合は、タグの階層構造を利用したセレクタを使用するなどの工夫が必要です。

より柔軟なセレクタを使用したJavaScriptのサンプルコードを紹介します。

const axios = require("axios");
const { JSDOM } = require("jsdom");

async function fetchArticleContent() {
  const response = await axios.get("https://example.com/article");
  const dom = new JSDOM(response.data);
  const article = dom.window.document.querySelector("article");

  const title = article.querySelector("h1, h2, h3")?.textContent;
  const content = article.querySelector("div > p")?.textContent;

  console.log({ title, content });
}

fetchArticleContent();

このコードでは、articleタグ内の最初の見出し(h1, h2, h3のいずれか)をタイトルとして、divタグ直下のpタグを本文として取得しています。

このように、より一般的なセレクタを使用することで、ページ構造の小さな変更に対してある程度の耐性を持たせることができます。

HTMLパースを行う際は、これらの注意点を常に意識し、適切に対処することが重要です。

エンコーディングの問題やウェブページ構造の変更に適切に対応することで、より信頼性の高いHTMLパースプログラムを作成することができます。

●HTMLパースのカスタマイズ

HTMLパースの基本的な使い方を理解したら、次はより高度な活用方法を理解しましょう。

HTMLパースをカスタマイズすることで、より精密な情報抽出や、ウェブページの効果的な操作が可能になります。

○データ抽出のカスタマイズ

HTMLパースを行う際、単純にタグやクラス名だけでなく、より複雑な条件に基づいてデータを抽出したいケースがあります。

例えば、特定の価格範囲内の商品だけを抽出したり、特定の日付以降に投稿された記事のみを取得したりする場合です。

このようなカスタマイズされたデータ抽出は、ビジネス分析や市場調査などで非常に有用です。

ここでは、Pythonを使って特定の価格範囲内の商品情報のみを抽出するサンプルコードを見てみましょう。

import requests
from bs4 import BeautifulSoup

def extract_products(url, min_price, max_price):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")
    products = soup.find_all("div", class_="product")

    filtered_products = []
    for product in products:
        name = product.find("h2", class_="product-name").text.strip()
        price = float(product.find("span", class_="price").text.strip().replace("$", ""))

        if min_price <= price <= max_price:
            filtered_products.append({"name": name, "price": price})

    return filtered_products

url = "https://example.com/products"
min_price = 50
max_price = 100

result = extract_products(url, min_price, max_price)
print(result)

このコードでは、ウェブページから全ての商品情報を取得した後、指定された価格範囲内の商品のみをフィルタリングしています。

このように、HTMLパースの結果に対して追加の処理を行うことで、より細かな条件に基づいたデータ抽出が可能になります。

○タグの操作によるカスタマイズ

HTMLパースを用いて、ウェブページの内容を変更したり、新しい要素を追加したりすることも可能です。

これは、ウェブスクレイピングだけでなく、ウェブページの動的な修正や、コンテンツの最適化などにも活用できます。

JavaScriptを使ってウェブページの特定の要素を修正するサンプルコードにも触れておきましょう。

const { JSDOM } = require("jsdom");

function modifyWebpage(html) {
    const dom = new JSDOM(html);
    const document = dom.window.document;

    // 全ての段落(p)タグに新しいクラスを追加
    document.querySelectorAll("p").forEach(p => {
        p.classList.add("modified-paragraph");
    });

    // 特定のID("old-header")を持つ要素のテキストを変更
    const header = document.getElementById("old-header");
    if (header) {
        header.textContent = "新しいヘッダーテキスト";
    }

    // 新しい要素を追加
    const newElement = document.createElement("div");
    newElement.textContent = "この要素は動的に追加されました。";
    document.body.appendChild(newElement);

    return dom.serialize();
}

const originalHtml = `
    <html>
        <body>
            <h1 id="old-header">古いヘッダー</h1>
            <p>これは段落です。</p>
            <p>これは別の段落です。</p>
        </body>
    </html>
`;

const modifiedHtml = modifyWebpage(originalHtml);
console.log(modifiedHtml);

このコードでは、HTMLの内容を解析し、特定の要素にクラスを追加したり、テキストを変更したり、新しい要素を追加したりしています。

このような操作は、ウェブページの内容を動的に変更する必要がある場合に非常に有用です。

●応用例とサンプルコード

ここまでHTMLパースの基本と応用について学んできました。ここでは、より実践的な応用例とそのサンプルコードを紹介します。

この例を通じて、HTMLパースがどのように実際のプロジェクトで活用されるか見ていきましょう。

○ニュースサイトからの情報抽出

ニュースサイトから最新の記事タイトルと投稿日時を抽出する例を見てみましょう。

この技術は、ニュース分析や情報収集の自動化に役立ちます。

Pythonを使用したコードですが、みていきましょう。

import requests
from bs4 import BeautifulSoup
from datetime import datetime

def extract_news(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")

    articles = soup.find_all("article", class_="news-item")
    news_data = []

    for article in articles:
        title = article.find("h2", class_="article-title").text.strip()
        date_str = article.find("time", class_="article-date")["datetime"]
        date = datetime.fromisoformat(date_str)

        news_data.append({
            "title": title,
            "date": date.strftime("%Y-%m-%d %H:%M:%S")
        })

    return news_data

url = "https://example.com/news"
news = extract_news(url)

for item in news:
    print(f"タイトル: {item['title']}")
    print(f"投稿日時: {item['date']}")
    print("---")

このコードでは、ニュースサイトのHTMLを解析し、各記事のタイトルと投稿日時を抽出しています。

datetime.fromisoformatを使用して日付文字列をdatetimeオブジェクトに変換し、適切なフォーマットで出力しています。

○商品価格の抽出と比較

複数のウェブサイトから同じ商品の価格を抽出し、比較する例を見てみましょう。

この技術は、価格比較サイトの構築や市場分析に活用できます。

JavaScriptを使ったサンプルコードを見てみましょう。

const axios = require("axios");
const { JSDOM } = require("jsdom");

async function fetchProductPrices(urls) {
  const prices = [];

  for (const url of urls) {
    try {
      const response = await axios.get(url);
      const dom = new JSDOM(response.data);
      const priceElement = dom.window.document.querySelector(".product-price");

      if (priceElement) {
        const price = parseFloat(priceElement.textContent.replace(/[^0-9.]/g, ""));
        prices.push({ url, price });
      } else {
        console.log(`価格要素が見つかりません: ${url}`);
      }
    } catch (error) {
      console.error(`エラーが発生しました (${url}):`, error.message);
    }
  }

  return prices;
}

async function comparePrices() {
  const urls = [
    "https://example1.com/product",
    "https://example2.com/product",
    "https://example3.com/product",
  ];

  const prices = await fetchProductPrices(urls);

  if (prices.length > 0) {
    const sortedPrices = prices.sort((a, b) => a.price - b.price);

    console.log("価格比較結果:");
    sortedPrices.forEach(({ url, price }) => {
      console.log(`${url}: $${price.toFixed(2)}`);
    });

    const cheapest = sortedPrices[0];
    console.log(`\n最安値: $${cheapest.price.toFixed(2)} (${cheapest.url})`);
  } else {
    console.log("価格情報を取得できませんでした。");
  }
}

comparePrices();

このコードでは、複数のウェブサイトから商品価格を抽出し、最安値を含む比較結果を表示しています。

エラーハンドリングも実装されており、特定のサイトでエラーが発生しても処理が続行されます。

また、結果を価格順にソートすることで、ユーザーにとってより有用な情報を提供しています。

まとめ

この記事では、HTMLパースの基本から応用まで、幅広くカバーしてきました。

HTMLパースは、ウェブスクレイピングやウェブページ分析、さらにはウェブアプリケーション開発など、様々な場面で活用される重要な技術です。

ただ、この記事で紹介した内容は、あくまでも入り口に過ぎません。

さらに高度な技術や最新のトレンドについても、継続的に学習していくことをお勧めしています。