BookTranslator
BookTranslator

Wie man eine HTML-Datei übersetzt, ohne Tags, Attribute oder Links zu beschädigen

Was in einer HTML-Datei übersetzt werden sollte, was unangetastet bleibt und wie man das prüft. Mit einer Beispielseite, einem kostenlosen Prüfwerkzeug und einem lokalen LLM-Test mit 9 Durchläufen.

BookTranslator

BookTranslator Team

14 Min. Lesezeit

Um eine HTML-Datei zu übersetzen, übersetzt man den Text, den Menschen lesen, und die Attribute, die lesbare Wörter enthalten, wie alt, title, placeholder, aria-label und die Meta-Beschreibung der Seite. Das Markup lässt man in Ruhe: Tag-Namen, href, src, id, class, Skripte, Styles und alles, was mit translate="no" markiert ist. Dann ändert man einen Wert, der leicht vergessen wird, das lang-Attribut am <html>-Element, damit Browser, Screenreader und Suchmaschinen wissen, in welcher Sprache die Seite jetzt ist.

Die Tags intakt zu halten, erwies sich als der einfache Teil. Wir haben eine 59-zeilige HTML-Hilfeseite neunmal mit einem lokalen Modell ins vereinfachte Chinesisch übersetzt, mit drei Methoden, und jede Ausgabe mit einem Skript geprüft. Jeder Durchlauf behielt jedes Tag, jeden Link und jede ID. Was schiefging, war leiser: Das Modell übersetzte eine Zeile in einem <pre>-Codeblock in allen sechs Durchläufen, die die ganze Datei sendeten, es ließ das aria-label der Navigation in allen sechs auf Englisch, und die Methode, die das Markup von der Anlage her am sichersten hält – das Übersetzen von Textstücken eins nach dem anderen –, erzeugte in allen drei ihrer Durchläufe einen Satz, der den Leser zu etwas Falschem anleitete.

Kurzantwort: Was übersetzen und was unangetastet lassen

Teil der DateiBeispiel aus unserer VorlageÜbersetzen?
Sichtbarer TextÜberschriften, Absätze, Tabellenzellen, Linktext, <label>Ja
<title> und Meta-Beschreibung<title>Export Your Library | Shelfmark Help</title>Ja. Beide erscheinen in Suchergebnissen und Browser-Tabs.
og:title und andere Social-Meta-Tags<meta property="og:title" content="Export Your Library">Ja, nur den content-Wert
alt, title, placeholder, aria-labelalt="The Export dialog with EPUB selected", aria-label="Breadcrumb"Ja
lang auf <html><html lang="en">Ändern Sie es auf die Zielsprache, zum Beispiel zh-Hans
Tag- und Attributnamen<a>, <img>, width, aria-label selbstNein
href, src, id, class, for, name, type, data-*href="#choose-format", id="q"Nein
<code>, <pre>, <script>, <style>shelfmark export --format epubNein. Über Code-Kommentare und Beispielausgaben separat entscheiden.
Text, der per CSS gesetzt wird.note::before { content: "Note: "; }Ja, aber es steckt im Stylesheet, also planen Sie es ein
JSON-LD-Strukturdaten"name": "Export your Shelfmark library"Übersetzen Sie die Werte von name und description; lassen Sie die Schlüssel und das JSON gültig
Elemente mit translate="no"<span translate="no">Shelfmark</span>Nein
HTML-Kommentare<!-- Generated by the help-center build... -->Optional. Leser sehen sie nie.
Zeichenreferenzen&lt;library&gt;, &nbsp;, &copy;Behalten Sie die maskierten maskiert. &lt; darf nicht zu einem echten < werden.

Diese Liste ist nicht unsere Erfindung. Der Abschnitt über das translate-Attribut im HTML-Standard definiert „übersetzbare Attribute“: title bei jedem Element, alt bei Bildern, placeholder bei Eingabefeldern, content bei meta-Elementen, deren Name als übersetzbar bekannt ist, und lang, das laut Standard geändert werden muss, um zur neuen Sprache zu passen. Er nennt außerdem ARIA's aria-label als Beispiel für ein Attribut, das andere Spezifikationen hinzufügen können, und besagt, dass in einem translate="no"-Element Text und Attributwerte „beim Lokalisieren der Seite unverändert bleiben sollen“.

Was wir getestet haben

