DEV Community

Cover image for HTMLテーブルの隠しデータ:見えないデータをスクレイピングする方法
circobit
circobit

Posted on

HTMLテーブルの隠しデータ:見えないデータをスクレイピングする方法

テーブルには10列が表示されている。エクスポートすると、CSVも10列。

でもそのページには実は15列分のデータがある。残りの5列はどこへ?

HTMLテーブルには、表示されている以上のデータが含まれていることがよくあります。非表示の列、data属性、折りたたまれた行——基本的な抽出方法では見えないデータです。

ここでは、見えないデータを見つけて抽出する方法を解説します。

隠しデータの種類

1. CSSで非表示にされた列

最もシンプルなケース:列はDOMに存在しているが、CSSで非表示にされている。

<th style="display: none;">内部ID</th>
<td style="display: none;">12345</td>
Enter fullscreen mode Exit fullscreen mode

またはクラスで指定される場合:

.hidden-column { display: none; }
Enter fullscreen mode Exit fullscreen mode

サイト側がこうする理由: モバイルレスポンシブ対応(小さい画面では列を非表示にする)、JavaScript用の内部データ、段階的な情報開示。

検出方法: DevToolsを開き、テーブルを検査して、display: none または visibility: hidden が設定されたセルを探す。

2. Data属性

HTML5ではどの要素にもカスタム data-* 属性を追加できます。テーブルではこれを使って、JavaScriptがアクセスするがユーザーには見えないメタデータを格納します。

<tr data-id="12345" data-category="electronics" data-stock="47">
  <td>ノートPC</td>
  <td>¥99,900</td>
</tr>
Enter fullscreen mode Exit fullscreen mode

表示されるテーブルには「ノートPC」と「¥99,900」だけ。しかし行には3つの追加データポイントがあります。

よく使われるdata属性:

  • data-id — 内部識別子
  • data-sort-value — ソート用の数値(表示が「2024年1月」でもソートには202401が必要な場合)
  • data-raw — フォーマットされていない値(表示が「120万円」でもデータは1200000の場合)
  • data-href — リンクURL

3. TitleとTooltip属性

title 属性はホバーテキストを提供し、追加情報が含まれていることがよくあります。

<td title="更新日時: 2024-01-15 14:32:00 UTC">1月15日</td>
Enter fullscreen mode Exit fullscreen mode

セルには「1月15日」と表示される。完全なタイムスタンプはツールチップの中にあります。

4. 折りたたみ可能な行

ドリルダウン機能を持つテーブルは、クリックされるまで詳細行を非表示にします。

<tr class="parent-row">
  <td>カテゴリA</td>
  <td>¥5,000,000</td>
</tr>
<tr class="child-row" style="display: none;">
  <td>— サブカテゴリA1</td>
  <td>¥3,000,000</td>
</tr>
<tr class="child-row" style="display: none;">
  <td>— サブカテゴリA2</td>
  <td>¥2,000,000</td>
</tr>
Enter fullscreen mode Exit fullscreen mode

データは存在している。ただ展開されていないだけです。

5. 遅延読み込みコンテンツ

一部のテーブルはサブセットだけを表示し、スクロールや「もっと読み込む」をクリックするとJavaScriptで追加データを読み込みます。

<table id="results">
  <!-- 最初の20行がレンダリング -->
</table>
<button onclick="loadMore()">さらに結果を表示</button>
Enter fullscreen mode Exit fullscreen mode

残りのデータは、読み込みがトリガーされるまでDOMに存在しません。

隠しデータの抽出方法

CSSで非表示にされた列の抽出

JavaScript(ブラウザコンソール)で:

// すべてのセルからdisplay:noneを削除
document.querySelectorAll('td, th').forEach(el => {
  el.style.display = '';
});
Enter fullscreen mode Exit fullscreen mode

これで通常通りエクスポートすれば、列が表示されます。

Python + BeautifulSoupで:

BeautifulSoupはCSSを無視します。表示状態に関係なくすべての要素を抽出します。

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, 'html.parser')
table = soup.find('table')

for row in table.find_all('tr'):
    cells = [td.get_text(strip=True) for td in row.find_all(['td', 'th'])]
    print(cells)  # 非表示列も含まれる
Enter fullscreen mode Exit fullscreen mode

Data属性の抽出

JavaScriptアプローチ:

const rows = document.querySelectorAll('table tr');
const data = [];

rows.forEach(row => {
  const rowData = {
    // 表示テキスト
    cells: Array.from(row.querySelectorAll('td')).map(td => td.textContent),
    // Data属性
    id: row.dataset.id,
    category: row.dataset.category,
    stock: row.dataset.stock
  };
  data.push(rowData);
});

