DEV Community

Cover image for HTML-Tabellen mit versteckten Daten: Scrapen, was man nicht sieht
circobit
circobit

Posted on

HTML-Tabellen mit versteckten Daten: Scrapen, was man nicht sieht

Die Tabelle zeigt 10 Spalten. Man exportiert sie. Die CSV hat 10 Spalten.

Aber die Seite hat 15 Spalten an Daten. Wo sind die anderen 5 geblieben?

HTML-Tabellen enthalten oft mehr Daten als sichtbar. Versteckte Spalten, Data-Attribute, eingeklappte Zeilen — alles unsichtbar für einfache Extraktionsmethoden.

So findet und extrahiert man die Daten, die man nicht sieht.

Arten versteckter Daten

1. CSS-versteckte Spalten

Der einfachste Fall: Spalten existieren im DOM, sind aber per CSS versteckt.

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

Oder über Klassen:

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

Warum Websites das machen: Mobile Responsiveness (Spalten auf kleinen Bildschirmen ausblenden), interne Daten für JavaScript, schrittweise Offenlegung.

Wie man es erkennt: DevTools öffnen, die Tabelle inspizieren, nach Zellen mit display: none oder visibility: hidden suchen.

2. Data-Attribute

HTML5 erlaubt benutzerdefinierte data-* Attribute auf jedem Element. Tabellen nutzen diese, um Metadaten zu speichern, auf die JavaScript zugreift, die der Nutzer aber nicht sieht.

<tr data-id="12345" data-category="elektronik" data-stock="47">
  <td>Laptop</td>
  <td>999 €</td>
</tr>
Enter fullscreen mode Exit fullscreen mode

Die sichtbare Tabelle zeigt „Laptop" und „999 €". Aber die Zeile trägt drei zusätzliche Datenpunkte.