Wir haben sample-source.html geschrieben, eine Help-Center-Seite für dieselbe fiktive Lese-App Shelfmark, die wir in unserem Markdown-Übersetzungstest verwendet haben. Sie enthält ein Beispiel für jede Zeile in der obigen Tabelle sowie ein paar Fallen:

  • einen Satz, der durch Inline-Tags aufgeteilt wird: „Bevor Sie exportieren, sichern Sie Ihre Notizen. Ein Export kopiert Ihre Bücher, löscht aber nichts aus Shelfmark“, wobei der Produktname in translate="no" steht;
  • einen Satz mit zwei Inline-<code>-Elementen, deren Reihenfolge wichtig ist: „Geben Sie den Pfad zum <library>-Ordner nach --out ein“;
  • einen <pre><code>-Block mit einem Befehl und einer Zeile Beispielausgabe, # Export finished: 128 books;
  • eine CSS-Regel, die das Wort „Hinweis:“ vor einem Absatz einfügt;
  • einen Link innerhalb der Seite zu #choose-format, einen mailto:-Link, ein Suchformular und einen JSON-LD-Block.

Dann baten wir ein lokales Modell, die Datei auf drei Arten ins vereinfachte Chinesisch zu übersetzen:

  1. Ganze Datei. Die ganze Datei einfügen und um die übersetzte Datei zurückbitten.
  2. Mit Anweisungen. Dasselbe, plus acht Regeln: jeden Tag- und Attributnamen beibehalten, href, src, id, class und ähnliche Werte nicht ändern, die aufgeführten Textattribute und Meta-Tags übersetzen, <code>, <pre>, <script> und <style> in Ruhe lassen, außer den JSON-LD-Werten name und description, translate="no" respektieren, Zeichenreferenzen und Kommentare beibehalten und lang auf zh-Hans setzen.
  3. Segmente. Der Ansatz von Tools, die Text aus HTML extrahieren: Ein Skript zerlegt die Datei in Tags und Text, überspringt <code>, <pre>, <script>, <style> und translate="no"-Elemente, schickt die verbleibenden Textstücke und Textattribute als nummerierte JSON-Liste an das Modell und schreibt die Übersetzungen zurück in das unveränderte Markup. Es setzt außerdem selbst lang="zh-Hans".

Das Modell war Qwen 3.6 27B (Q4_K_M) in LM Studio, mit ausgeschaltetem Denken und Temperatur 0,3, auf einem Apple M4 Max mit 64 GB Arbeitsspeicher. Wir haben jede Methode dreimal ausgeführt, insgesamt neun Läufe, am 27. Oktober 2026. Das Skript ist run_llm_html_test.py, und alle neun Ausgaben sind unverändert veröffentlicht; die README listet jede Datei auf. Wenn Sie noch kein lokales Modell eingerichtet haben, deckt unser Leitfaden zur lokalen LLM-Übersetzung die Einstellungen ab.

Dies war ein kleiner Test mit einem Modell, einem Sprachpaar und einer Seite. Er zeigt, welche Probleme auftreten und wie man sie erkennt. Er bewertet keine Modelle oder Tools.

Ergebnis: Das Markup überlebte; drei Entscheidungen nicht

Wir haben jede Ausgabe mit check_html_translation.py überprüft, einem Prüfprogramm, das ausschließlich die Python-Standardbibliothek verwendet. Die vollständige Ausgabe befindet sich in check-results.txt, und results.csv enthält eine Zeile pro Durchlauf.

PrüfungGesamte Datei (3 Durchläufe)Mit Anweisung (3 Durchläufe)Segmente (3 Durchläufe)
Dieselben 58 Tags in derselben Reihenfolge; alle href, src, id, class unverändert3 von 33 von 33 von 3
translate="no"-Text beibehalten, seiteninterner Link funktioniert weiterhin, &lt;library&gt; weiterhin maskiert3 von 33 von 33 von 3
Beispielausgabezeile innerhalb von <pre> übersetzt3 von 33 von 30 von 3 (konstruktionsbedingt übersprungen)
CSS content: "Note: " übersetzt3 von 30 von 30 von 3 (konstruktionsbedingt übersprungen)
JSON-LD name und description übersetzt3 von 33 von 30 von 3 (bewusst übersprungen)
aria-label="Breadcrumb" übersetzt0 von 30 von 33 von 3
Satz mit zwei Inline-<code>-Elementen sagt das Richtige3 von 33 von 30 von 3
Leerzeichen zwischen chinesischem Text über einen Inline-Tag hinwegkeine0, 5 und 46 in jedem Durchlauf
lang auf <html>zh-CN (nicht verlangt)zh-Hanszh-Hans (vom Skript gesetzt)