console.log(JSON.stringify(data, null, 2));
Enter fullscreen mode Exit fullscreen mode

Pythonアプローチ:

for row in table.find_all('tr'):
    # data属性を取得
    attrs = {k: v for k, v in row.attrs.items() if k.startswith('data-')}

    # セルテキストを取得
    cells = [td.get_text(strip=True) for td in row.find_all('td')]

    print(f"Data: {attrs}, Cells: {cells}")
Enter fullscreen mode Exit fullscreen mode

Title属性の抽出

const cells = document.querySelectorAll('table td');
cells.forEach(cell => {
  if (cell.title) {
    console.log(`表示: ${cell.textContent}, 全体: ${cell.title}`);
  }
});
Enter fullscreen mode Exit fullscreen mode

折りたたまれた行の展開

方法1:すべての展開ボタンをクリック

// すべての展開ボタンを見つけてクリック
document.querySelectorAll('.expand-btn, .toggle-row').forEach(btn => {
  btn.click();
});

// DOMの更新を待ってからエクスポート
setTimeout(() => {
  // エクスポート処理
}, 1000);
Enter fullscreen mode Exit fullscreen mode

方法2:非表示クラスを削除

document.querySelectorAll('.child-row, .detail-row').forEach(row => {
  row.style.display = '';
  row.classList.remove('hidden', 'collapsed');
});
Enter fullscreen mode Exit fullscreen mode

遅延読み込みのトリガー

これはやや複雑で、読み込みをトリガーするアクションをシミュレートする必要があります。

// 無限スクロールをトリガーするためにページ下部にスクロール
window.scrollTo(0, document.body.scrollHeight);

// または「もっと読み込む」を繰り返しクリック
const loadMore = document.querySelector('.load-more-btn');
while (loadMore && !loadMore.disabled) {
  loadMore.click();
  await new Promise(r => setTimeout(r, 500)); // 読み込みを待つ
}
Enter fullscreen mode Exit fullscreen mode

実例:ソート値

スポーツ統計テーブルは、フォーマットされた数値を表示しつつ、生の値でソートすることがよくあります。

<td data-sort="1234567">123.4万</td>
<td data-sort="20240115">2024年1月15日</td>
<td data-sort="0.347">34.7%</td>
Enter fullscreen mode Exit fullscreen mode

表示テキストだけを抽出すると、正しくソートも計算もできないフォーマット済みの文字列になってしまいます。

両方の値を抽出:

const cells = document.querySelectorAll('table td');
const data = Array.from(cells).map(cell => ({
  display: cell.textContent.trim(),
  sortValue: cell.dataset.sort || cell.textContent.trim()
}));
Enter fullscreen mode Exit fullscreen mode

ブラウザ拡張機能が役立つ場面

優れたテーブルエクスポートツールは、これらの一部を自動的に処理します:

  • CSSで非表示にされた列をオプションで含めることが可能
  • Data属性を追加列として抽出可能
  • 数値の正規化で「120万円」を1200000に変換可能

HTML Table Exporterは、結合セルやフォーマットを適切に処理しつつ、表示コンテンツを抽出します。コードなしでのより複雑な抽出については、コードなしでWebサイトのテーブルをスクレイピングする方法のガイドをご覧ください。

Data属性や深く隠されたコンテンツについては、上記のJavaScriptアプローチが必要になる場合があります。

検査ワークフロー

テーブルを抽出する前に:

  1. DevToolsを開く(F12)
  2. テーブル要素を検査
  3. 以下を確認:
    • 列の display: none
    • 行/セルの data-* 属性
    • 追加情報を含む title 属性
    • 非表示の子行
    • 「もっと読み込む」ボタン
  4. 判断: 表示データで十分か、それとも隠しデータが必要か?

ほとんどの場合、表示データで十分です。しかし足りない場合に、隠しデータの見つけ方と抽出方法を知っていることが決定的な差になります。

まとめ

HTMLテーブルには複数のデータレイヤーが含まれることがあります:

レイヤー アクセス方法
表示テキスト 通常のエクスポート
CSS非表示列 display:noneを削除またはBeautifulSoupを使用
Data属性 JavaScript datasetまたはPython attrs
Title/ツールチップ title属性を抽出
折りたたまれた行 展開または非表示クラスを削除
遅延読み込み 先に読み込みをトリガー

データは通常そこにあります。どこを見ればいいかを知るだけです。


表示されているデータをエクスポートしたい方は、gauchogrid.com/ja/html-table-exporterで詳細を確認するか、Chrome ウェブストアでHTML Table Exporterを無料でお試しください。

Top comments (0)