Как да преведете HTML файл, без да счупите тагове, атрибути или връзки
Какво да превеждате в един HTML файл, какво да оставите непокътнато и как да го проверите. С примерна страница, безплатен инструмент за проверка и тест с локален LLM в 9 пускания.

За да преведете HTML файл, преведете текста, който хората четат, и атрибутите, които съдържат думи, насочени към читателя, като alt, title, placeholder, aria-label и мета описанието на страницата. Оставете разметката непокътната: имена на тагове, href, src, id, class, скриптове, стилове и всичко, маркирано с translate="no". След това променете една стойност, която лесно се забравя – атрибута lang на елемента <html>, така че браузърите, екранните четци и търсачките да знаят на какъв език е страницата сега.
Опазването на таговете се оказа лесната част. Преведохме 59-редова HTML помощна страница на опростен китайски девет пъти с локален модел, използвайки три метода, и проверихме всеки резултат със скрипт. Всяко пускане запази всеки таг, връзка и ID. Проблемите бяха по-незабележими: моделът преведе ред вътре в кодов блок <pre> във всичките шест пускания, при които изпратихме целия файл, остави aria-label на навигацията на английски във всичките шест, а методът, който по дизайн пази разметката най-сигурно – превеждане на текстовите части една по една – създаде изречение, което казва на читателя да направи грешното нещо, във всичките три свои пускания.
Бърз отговор: какво да превеждате и какво да оставите непокътнато
| Част от файла | Пример от нашата извадка | Да се преведе ли? |
|---|---|---|
| Видим текст | заглавия, параграфи, клетки от таблици, текст на връзки, <label> | Да |
<title> и мета описание | <title>Export Your Library | Shelfmark Help</title> | Да. И двете се показват в резултатите от търсенето и в разделите на браузъра. |
og:title и други социални мета тагове | <meta property="og:title" content="Export Your Library"> | Да, само стойността на content |
alt, title, placeholder, aria-label | alt="The Export dialog with EPUB selected", aria-label="Breadcrumb" | Да |
lang на <html> | <html lang="en"> | Променете го на целевия език, например zh-Hans |
| Имена на тагове и атрибути | <a>, <img>, width, самият aria-label | Не |
href, src, id, class, for, name, type, data-* | href="#choose-format", id="q" | Не |
<code>, <pre>, <script>, <style> | shelfmark export --format epub | Не. Решете отделно за коментарите в кода и примерното изходно съдържание. |
| Текст, зададен чрез CSS | .note::before { content: "Note: "; } | Да, но се намира в стиловия файл, така че го планирайте |
| JSON-LD структурирани данни | "name": "Export your Shelfmark library" | Преведете стойностите на name и description; запазете ключовете и JSON валиден |
Елементи с translate="no" | <span translate="no">Shelfmark</span> | Не |
| HTML коментари | <!-- Generated by the help-center build... --> | По избор. Читателите никога не ги виждат. |
| Символни препратки | <library>, , © | Запазете екранираните екранирани. < не трябва да става истински <. |
Този списък не е наше изобретение. Разделът за атрибута translate в HTML стандарта дефинира „преводими атрибути“: title на всеки елемент, alt на изображенията, placeholder на полетата за въвеждане, content на meta елементи, чието име е известно като преводимо, и lang, за който се казва, че трябва да бъде променен, за да съответства на новия език. Той също така посочва aria-label на ARIA като пример за атрибут, който други спецификации могат да добавят, и казва, че в елемент с translate="no" текстът и стойностите на атрибутите „трябва да бъдат оставени както са, когато страницата се локализира.“
Какво тествахме
Написахме sample-source.html – страница от помощен център за същото измислено приложение за четене Shelfmark, което използвахме в нашия тест за превод на Markdown. Тя съдържа по един пример за всеки ред от таблицата по-горе, плюс няколко капана:
- изречение, разделено от вградени тагове: „Преди да експортирате, направете резервно копие на бележките си. Експортирането копира книгите ви, но не изтрива нищо от Shelfmark,“ като името на продукта е вътре в
translate="no"; - изречение с два вградени
<code>елемента, чийто ред е важен: „Въведете пътя до папката<library>след--out“; - блок
<pre><code>с команда и един ред примерно изходно съобщение,# Export finished: 128 books; - CSS правило, което вмъква думата „Забележка:“ преди абзац;
- връзка в страницата към
#choose-format, връзкаmailto:, форма за търсене и JSON-LD блок.
След това помолихме локален модел да го преведе на опростен китайски по три начина:
- Цял файл. Поставете целия файл и поискайте обратно преведения файл.
- С инструкции. Същото, плюс осем правила: запазете всеки таг и име на атрибут, не променяйте
href,src,id,classи подобни стойности, преведете изброените текстови атрибути и мета тагове, оставете<code>,<pre>,<script>и<style>без промяна с изключение на JSON-LDnameиdescription, спазвайтеtranslate="no", запазете символните препратки и коментарите и задайтеlangнаzh-Hans. - Сегменти. Подходът на инструментите, които извличат текст от HTML: скрипт разделя файла на тагове и текст, пропуска
<code>,<pre>,<script>,<style>и елементите сtranslate="no", изпраща останалите текстови части и текстови атрибути на модела като номериран JSON списък и записва преводите обратно в непокътнатия markup. Той също така сам задаваlang="zh-Hans".
Моделът беше Qwen 3.6 27B (Q4_K_M) в LM Studio, с изключено мислене и температура 0.3, на Apple M4 Max с 64 GB памет. Пуснахме всеки метод три пъти, общо девет пускания, на 27 октомври 2026 г. Скриптът е run_llm_html_test.py, а всичките девет изхода са публикувани без редакция; README изброява всеки файл. Ако не сте настройвали локален модел преди, нашето ръководство за превод с локален LLM покрива настройките.
Това беше малък тест на един модел, една езикова двойка и една страница. Той показва какви проблеми се случват и как да ги хванете. Не класира модели или инструменти.
Резултат: Markup-ът оцеля; три решения – не
Проверихме всеки резултат с check_html_translation.py – скрипт за проверка, който използва само стандартната библиотека на Python. Пълният изход е в check-results.txt, а results.csv съдържа по един ред за всяко изпълнение.
| Проверка | Цял файл (3 изпълнения) | С инструкции (3 изпълнения) | Сегменти (3 изпълнения) |
|---|---|---|---|
Същите 58 тага в същия ред; всеки href, src, id, class е непроменен | 3 от 3 | 3 от 3 | 3 от 3 |
Текстът с translate="no" е запазен, връзката в страницата все още работи, <library> все още е екраниран | 3 от 3 | 3 от 3 | 3 от 3 |
Примерен изходен ред в <pre>, преведен | 3 от 3 | 3 от 3 | 0 от 3 (пропуснато по дизайн) |
CSS content: "Note: " преведен | 3 от 3 | 0 от 3 | 0 от 3 (пропуснато по дизайн) |
JSON-LD name и description преведени | 3 от 3 | 3 от 3 | 0 от 3 (пропуснати по дизайн) |
aria-label="Breadcrumb" преведено | 0 от 3 | 0 от 3 | 3 от 3 |
Изречение с два вградени <code> елемента казва правилното нещо | 3 от 3 | 3 от 3 | 0 от 3 |
| Интервали между китайски текст около вграден таг | няма | 0, 5 и 4 | 6 при всяко изпълнение |
lang на <html> | zh-CN (не е поискано) | zh-Hans | zh-Hans (зададено от скрипта) |
Всяко от деветте изпълнения запази същите 58 тага в същия ред, всеки href, src, id и class, целта на връзката в страницата, коментара, екранирания <library> и името на продукта в translate="no". Ако се притеснявахте, че моделът ще развали разметката на проста страница, той не го направи. Проблемите бяха изцяло в това какво да се преведе.
1. Примерният изход в <pre> беше преведен
Блокът с код в нашия пример завършва с ред от изхода на програмата:
<pre><code>shelfmark export --format epub --covers --out ~/Books/export
# Export finished: 128 books</code></pre>
Във всичките шест изпълнения на цял файл и с инструкции моделът върна # 导出完成:128 本书 на този ред, включително в трите изпълнения, където подсказката казваше да не се променя нищо в <pre>. Самата команда никога не беше докосвана. Моделът третира реда като коментар, а превеждането на коментари е разумен избор в урок. Но този ред е това, което програмата отпечатва, и читател, който го сравни с терминала си, ще види английски. Решете преди превода дали примерният изход и коментарите в кода се превеждат, и кажете на инструмента, или защитете напълно блоковете <pre>.
Изпълненията на цял файл също преведоха CSS content: "Note: " в блока <style>, докато изпълненията с инструкции, на които беше казано да оставят <style> на мира, го запазиха на английски. Нито едно от двете не е грешно само по себе си. Превеждането на стиловото описание е правилно за страница, където CSS е вграден, и грешно за сайт, където едно споделено стилово описание обслужва всички езици. Както и да е, това е решение, което някой трябва да вземе, а не подробност, която моделът да отгатва.
2. Етикетите за достъпност бяха пропуснати
Навигацията с трохи е <nav aria-label="Breadcrumb">. Екранният четец обявява този етикет; зрящите читатели никога не го виждат. Във всичките шест изпълнения на цял файл и с инструкции той остана на английски, въпреки че подсказката с инструкции изброяваше aria-label сред атрибутите за превод. В едно изпълнение с инструкции aria-label="Search" на бутона за търсене също остана на английски.
Методът на сегментите го превеждаше всеки път, защото неговият скрипт събираше всяка стойност на aria-label, alt, title и placeholder и питаше за всяка изрично. Това е най-силният аргумент за извличане на текстовите атрибути нарочно, вместо да се надяваме, че моделът ще ги забележи.
3. Преводът на части запази таговете, но развали изречението
Сегментният метод е безопасен за разметката по своята същност: моделът никога не вижда таг, така че не може да го повреди. Той премина всички структурни проверки и в трите пуска. Той също така произведе единствения превод в теста, който даде на читателя грешни инструкции.
Английското изречение е „Type the path to the <library> folder after --out.“ Вграденият <code> го разделя на три части: „Type the path to the“, „folder after“ и точка. Китайският поставя тези думи в различен ред, така че преводачът трябва да премести двата кодови елемента. Сегментният метод не може да ги премести. И трите пуска обърнаха инструкцията. Пусk 2 произведе това (пускове 1 и 3 казват 后 вместо 之后, със същото значение):
在 <code><library></code> 之后输入 <code>--out</code>文件夹的路径。
Това се чете „след <library>, въведете пътя до папката --out“, обратното на инструкцията. Всичките шест пуска с цял файл и с инструкции преместиха кодовите елементи и го направиха правилно:
在 <code>--out</code> 后面输入 <code><library></code> 文件夹的路径。
Същото разделяне остави излишни интервали там, където таг се среща с китайски текст, като 前往 <b>设置</b> и <b>书库</b> ,, и в трите сегментни пуска, по шест места на пуск. Браузърът ги показва като видими празнини, включително преди китайска пунктуация. Пусковете с цял файл нямаха такива; два от трите пуска с инструкции имаха четири или пет.
Структурният проверяващ не може да хване обърнатото изречение, защото всеки таг е точно там, където е бил. Нашият проверяващ съобщава, когато вграденият код промени реда си, което е нормално за много езици, но това предупреждение не може да различи правилно от грешно. В този тест то се задейства при всичките шест правилни превода и остана безмълвно при трите грешни, защото грешните запазиха английския ред. Само човек, който чете изречението, може да каже. Решението е да се изпращат цели изречения, с техните вградени тагове, на преводача, което направиха пусковете с цял файл, и структурата да се проверява след това.
По-малки разлики
lang: пусковете с цял файл го промениха наzh-CNсами. Пусковете с инструкции използвахаzh-Hans, както беше поискано. И двете са валидни езикови тагове;zh-Hansименува писмеността (опростен китайски),zh-CNименува регион. Насоките на W3C за езикови декларации препоръчват да се декларира езикът на елемента<html>, а не с мета тагContent-Language.- JSON-LD: пусковете с цял файл и с инструкции преведоха стойностите на
nameиdescriptionи запазиха JSON валиден. Нашият сегментен скрипт пропусна съдържанието на<script>, така че структурираните му данни останаха на английски, което е и как ще се държи инструмент, който игнорира скриптове. - Знакови препратки: пусковете с цял файл и с инструкции запазиха
›, ,©и емоджи препратката както са написани. Пет от тези шест пуска презаписаха диапазона2–5с китайски думи (2 到 5 или 2 至 5); един пуск с инструкции написа обикновено тире вместо препратката, въпреки че подсказката му казваше да запази препратките. Нашият сегментен скрипт декодира всички тях и записа символите обратно, което изглежда по същия начин. Единствената, която има значение,<library>вътре в<code>, остана екранирана и в деветте пуска.
Преди да превеждате: подгответе файла
- Отбележете какво не трябва да се променя. Поставете
translate="no"на имена на продукти, номера на модели, кодоподобни низове в прозата и всичко друго, което трябва да остане както е. Това е част от HTML, не струва нищо и моделът го спази и в шестте пуска, които му изпратиха целия файл. Сегментни инструменти, които го четат, като нашия скрипт, пропускат тези елементи изцяло. Нашето ръководство за това какво да не се превежда обхваща как да решите какво да влезе в този списък. - Решете политиката за код. Превеждат ли се коментарите в кода? Примерният изход? Споделя ли се стиловата таблица между езиците? Запишете отговора, заедно с имената, които не трябва да се променят, в глосар за превод и го дайте на този, който или което превежда.
- Запазете ID в изходния език. Връзките в страницата сочат към стойности на
id. Ако някой преведеid, всяка връзка към него се чупи. Нито един от нашите пускове не го направи, но преводач, който „услужливо“ локализира котви, ще го направи. - Съберете скрития текст. Изброете атрибутите, които съдържат думи:
alt,title,placeholder,aria-label,valueна бутони, мета тагове и JSON-LD, за да бъдат проверени и да не бъдат забравени. - Не превеждайте JavaScript низове на място. Съобщенията, зададени от скрипт, като предупреждение или етикет на бутон, създаден в код, се нуждаят от отделна стъпка за локализация в кода. Нито един от шестте пуска с цял файл или с инструкции не промени нашия скриптов блок, което е правилно, но това означава, че тези низове остават на английски.
След като преведете: проверете го
-
Изпълнете структурната проверка.
python3 check_html_translation.py source.html translated.html --lang zh-Hans --keep ShelfmarkТя сравнява таговете и техния ред, всеки атрибут, който не е текст за читателя, съдържанието на
<pre>,<script>и<style>, вградения код, ключовете на JSON-LD, текста сtranslate="no", коментарите и връзките в страницата. Тя предупреждава за текстови атрибути, които все още са на английски, стойност наlang, която се различава от очакваната, видим текст, който изглежда непреведен, вграден код, който е променил реда си, и интервали между китайски, японски или корейски текст през вграден таг. Тя не съди за качеството на превода. -
Прочетете всяко изречение, което съдържа вграден таг. Тук значението се развали в нашия тест. Не разчитайте на предупреждението на проверяващия „вграденият код е пренареден“, за да намерите тези изречения: в нашия тест грешните преводи бяха тези, които запазиха оригиналния ред.
-
Отворете страницата в браузър. Кликнете върху връзките в страницата, преминете през формуляра с екранен четец, ако можете, и потърсете празнини около удебелен и свързан текст.
-
За езици с писане от дясно на ляво също задайте
dir="rtl"на елемента<html>. Нашето ръководство за превод на книги с RTL писане обхваща какво друго се променя. -
За XHTML, като файловете с глави в EPUB, също потвърдете, че файлът все още е добре оформен XML, например с
xmllint --noout chapter.xhtml. Браузърът прощава незатворен таг; електронният четец може и да не го направи. Нашият контролен списък за QA при превод на EPUB обхваща останалото за една електронна книга.
Къде се вписва BookTranslator
Страницата за качване на BookTranslator приема файлове с разширения .html, .htm и .xhtml заедно с книги и документи, така че можете да качите запазена страница или статична помощна статия като цял файл. Не сме прекарвали тази извадка през BookTranslator за тази статия и не сме тествали как се справя с реда на вградения код, CSS съдържание или JSON-LD, затова проверявайте резултата по същия начин, по който бихте проверили резултата от всеки друг инструмент. Виждате цената, преди да платите.
Каквото и да използвате, направете подготвителните стъпки преди превода и проверките след това. Страница с всички непокътнати тагове все още може да каже на читателя да напише грешното нещо. Ако вашият HTML всъщност е документация, написана на Markdown, нашето ръководство за превод на Markdown разглежда изходния формат вместо това.
Вземете тестовите файлове
Всичко от този тест е свободно за повторна употреба:
- sample-source.html: английската извадка от 59 реда;
- check_html_translation.py: структурната проверка (само стандартната библиотека на Python);
- run_llm_html_test.py: трите метода, за всеки локален сървър, съвместим с OpenAI;
- деветте резултата в папката с резултати, заедно с check-results.txt и results.csv.
Свързани публикации