Jeder der neun Durchläufe behielt dieselben 58 Tags in derselben Reihenfolge, jedes href, src, id und class, das Ziel des seiteninternen Links, den Kommentar, das maskierte &lt;library&gt; und den Produktnamen innerhalb von translate="no". Wer befürchtet hatte, ein Modell würde das Markup einer einfachen Seite verhunzen, wurde eines Besseren belehrt. Die Probleme lagen alle darin, was übersetzt werden sollte.

1. Beispielausgabe innerhalb von <pre> wurde übersetzt

Der Codeblock in unserem Beispiel endet mit einer Zeile Programmausgabe:

<pre><code>shelfmark export --format epub --covers --out ~/Books/export
# Export finished: 128 books</code></pre>

In allen sechs Durchläufen mit ganzer Datei und mit Anweisungen gab das Modell in dieser Zeile # 导出完成:128 本书 zurück, auch in den drei Durchläufen, in denen die Anweisung lautete, nichts innerhalb von <pre> zu ändern. Der Befehl selbst wurde nie angefasst. Das Modell behandelte die Zeile als Kommentar, und Kommentare zu übersetzen ist in einem Tutorial eine vernünftige Wahl. Aber diese Zeile ist das, was das Programm ausgibt, und wer sie mit seinem Terminal vergleicht, sieht Englisch. Entscheiden Sie vor dem Übersetzen, ob Beispielausgaben und Codekommentare übersetzt werden, und teilen Sie es dem Tool mit, oder schützen Sie <pre>-Blöcke vollständig.

Die Durchläufe mit ganzer Datei übersetzten außerdem das CSS content: "Note: " im <style>-Block, während die Durchläufe mit Anweisungen, die <style> unangetastet lassen sollten, es auf Englisch beließen. Beides ist für sich genommen nicht falsch. Das Stylesheet zu übersetzen ist richtig für eine Seite, auf der das CSS inline steht, und falsch für eine Website, auf der ein gemeinsames Stylesheet alle Sprachen bedient. So oder so ist es eine Entscheidung, die jemand treffen muss, kein Detail, das ein Modell raten sollte.

2. Barrierefreiheits-Labels wurden übersprungen

Die Breadcrumb-Navigation ist <nav aria-label="Breadcrumb">. Ein Screenreader liest dieses Label vor; sehende Leser sehen es nie. In allen sechs Durchläufen mit ganzer Datei und mit Anweisungen blieb es auf Englisch, obwohl die Anweisung aria-label unter den zu übersetzenden Attributen aufführte. In einem Durchlauf mit Anweisungen blieb auch das aria-label="Search" der Suchschaltfläche auf Englisch.

Die Segmentmethode übersetzte es jedes Mal, weil ihr Skript jeden Wert von aria-label, alt, title und placeholder sammelte und jeden einzeln anforderte. Das ist das stärkste Argument dafür, Textattribute gezielt zu extrahieren, statt zu hoffen, dass das Modell sie bemerkt.

3. Die Übersetzung einzelner Teile bewahrte die Tags, zerstörte aber den Satz

Die Segmentmethode ist konstruktionsbedingt sicher für das Markup: Das Modell sieht nie ein Tag und kann daher keines beschädigen. Sie bestand alle strukturellen Prüfungen in allen drei Durchläufen. Sie lieferte aber auch die einzige Übersetzung im Test, die dem Leser falsche Anweisungen gab.

Der englische Satz lautet „Type the path to the <library> folder after --out.“ Inline-<code> teilt ihn in drei Teile: „Type the path to the“, „folder after“ und einen Punkt. Chinesisch ordnet diese Wörter anders, sodass ein Übersetzer die beiden Code-Elemente verschieben muss. Die Segmentmethode kann sie nicht verschieben. Alle drei Durchläufe kehrten die Anweisung um. Durchlauf 2 erzeugte dies (Durchläufe 1 und 3 sagen 后 statt 之后, mit derselben Bedeutung):

在 <code>&lt;library&gt;</code> 之后输入 <code>--out</code>文件夹的路径。