Häufige Data-Attribute:

  • data-id — interner Bezeichner
  • data-sort-value — numerischer Wert zum Sortieren (wenn die Anzeige „Jan 2024" zeigt, aber die Sortierung 202401 braucht)
  • data-raw — unformatierter Wert (wenn die Anzeige „1,2 Mio. €" zeigt, aber der Wert 1200000 ist)
  • data-href — Link-URL

3. Title- und Tooltip-Attribute

Das title-Attribut liefert Hover-Text, der oft zusätzliche Informationen enthält.

<td title="Aktualisiert: 2024-01-15 14:32:00 UTC">15. Jan</td>
Enter fullscreen mode Exit fullscreen mode

Die Zelle zeigt „15. Jan". Der vollständige Zeitstempel steckt im Tooltip.

4. Eingeklappte/Erweiterbare Zeilen

Tabellen mit Drill-Down-Funktionalität verstecken Detailzeilen, bis man klickt.

<tr class="parent-row">
  <td>Kategorie A</td>
  <td>50.000 €</td>
</tr>
<tr class="child-row" style="display: none;">
  <td>— Unterkategorie A1</td>
  <td>30.000 €</td>
</tr>
<tr class="child-row" style="display: none;">
  <td>— Unterkategorie A2</td>
  <td>20.000 €</td>
</tr>
Enter fullscreen mode Exit fullscreen mode

Die Daten existieren. Sie sind nur nicht aufgeklappt.

5. Lazy-Loaded-Inhalte

Manche Tabellen zeigen eine Teilmenge und laden mehr per JavaScript, wenn man scrollt oder auf „Mehr laden" klickt.

<table id="results">
  <!-- Erste 20 Zeilen gerendert -->
</table>
<button onclick="loadMore()">Mehr Ergebnisse anzeigen</button>
Enter fullscreen mode Exit fullscreen mode

Die restlichen Daten sind nicht im DOM, bis man das Laden auslöst.

Versteckte Daten extrahieren

CSS-versteckte Spalten extrahieren

Mit JavaScript (in der Browser-Konsole):

// display:none von allen Zellen entfernen
document.querySelectorAll('td, th').forEach(el => {
  el.style.display = '';
});
Enter fullscreen mode Exit fullscreen mode

Jetzt normal exportieren — die Spalten sind sichtbar.

Mit Python + BeautifulSoup:

BeautifulSoup ignoriert CSS. Es extrahiert alle Elemente unabhängig von der Sichtbarkeit.

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)  # Enthält versteckte Spalten
Enter fullscreen mode Exit fullscreen mode

Data-Attribute extrahieren

JavaScript-Ansatz:

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

rows.forEach(row => {
  const rowData = {
    // Sichtbarer Text
    cells: Array.from(row.querySelectorAll('td')).map(td => td.textContent),
    // Data-Attribute
    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-Ansatz:

for row in table.find_all('tr'):
    # Data-Attribute holen
    attrs = {k: v for k, v in row.attrs.items() if k.startswith('data-')}

    # Zellentext holen
    cells = [td.get_text(strip=True) for td in row.find_all('td')]

    print(f"Daten: {attrs}, Zellen: {cells}")
Enter fullscreen mode Exit fullscreen mode

Title-Attribute extrahieren

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

Eingeklappte Zeilen expandieren

Option 1: Alle Expander klicken

// Alle Expand-Buttons finden und klicken
document.querySelectorAll('.expand-btn, .toggle-row').forEach(btn => {
  btn.click();
});

// Auf DOM-Update warten, dann exportieren
setTimeout(() => {
  // Export-Logik hier
}, 1000);
Enter fullscreen mode Exit fullscreen mode

Option 2: Hidden-Klasse entfernen

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

Lazy Load auslösen

Das ist kniffliger — man muss die Aktion simulieren, die das Laden auslöst.

// Zum Ende scrollen, um Infinite Scroll auszulösen
window.scrollTo(0, document.body.scrollHeight);

// Oder "Mehr laden" wiederholt klicken
const loadMore = document.querySelector('.load-more-btn');
while (loadMore && !loadMore.disabled) {
  loadMore.click();
  await new Promise(r => setTimeout(r, 500)); // Auf Laden warten
}
Enter fullscreen mode Exit fullscreen mode

Praxisbeispiel: Sort-Werte

Sportstatistik-Tabellen zeigen oft formatierte Zahlen, sortieren aber nach Rohwerten.

<td data-sort="1234567">1,23 Mio.</td>
<td data-sort="20240115">15. Jan 2024</td>
<td data-sort="0.347">34,7 %</td>
Enter fullscreen mode Exit fullscreen mode

Wenn man nur den sichtbaren Text extrahiert, bekommt man formatierte Strings, die sich nicht sortieren oder berechnen lassen.

Extraktion mit beiden Werten:

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

Wann Browser-Erweiterungen helfen

Gute Tabellenexport-Tools erledigen einiges davon automatisch:

  • CSS-versteckte Spalten können per Option einbezogen werden
  • Data-Attribute können als zusätzliche Spalten extrahiert werden
  • Zahlennormalisierung kann „1,23 Mio. €" in 1230000 umwandeln

HTML Table Exporter extrahiert sichtbare Inhalte mit korrekter Behandlung zusammengeführter Zellen und Formatierung. Für komplexere Extraktionsanforderungen ohne Code siehe unseren Leitfaden zu HTML-Tabellen-Scrapern für Chrome.

Für Data-Attribute und tief versteckte Inhalte benötigt man möglicherweise die oben gezeigten JavaScript-Ansätze.

Der Inspektions-Workflow

Vor dem Extrahieren jeder Tabelle:

  1. DevTools öffnen (F12)
  2. Das Tabellenelement inspizieren
  3. Prüfen auf:
    • display: none bei Spalten
    • data-* Attribute auf Zeilen/Zellen
    • title-Attribute mit Zusatzinfos
    • Versteckte Kindzeilen
    • „Mehr laden"-Buttons
  4. Entscheiden: Reichen die sichtbaren Daten, oder braucht man die versteckten Daten?

Meistens reichen die sichtbaren Daten. Aber wenn nicht, macht das Wissen, wie man versteckte Daten findet und extrahiert, den entscheidenden Unterschied.

Zusammenfassung

HTML-Tabellen können mehrere Datenschichten enthalten:

Schicht Zugriffsmethode
Sichtbarer Text Standard-Export
CSS-versteckte Spalten display:none entfernen oder BeautifulSoup verwenden
Data-Attribute JavaScript dataset oder Python attrs
Title/Tooltips title-Attribut extrahieren
Eingeklappte Zeilen Expandieren oder Hidden-Klasse entfernen
Lazy-Loaded Laden zuerst auslösen

Die Daten sind meistens da. Man muss nur wissen, wo man suchen muss.


Sichtbare Daten exportieren? Erfahren Sie mehr auf gauchogrid.com/de/html-table-exporter oder probieren Sie HTML Table Exporter kostenlos im Chrome Web Store.

Top comments (0)