Cum să traduci un fișier HTML fără a strica etichetele, atributele sau linkurile
Ce să traduci într-un fișier HTML, ce să lași neatins și cum să verifici. Cu o pagină exemplu, un verificator gratuit și un test cu un LLM local în 9 rulări.

Pentru a traduce un fișier HTML, traduce textul pe care oamenii îl citesc și atributele care conțin cuvinte destinate cititorului, cum ar fi alt, title, placeholder, aria-label și meta descrierea paginii. Lasă marcajul neatins: numele etichetelor, href, src, id, class, scripturile, stilurile și orice este marcat cu translate="no". Apoi modifică o valoare ușor de uitat, atributul lang de pe elementul <html>, astfel încât browserele, cititoarele de ecran și motoarele de căutare să știe în ce limbă este acum pagina.
Păstrarea etichetelor intacte s-a dovedit a fi partea ușoară. Am tradus o pagină de ajutor HTML de 59 de linii în chineză simplificată de nouă ori cu un model local, folosind trei metode, și am verificat fiecare rezultat cu un script. Fiecare rulare a păstrat fiecare etichetă, link și ID. Ce a mers prost a fost mai discret: modelul a tradus o linie dintr-un bloc de cod <pre> în toate cele șase rulări care au trimis întregul fișier, a lăsat aria-label din navigare în engleză în toate cele șase, iar metoda care păstrează cel mai sigur marcajul prin design, traducerea bucăților de text una câte una, a produs o propoziție care îi spunea cititorului să facă lucrul greșit în toate cele trei rulări ale sale.
Răspuns rapid: ce să traduci și ce să lași neatins
| Parte a fișierului | Exemplu din eșantionul nostru | Să o traduci? |
|---|---|---|
| Text vizibil | titluri, paragrafe, celule de tabel, text de link, <label> | Da |
<title> și meta descrierea | <title>Export Your Library | Shelfmark Help</title> | Da. Ambele apar în rezultatele căutării și în filele browserului. |
og:title și alte meta etichete sociale | <meta property="og:title" content="Export Your Library"> | Da, doar valoarea content |
alt, title, placeholder, aria-label | alt="The Export dialog with EPUB selected", aria-label="Breadcrumb" | Da |
lang pe <html> | <html lang="en"> | Schimbă-l în limba țintă, de exemplu zh-Hans |
| Numele etichetelor și atributelor | <a>, <img>, width, aria-label în sine | Nu |
href, src, id, class, for, name, type, data-* | href="#choose-format", id="q" | Nu |
<code>, <pre>, <script>, <style> | shelfmark export --format epub | Nu. Decide separat despre comentariile din cod și rezultatul exemplu. |
| Text setat prin CSS | .note::before { content: "Note: "; } | Da, dar se află în foaia de stil, așa că planifică pentru asta |
| Date structurate JSON-LD | "name": "Export your Shelfmark library" | Tradu valorile name și description; păstrează cheile și JSON-ul valid |
Elemente cu translate="no" | <span translate="no">Shelfmark</span> | Nu |
| Comentarii HTML | <!-- Generated by the help-center build... --> | Opțional. Cititorii nu le văd niciodată. |
| Referințe de caractere | <library>, , © | Păstrează-le pe cele escape-ate ca escape-ate. < nu trebuie să devină un < real. |
Această listă nu este invenția noastră. Secțiunea HTML Standard despre atributul translate definește „atribute traductibile”: title pe orice element, alt pe imagini, placeholder pe inputuri, content pe elementele meta al căror nume este cunoscut ca traductibil, și lang, despre care spune că trebuie schimbat pentru a se potrivi cu limba nouă. De asemenea, numește aria-label din ARIA ca exemplu de atribut pe care alte specificații îl pot adăuga, și spune că într-un element cu translate="no", textul și valorile atributelor „trebuie lăsate așa cum sunt atunci când pagina este localizată.”
Ce am testat
Am scris sample-source.html, o pagină de centru de ajutor pentru aceeași aplicație fictivă de lectură, Shelfmark, pe care am folosit-o în testul nostru de traducere Markdown. Are câte un exemplu pentru fiecare rând din tabelul de mai sus, plus câteva capcane:
- o propoziție împărțită de etichete inline: „Înainte de a exporta, fă o copie de siguranță a notițelor. Un export copiază cărțile, dar nu șterge nimic din Shelfmark,” cu numele produsului în interiorul
translate="no"; - o propoziție cu două elemente inline
<code>a căror ordine contează: „Tastează calea către folderul<library>după--out”; - un bloc
<pre><code>cu o comandă și o linie de ieșire exemplu,# Export finished: 128 books; - o regulă CSS care inserează cuvântul „Notă:” înaintea unui paragraf;
- un link în pagină către
#choose-format, un linkmailto:, un formular de căutare și un bloc JSON-LD.
Apoi am rugat un model local să îl traducă în chineză simplificată în trei moduri:
- Fișier întreg. Lipește întregul fișier și cere fișierul tradus înapoi.
- Cu instrucțiuni. La fel, plus opt reguli: păstrează fiecare nume de etichetă și atribut, nu schimba
href,src,id,classși valori similare, traduce atributele text listate și meta-etichetele, lasă<code>,<pre>,<script>și<style>în pace, cu excepțianameșidescriptiondin JSON-LD, respectătranslate="no", păstrează referințele de caractere și comentariile și seteazălanglazh-Hans. - Segmente. Abordarea instrumentelor care extrag text din HTML: un script împarte fișierul în etichete și text, sare peste
<code>,<pre>,<script>,<style>și elementele cutranslate="no", trimite bucățile de text rămase și atributele text modelului ca o listă JSON numerotată și scrie traducerile înapoi în marcajul neatins. De asemenea, setează singurlang="zh-Hans".
Modelul a fost Qwen 3.6 27B (Q4_K_M) în LM Studio, cu gândirea dezactivată și temperatura 0,3, pe un Apple M4 Max cu 64 GB de memorie. Am rulat fiecare metodă de trei ori, nouă rulări în total, pe 27 octombrie 2026. Scriptul este run_llm_html_test.py, iar toate cele nouă rezultate sunt publicate needitate; README listează fiecare fișier. Dacă nu ai configurat niciodată un model local, ghidul nostru de traducere cu LLM local acoperă setările.
Acesta a fost un test mic cu un singur model, o singură pereche de limbi și o singură pagină. Arată ce probleme apar și cum să le prinzi. Nu clasează modele sau instrumente.
Rezultat: Marcajul a supraviețuit; trei decizii nu
Am verificat fiecare rezultat cu check_html_translation.py, un verificator care folosește doar biblioteca standard Python. Rezultatul complet este în check-results.txt, iar results.csv conține câte un rând pentru fiecare rulare.
| Verificare | Fișier complet (3 rulări) | Cu instrucțiuni (3 rulări) | Segmente (3 rulări) |
|---|---|---|---|
Aceleași 58 de etichete în ordine; fiecare href, src, id, class neschimbat | 3 din 3 | 3 din 3 | 3 din 3 |
Textul cu translate="no" păstrat, linkul din pagină încă funcționează, <library> încă escapat | 3 din 3 | 3 din 3 | 3 din 3 |
Linia de exemplu din interiorul <pre> tradusă | 3 din 3 | 3 din 3 | 0 din 3 (omisă intenționat) |
CSS content: "Note: " tradus | 3 din 3 | 0 din 3 | 0 din 3 (omisă intenționat) |
JSON-LD name și description traduse | 3 din 3 | 3 din 3 | 0 din 3 (omise intenționat) |
aria-label="Breadcrumb" tradus | 0 din 3 | 0 din 3 | 3 din 3 |
Propoziția cu două elemente inline <code> spune lucrul corect | 3 din 3 | 3 din 3 | 0 din 3 |
| Spații între textul chinezesc de-a lungul unui tag inline | niciunul | 0, 5 și 4 | 6 în fiecare rulare |
lang pe <html> | zh-CN (nu a fost cerut) | zh-Hans | zh-Hans (setat de script) |
Fiecare dintre cele nouă rulări a păstrat aceleași 58 de taguri în aceeași ordine, fiecare href, src, id și class, ținta linkului din pagină, comentariul, <library> escapat și numele produsului din interiorul translate="no". Dacă vă îngrijorați că un model va strica markup-ul unei pagini simple, nu s-a întâmplat. Problemele au fost toate legate de ce trebuia tradus.
1. Rezultatul exemplu din interiorul <pre> a fost tradus
Blocul de cod din exemplul nostru se termină cu o linie de ieșire a programului:
<pre><code>shelfmark export --format epub --covers --out ~/Books/export
# Export finished: 128 books</code></pre>
În toate cele șase rulări pe fișier complet și cu instrucțiuni, modelul a returnat # 导出完成:128 本书 pe acea linie, inclusiv în cele trei rulări în care promptul spunea să nu se modifice nimic din interiorul <pre>. Comanda în sine nu a fost atinsă niciodată. Modelul a tratat linia ca pe un comentariu, iar traducerea comentariilor este o alegere rezonabilă într-un tutorial. Dar această linie este ceea ce afișează programul, iar un cititor care o compară cu terminalul său va vedea engleză. Decideți înainte de a traduce dacă rezultatul exemplu și comentariile din cod sunt traduse și spuneți-i instrumentului, sau protejați complet blocurile <pre>.
Rulările pe fișier complet au tradus și CSS-ul content: "Note: " din blocul <style>, în timp ce rulările cu instrucțiuni, cărora li s-a spus să lase <style> în pace, l-au păstrat în engleză. Niciuna nu este greșită în sine. Traducerea foii de stil este corectă pentru o pagină în care CSS-ul este inline și greșită pentru un site în care o foaie de stil partajată servește toate limbile. În orice caz, este o decizie pe care cineva trebuie să o ia, nu un detaliu pe care un model ar trebui să îl ghicească.
2. Etichetele de accesibilitate au fost omise
Navigarea breadcrumb este <nav aria-label="Breadcrumb">. Un cititor de ecran anunță acea etichetă; cititorii vizuali nu o văd niciodată. În toate cele șase rulări pe fișier complet și cu instrucțiuni, a rămas în engleză, deși promptul cu instrucțiuni enumera aria-label printre atributele de tradus. Într-o rulare cu instrucțiuni, și aria-label="Search" al butonului de căutare a rămas în engleză.
Metoda pe segmente l-a tradus de fiecare dată, pentru că scriptul său colecta fiecare valoare aria-label, alt, title și placeholder și cerea explicit fiecare dintre ele. Acesta este cel mai puternic argument pentru a extrage atributele de text în mod intenționat, în loc să speri că modelul le observă.
3. Traducerea pe fragmente a păstrat etichetele, dar a stricat propoziția
Metoda pe segmente este sigură pentru marcaj prin construcție: modelul nu vede niciodată o etichetă, așa că nu poate deteriora una. A trecut toate verificările structurale în toate cele trei rulări. De asemenea, a produs singura traducere din test care le-a dat cititorilor instrucțiuni greșite.
Propoziția în engleză este „Type the path to the <library> folder after --out.” Codul inline <code> o împarte în trei fragmente: „Type the path to the”, „folder after” și un punct. Chineză pune aceste cuvinte într-o ordine diferită, așa că un traducător trebuie să mute cele două elemente de cod. Metoda pe segmente nu le poate muta. Toate cele trei rulări au inversat instrucțiunea. Rularea 2 a produs asta (rulările 1 și 3 spun 后 în loc de 之后, cu același sens):
在 <code><library></code> 之后输入 <code>--out</code>文件夹的路径。
Asta se citește „după <library>, tastați calea folderului --out”, inversul instrucțiunii. Toate cele șase rulări pe fișier întreg și cu instrucțiuni au mutat elementele de cod și au făcut corect:
在 <code>--out</code> 后面输入 <code><library></code> 文件夹的路径。
Aceeași împărțire a lăsat spații nedorite acolo unde o etichetă se întâlnește cu text chinez, cum ar fi 前往 <b>设置</b> și <b>书库</b> ,, în toate cele trei rulări pe segmente, câte șase locuri pe rulare. Un browser le afișează ca goluri vizibile, inclusiv înaintea punctuației chinezești. Rulările pe fișier întreg nu au avut niciunul; două dintre cele trei rulări cu instrucțiuni au avut patru sau cinci.
Un verificator structural nu poate prinde propoziția inversată, pentru că fiecare etichetă este exact unde era. Verificatorul nostru raportează când codul inline își schimbă ordinea, ceea ce este normal pentru multe limbi, dar acel avertisment nu poate distinge corect de greșit. În acest test a semnalat toate cele șase traduceri corecte și a rămas tăcut la cele trei greșite, pentru că cele greșite au păstrat ordinea engleză. Doar o persoană care citește propoziția poate spune. Soluția este să trimiteți propoziții întregi, cu etichetele lor inline, traducătorului, ceea ce au făcut rulările pe fișier întreg, și să verificați structura după aceea.
Diferențe mai mici
lang: rulările pe fișier întreg l-au schimbat înzh-CNde la sine. Rulările cu instrucțiuni au folositzh-Hans, cum s-a cerut. Ambele sunt etichete de limbă valide;zh-Hansnumește scrierea (chineză simplificată),zh-CNnumește o regiune. Ghidul W3C privind declarațiile de limbă recomandă declararea limbii pe elementul<html>și nu cu o meta-etichetăContent-Language.- JSON-LD: rulările pe fișier întreg și cu instrucțiuni au tradus valorile
nameșidescriptionși au păstrat JSON valid. Scriptul nostru pe segmente a sărit peste conținutul<script>, așa că datele sale structurate au rămas în engleză, ceea ce va face și un instrument care ignoră scripturile. - Referințe de caractere: rulările pe fișier întreg și cu instrucțiuni au păstrat
›, ,©și referința emoji așa cum erau scrise. Cinci dintre cele șase rulări au rescris intervalul2–5în cuvinte chinezești (2 到 5 sau 2 至 5); o rulare cu instrucțiuni a scris o liniuță simplă în locul referinței, deși promptul său spunea să păstreze referințele. Scriptul nostru pe segmente le-a decodat pe toate și a scris caracterele înapoi, ceea ce afișează la fel. Cel care contează,<library>din interiorul<code>, a rămas escapat în toate cele nouă rulări.
Înainte să traduci: pregătește fișierul
- Marchează ce nu trebuie schimbat. Pune
translate="no"pe numele produselor, numerele de model, șirurile asemănătoare codului din proză și orice altceva care trebuie să rămână așa cum este. Face parte din HTML, nu costă nimic și modelul l-a respectat în toate cele șase rulări cărora li s-a trimis fișierul întreg. Instrumentele pe segmente care îl citesc, ca scriptul nostru, sar complet peste acele elemente. Ghidul nostru despre ce nu trebuie tradus acoperă cum să decizi ce intră pe acea listă. - Decide politica pentru cod. Sunt traduse comentariile din cod? Dar rezultatul exemplu? Este foaia de stil partajată între limbi? Notează răspunsul, împreună cu numele care nu trebuie schimbate, într-un glosar de traducere și dă-l celui sau celor care traduc.
- Păstrează ID-urile în limba sursă. Linkurile din pagină indică valori
id. Dacă cineva traduce unid, toate linkurile către el se strică. Niciuna dintre rulările noastre nu a făcut asta, dar un traducător care „ajută” localizând ancorele o va face. - Colectează textul ascuns. Listează atributele care conțin cuvinte,
alt,title,placeholder,aria-label,valuepe butoane, meta-etichete și JSON-LD, ca să fie verificate și nu uitate. - Nu traduce șirurile JavaScript la fața locului. Mesajele setate de un script, cum ar fi o alertă sau o etichetă de buton creată în cod, necesită un pas separat de localizare în cod. Niciuna dintre cele șase rulări pe fișier întreg sau cu instrucțiuni nu a modificat blocul nostru de script, ceea ce este corect, dar înseamnă că acele șiruri rămân în engleză.
După ce traduci: verifică
-
Rulează verificarea structurală.
python3 check_html_translation.py source.html translated.html --lang zh-Hans --keep ShelfmarkCompară etichetele și ordinea lor, fiecare atribut care nu este text pentru cititor, conținutul
<pre>,<script>și<style>, codul inline, cheile JSON-LD, textul cutranslate="no", comentariile și linkurile din pagină. Avertizează despre atributele text încă în engleză, o valoarelangcare diferă de ce te aștepți, text vizibil care pare netradus, cod inline care și-a schimbat ordinea și spații între text chinez, japonez sau coreean de-a lungul unei etichete inline. Nu judecă calitatea traducerii. -
Citește fiecare propoziție care conține o etichetă inline. Aici s-a stricat sensul în testul nostru. Nu te baza pe avertismentul verificatorului „cod inline reordonat” pentru a găsi aceste propoziții: în testul nostru, traducerile greșite erau cele care păstrau ordinea originală.
-
Deschide pagina într-un browser. Dă clic pe linkurile din pagină, parcurge formularul cu tabulare folosind un cititor de ecran dacă poți și caută goluri în jurul textului aldine și al linkurilor.
-
Pentru limbile de la dreapta la stânga, setează de asemenea
dir="rtl"pe elementul<html>. Ghidul nostru de traducere a cărților RTL acoperă ce se mai schimbă. -
Pentru XHTML, cum ar fi fișierele de capitole dintr-un EPUB, confirmă de asemenea că fișierul este încă XML bine format, de exemplu cu
xmllint --noout chapter.xhtml. Un browser iartă o etichetă neînchisă; un e-reader s-ar putea să nu. Lista noastră de verificare QA pentru traducerea EPUB acoperă restul unui ebook.
Unde se potrivește BookTranslator
Pagina de încărcare a BookTranslator acceptă fișiere .html, .htm și .xhtml alături de cărți și documente, așa că poți încărca o pagină salvată sau un articol de ajutor static ca fișier întreg. Nu am trecut acest exemplu prin BookTranslator pentru acest articol și nu am testat cum gestionează ordinea codului inline, conținutul CSS sau JSON-LD, așa că verifică rezultatul la fel cum ai verifica rezultatul oricărui alt instrument. Vezi prețul înainte de a plăti.
Indiferent ce folosești, fă pașii de pregătire înainte de traducere și verificările după. O pagină cu toate etichetele intacte poate totuși să-i spună cititorului să tasteze ceva greșit. Dacă HTML-ul tău este de fapt documentație scrisă în Markdown, ghidul nostru de traducere Markdown acoperă formatul sursă în schimb.
Obține fișierele de test
Totul din acest test poate fi reutilizat gratuit:
- sample-source.html: exemplul în engleză de 59 de linii;
- check_html_translation.py: verificatorul structural (doar biblioteca standard Python);
- run_llm_html_test.py: cele trei metode, pentru orice server local compatibil OpenAI;
- cele nouă rezultate din folderul outputs, împreună cu check-results.txt și results.csv.
Articole asociate