Das bedeutet „nach <library> geben Sie den Pfad des --out-Ordners ein“, also das Gegenteil der Anweisung. Alle sechs Ganzdatei- und instruierten Durchläufe verschoben die Code-Elemente und lagen richtig:

在 <code>--out</code> 后面输入 <code>&lt;library&gt;</code> 文件夹的路径。

Dieselbe Aufteilung hinterließ an allen drei Segmentdurchläufen an sechs Stellen pro Durchlauf störende Leerzeichen, wo ein Tag auf chinesischen Text trifft, etwa 前往 <b>设置</b> und <b>书库</b> ,. Ein Browser zeigt sie als sichtbare Lücken an, auch vor chinesischer Interpunktion. Die Ganzdatei-Durchläufe hatten keine; zwei der drei instruierten Durchläufe hatten vier oder fünf.

Ein struktureller Prüfer kann den umgekehrten Satz nicht erkennen, weil jedes Tag genau dort ist, wo es war. Unser Prüfer meldet, wenn Inline-Code die Reihenfolge ändert, was für viele Sprachen normal ist, aber diese Warnung kann nicht zwischen richtig und falsch unterscheiden. In diesem Test schlug sie bei allen sechs korrekten Übersetzungen an und blieb bei den drei falschen stumm, weil die falschen die englische Reihenfolge beibehielten. Nur ein Mensch, der den Satz liest, kann das erkennen. Die Lösung besteht darin, ganze Sätze mit ihren Inline-Tags an den Übersetzer zu senden, was die Ganzdatei-Durchläufe taten, und die Struktur danach zu prüfen.

Kleinere Unterschiede

  • lang: Die Ganzdatei-Durchläufe änderten es von selbst in zh-CN. Die instruierten Durchläufe verwendeten wie verlangt zh-Hans. Beide sind gültige Sprach-Tags; zh-Hans benennt die Schrift (vereinfachtes Chinesisch), zh-CN eine Region. Die W3C-Empfehlungen zu Sprachdeklarationen raten dazu, die Sprache am <html>-Element anzugeben und nicht mit einem Content-Language-Meta-Tag.
  • JSON-LD: Die Ganzdatei- und instruierten Durchläufe übersetzten die Werte von name und description und hielten das JSON gültig. Unser Segment-Skript übersprang den Inhalt von <script>, sodass seine strukturierten Daten auf Englisch blieben, was auch ein Werkzeug tun wird, das Skripte ignoriert.
  • Zeichenreferenzen: Die Ganzdatei- und instruierten Durchläufe behielten &rsaquo;, &nbsp;, &copy; und die Emoji-Referenz wie geschrieben bei. Fünf dieser sechs Durchläufe schrieben den Bereich 2&ndash;5 in chinesische Wörter um (2 到 5 oder 2 至 5); ein instruierter Durchlauf schrieb einen einfachen Bindestrich statt der Referenz, obwohl sein Prompt besagte, Referenzen beizubehalten. Unser Segment-Skript dekodierte alle und schrieb Zeichen zurück, was dasselbe anzeigt. Die entscheidende, &lt;library&gt; innerhalb von <code>, blieb in allen neun Durchläufen maskiert.

Vor der Übersetzung: Bereiten Sie die Datei vor

  1. Markieren Sie, was sich nicht ändern darf. Setzen Sie translate="no" auf Produktnamen, Modellnummern, codeähnliche Zeichenfolgen im Fließtext und alles andere, was unverändert bleiben muss. Es ist Teil von HTML, kostet nichts, und das Modell respektierte es in allen sechs Durchläufen, die ihm die ganze Datei sandten. Segmentwerkzeuge, die es lesen, wie unser Skript, überspringen diese Elemente vollständig. Unser Leitfaden zu nicht zu übersetzenden Inhalten behandelt, wie Sie entscheiden, was auf diese Liste gehört.
  2. Legen Sie die Code-Richtlinie fest. Werden Codekommentare übersetzt? Beispielausgaben? Wird das Stylesheet sprachübergreifend geteilt? Schreiben Sie die Antwort zusammen mit den Namen, die sich nicht ändern dürfen, in ein Übersetzungsglossar und geben Sie es an wen oder was auch immer übersetzt.
  3. Behalten Sie IDs in der Ausgangssprache bei. Seiteninterne Links verweisen auf id-Werte. Wenn jemand eine id übersetzt, bricht jeder Link darauf. Keiner unserer Durchläufe tat das, aber ein Übersetzer, der Anker „hilfreich“ lokalisiert, wird es tun.
  4. Sammeln Sie den verborgenen Text. Listen Sie die Attribute auf, die Wörter enthalten, alt, title, placeholder, aria-label, value bei Schaltflächen, Meta-Tags und JSON-LD, damit sie geprüft und nicht vergessen werden.
  5. Übersetzen Sie JavaScript-Zeichenfolgen nicht an Ort und Stelle. Meldungen, die von einem Skript gesetzt werden, etwa ein Alert oder eine im Code erzeugte Schaltflächenbeschriftung, benötigen einen separaten Lokalisierungsschritt im Code. Keiner der sechs Ganzdatei- oder instruierten Durchläufe änderte unseren Skriptblock, was korrekt ist, aber es bedeutet, dass diese Zeichenfolgen auf Englisch bleiben.

Nach der Übersetzung: Prüfen Sie sie

  1. Führen Sie die strukturelle Prüfung aus.

    python3 check_html_translation.py source.html translated.html --lang zh-Hans --keep Shelfmark
    

    Sie vergleicht Tags und ihre Reihenfolge, jedes Attribut, das kein leserorientierter Text ist, den Inhalt von <pre>, <script> und <style>, Inline-Code, JSON-LD-Schlüssel, translate="no"-Text, Kommentare und seiteninterne Links. Sie warnt vor Textattributen, die noch auf Englisch sind, einem lang-Wert, der von Ihrem erwarteten abweicht, sichtbarem Text, der unübersetzt aussieht, Inline-Code, der die Reihenfolge geändert hat, und Leerzeichen zwischen chinesischem, japanischem oder koreanischem Text über ein Inline-Tag hinweg. Sie beurteilt nicht die Übersetzungsqualität.

  2. Lesen Sie jeden Satz, der ein Inline-Tag enthält. Hier brach die Bedeutung in unserem Test. Verlassen Sie sich nicht auf die Warnung „Inline-Code neu geordnet“ des Prüfers, um diese Sätze zu finden: In unserem Test waren die falschen Übersetzungen diejenigen, die die ursprüngliche Reihenfolge beibehielten.

  3. Öffnen Sie die Seite in einem Browser. Klicken Sie die seiteninternen Links an, tabben Sie mit einem Screenreader durch das Formular, wenn möglich, und achten Sie auf Lücken um fetten und verlinkten Text.

  4. Für rechts-nach-links-Sprachen setzen Sie außerdem dir="rtl" am <html>-Element. Unser Leitfaden zur RTL-Buchübersetzung behandelt, was sich sonst noch ändert.

  5. Für XHTML, etwa die Kapiteldateien in einem EPUB, bestätigen Sie außerdem, dass die Datei noch wohlgeformtes XML ist, zum Beispiel mit xmllint --noout chapter.xhtml. Ein Browser verzeiht ein nicht geschlossenes Tag; ein E-Reader möglicherweise nicht. Unsere QA-Checkliste für EPUB-Übersetzungen behandelt den Rest eines E-Books.

Wo BookTranslator passt

Die Upload-Seite von BookTranslator akzeptiert .html-, .htm- und .xhtml-Dateien neben Büchern und Dokumenten, sodass du eine gespeicherte Seite oder einen statischen Hilfeartikel als ganze Datei hochladen kannst. Wir haben dieses Beispiel für diesen Artikel nicht durch BookTranslator laufen lassen und nicht getestet, wie es mit der Reihenfolge von Inline-Code, CSS-Inhalten oder JSON-LD umgeht. Prüfe die Ausgabe daher genauso, wie du die Ausgabe jedes anderen Tools prüfen würdest. Du siehst den Preis, bevor du bezahlst.

Was auch immer du verwendest: Führe die Vorbereitungsschritte vor dem Übersetzen und die Prüfungen danach durch. Eine Seite mit intakten Tags kann einem Leser immer noch sagen, das Falsche einzugeben. Wenn dein HTML eigentlich eine in Markdown geschriebene Dokumentation ist, behandelt unser Markdown-Übersetzungsleitfaden stattdessen das Quellformat.

Lade die Testdateien herunter

Alles aus diesem Test darf frei wiederverwendet werden:

Verwandte Beiträge