This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Wednesday, 24 June 2026
Cloudflare's "Markdown Mode" дає штучний крейлер чистий текст замість відтвореного HTMLM SK3 Оператори StyloBot отримують таку ж здатність за допомогою StyloExtractMSC4 запускаючи локально на вхідній шлюзі Stylo BotМSK5 достатньо швидко, щоб сидіти на гарячій доріжки, без жодних змін на дохідному сайті. Це те, що робить Styloextract\M SK8 як він підключається до Stylobot\Mska9 що собаки з 'їдаються за допомогою lucidVIEW спіймали\Mска10 і що\Mске11 все ще не працює\M Ska12
Cloudflare завантажує функцію, в якій:, якщо відомий штучний crawler просить сторінки , краєчок відповідає за Markdown репозицію тіла, а не повного HTML МSK2 Клівер отримує реальну zawartość без жодного хрома M SK3 без жодної Java-скрипта , без баннеров куки MSC5 Пользователь(а)
Архітектура очевидна ззовні.: classify the request as a crawler (Cloudflare already does this), pull the page through some contentM SK3extraction layerMSC4 project to Markdown, return that instead of the HTMLMSL6 Класифікатор - це цікава частина, якщо ви' Cloudflare and the extractor is the interesting part if you' anybody else(МSK9)
Те ж саме для оператора StyloBot є трьома обмеженнями
З боку StyloBot цього вже зроблено: ланцюг детектора класифікує алгоритми crawlers (BotType.AiBot) з такою ж швидкістю - затримкою маршруту, як і будь-який інший вирок DetectionPolicyMiddleware в 7.x надсилає policies дій, названі вироком ,, таким чином проводячи extract-markdown policy для "AiBot на /docsM SK2*" - це конфигурація ♫ ♫ МSK1 ♫ Поганий шматок був самим экстрактором ♫
Те, що's StyloExtract: HTMLM SK2toMSC3Markdown шар, який поєднується з схемою StyloBot 's detectionMST5 Інтеграційний корабель у вигляді маленького пакету адаптаторів МSK6Mostlylucid.BotDetection.StyloExtract) і правило, яке запускає це, це шість рядків JSON . Оператор відкидає пакет в МSK2 додає правило МSK3 і штучний crawler починає отримувати значок вниз за ті самі URL, які досі служать HTML для людей M SK4
Якщо ви читаєте спецификацію на лицевій основі, то це вирішена проблема. Є десятки бібліотек. МСК4. В дійсності, всі вони деградують на реальних сторінках, тому що вони сприймають документ як плоский контент і сторінку як масштабування.
Справжня-світові веб-сторінки - це M SK1 котлована płytа . Artykuł, який ви насправді хочете, живе в двох або трьох обгортаннях <div>s з двох або трьох сотень. Наївний HTMLМSK1на МSK2Biblioteka Маркдау перетворює всеМСК3 кожен наві-конектМ СК4 кожен баннер баннер cookieMСК5 кожен футрM СК6 кожен пов 'язанийМ סК7 пост-сайдбарМ SК8 кожен кнопок обмінуМ ็ СК9 кожен модул, щоM ็ SК10 прихований CSS, але присутній в DOMМ ШК11 Клокер попросив про статтюМ М СК12 ви передали йому цілий файл М ЦСК13 КБ Маркдау з статтю закопаною десь в мережі M ШК14
Отже, екстрактор повинен виконувати дві функції.
Це найважче визначити. МСК0. У МСК1 є ціла галузь наукової літератури виведення веб-контенту і встановлений Benchmark - WCXB. Коли я почав читати, то знаходився інструментом Python під назвою Trafilatura. Я переніс навантаженняM SK2на основі ідей до .NET та додав шар Trafiluca doesnMSC4t haveMska5 perMske6host навчання з шаблонами за допомогою структурних відбитків пальців.
Форма::
parse HTML → clean → fingerprint the structure → does this fingerprint
match a template I've seen on this host before?
yes → apply the cached extractor → render
no → run the heuristic classifier → induce a fresh extractor →
cache it under this host's fingerprint → render
Першого разу, коли ворота бачать сторінку з домашнєї мережі, вони платять за повну эвристичністьM SK1 вартість класифікатора МSK2μs для середньої сторінки). Кожна наступна сторінка з того домашнего сервера, яка відповідає структурному відбитку пальців, отримує замість цього ввімкнений екстрактор , який є лише кількома CSS МSK5 пошуки виборця MSC6 μsMST7 Схожі МСК8host-сторінки з однаковим шаблоном МСК9 яка є більшою частиною веб-сайту M SK10 рухаються по швидкій дорозі . Страні з новими інтерфейсами викликають переробку MSC12
Опинка пальців - це малюнок MinHash над стандартизованим DOM-оточенням маршрутуM SK1 з LSH-бандером на вершині для суб--мільйсекундної зондуМSK3 Математика співпадіння неважлива МSK4 не має значення для цього artykułу ; важливим є те, що це робить навчання за один учасника МСК6 досить дешевим для запуску на кожному запиті М СК7
На стороні рендеру є петля, яка дає мені змогу заробляти на цьому.
Перша версія StyloExtract випустила знак Марка-Даун , переміщуючи класифіковані блоки та проектуючи element.TextContent.Trim() в вихідні коди. Кожен блок став абзацомM SK1 Кожен заголовок став # text незважаючи на те, чи це H1 чи HМSK1 Анкори зруйновані до оголеного тексту МSK2 Листи втратили кулі . Блоки коду втратили паркани МСК4 Столи порівнювалися до коми М СК5 відокремлені запуски MСК6
Це технічно "Markdown." Це ' також непотрібно МSK3 crawler asks for Markdown to уникати аналізу хрома, і ми дамо йому стіну абзаців, де єдиний сигнал є інколи простим - текстові знаряддя фрази МSK2 Весь сенс служення Марка-Дауна полягає в тому, що структура несає інформацію
Отже, наступна версія StyloExtract рухається DOM кожного класифікованого блоку контенту і випускає реальні GFM:
<h1> через <h6> перетворюється на 1 через МSK1 # символи<a href> стає [text](href)<em> і <strong> підтримувати їх<code> залишає зворотний знак, <pre> стає замкненим блоком з language-x carried across<ul> і <ol> випускати справжні пулі та числові листи<blockquote> примітки кожного рядка з > ( і багатозначнийM SK1запис отримує > body\n>\n> body конвенція)<table> відтворюється за допомогою алгоритму шкали WHATWG- з відповідним розтягом рядків / розтргів рядків чи вони "'" вживають в просі, чи самотні <figure>Глокер - це один StringBuilder на блок , внутрішній буфер скарбів, повторюваний через клітини / списку об 'єктів МSK2 і один перехід через DOM
Похідник - це також частина, яка зламалась першими.
lucidVIEW - це маркер-відрізок, який я створив разом з StyloExtract. Продукт - це веб-браузер - сторонній читач, який бере URL M SK2 завантажує його , запускає StyloEXtract над відповіддю MSC4 і показує отриманий маркерні відрізки МSK5 Застосований випадок: " Я хочу прочитати це блоговий пост на повільному підключенні без Java-скрипта Mska7 чи на телефоні без товарного запасу M Ska8 або просто тому, що оригінальна сторінка має око MSKA9 розмиканий CSS Мska10 Втілення - це Styloextract на сервері Mска11 маленький рендератор маркерних відрівок в браузері Мска12 і нічого іншого М Ska13
Те, що lucidVIEW дав мені - це петлю для собаки з зубами. МСК0. Другий випуск StyloBotу, МСК1, серія статей говорить про панель, як про поверхню для собак, МSK2, що МСК3 є правильним на рівні протоколу. МSK4. Але панель читає дані, які генерує детектор, і робить їх я. I'm в циклі МSK2 I\ ' я пробачу багато дивних можливих виходів, якщо підрахунки будуть правильними
lucidVIEW перетворює Маркдау на доштовховий читач (meM SK1 але читає зміст ). Це МSK3 має ту ж форму, як і пристрій для використання Шриверки штучного інтелекту МSK4 хтось споживає мій вихідний код речовина, не в якості інструментарію . Коли виход неправильний МSK2 ви бачите його відразу МСК3 Там М СК4 немає абстрактного шару між М СК5 экстрактор виробив X М ס К6 і М S К7 Я читаю X M С К8
Отож, я відкриваю lucidVIEW, дивлячись на мій власний блоговий індекс. Карти відтворюють . Потім я перегортаю МSK2 Кожен блог МСК3 карта з минулим першим відтворюється як [Post title](/blog/post) - літеральний скобковий текст - замість сліпої, натисливої посилання
unit-test suite є зеленим [Post title](/blog/post). Марка-даун неправильний в будь-якому разі
Індекс блогу збудований за допомогою Tailwind. вихід Tail wind встромлений для читабельностіM SK1 кожен обкладач div сидить на двох місцях далі, ніж його батьківський . Коли ви дістаєтеся до справжнього анкера для блогуMSC3 карта зв 'язок, джерело HTML виглядає такою ж як
<section class="...">
<div class="container...">
<div class="grid...">
<div class="card...">
<a href="/blog/post-a">Post title</a>
...
Рухник'с текстомМSK1помічник для obsługiM SK2 AppendEscapedInline, рухає runs білого простору в один простір . Всередині одного виклику він робить це правильно МSK2 функція зберігає prevWs прапорець, який пригнічує послідовне виділення білого простору, видає:. Між wywołaннями: , прапорець відпочиняється:
Чотири обкладинки індикації, чотири тексти - нот=- двоє літер з білим простором МSK3 чотири сплющені місця M SK4 Соціальний знак ' встромлений Mska6 код M Ska7 правило блокування реагує на чотири місця [Post title](/blog/post) lands on a line that starts with four spaces. Markdig parses the entire line as a code blockMSC1 The bracket text renders as literal text. The link is deadM SK3
Тест на одиниці проходить, тому що тест затверджує стрічку [Post title](/blog/post) з 'являється десь в вихідному коді.
Постановка - дві лінії: : на лінії, МSK1початкова, , просте число prevWs = true тож першим лідерський білий простір з кожного вузла стає пропущеним замість emitted. Лідерський білій простір всередині встромленої HTML ніколи не досягає вихідного коду
Цікаво те, що тест повинна стверджували. поверхняM SK1текст .Contains() перевіряє символи є присутнім. Вони булиM SK1 Вони просто були в неправильному CommonMark блоковому типу. Все, що мені потрібно було структурна ствердження: розшифровує ходунок ' його вихідний код за допомогою реального комп 'ютера CommonMark, іsert paragraphs are paragraphsM SK2 links are links, no spurious code blocksМSK4 MarkdigMSC5s AST gives you that for freeMska6 Таким чином, виправлення помилки приземлилося з тестом регресії Mska7 and the regression test landed with a lint harnessM Ska8 small helper that takes any walker outputM ska9 parses it with Markdig Mска10 and asserts Мska11
LinkInline в АСТЩоб довести, що lint має зуби, Я повернув оригіналний ремонт і запустив комплект lint. Точнісінько один тест провалився - той, який використовує чотириM SK3 непотрібний МSK4 зразок ковпака . Знову підпорядкувати ремонтMSC6 всі пропущеніMスク7
Ця одна перевірка тепер проходить на кожному тесті на ходунки в наборі.. Дальне відхилення однієї категорії структурно фіксуються. , не через співпадіння стрічок. МSK2 Це означає, що я M SK3 знаходжу їх у CI, а не у lucidVIEW.

У кожному продукті є етап, коли тести на одиниці є зеленими і демо працює, і оператор встановлює правильні флаги конфігурації, і ви відправляєте реліз, а через день пользователь відкриває проблему, говорячи: "" МСК1 "", це не працює. МСК2 "", не працює з реальним змістом. МSK3 "". Кожний продукт потрапляє на це. . "". Чесно кажучи, тестові пристрої та контент для демонстрації є стерильними, так само як і реальний контент.
. Фраза """, "" dogfooding "" і "" МSK2 "" вживаються повільно, а в цьому випадку це означає щось специфічне. окремий продукт, з окремими користувачами стається споживати Output StyloExtract' як поверхню продукту. Якщо lucidVIEW показує пошкоджений Маркдау , lucidVIEW МSK2 користувачі скаржаться на lucidVIEW
Ця відокремлення має значення. Якби lucidVIEW був пристроєм для тесту StyloExtract, я б написав його із стерильним вмістом, бо знаю, що подобається екстрактору . Тому що lucidVIEW існує в своєму світі МSK4 він вказує на мій справжній блог МСК5, який використовує Tailwind М СК6, що виробляє встромлений HTML-об 'єкт, що запускає клас багів M СК7 Баг з' явився за п 'ять хвилин використання продукту як користувача MСК8
Багато випущень v1.7.x повертаються до цієї ланцюги . СтруктурованийM SK2виход ходуча (v\1.7.0) відправлений через те, що перша версія lucidVIEWМSK5 була нерозбірливою, коли StyloExtract випустив плоскі абзаци МSK6 ГоловнийMSC7 whitespace fix МСК8v МСК9 відправлен через те що постMСК10version ходучка була помітно зламана на сайтах TailwindМ СК11 ВиходM СК12quality lint harness відправлений тому, що я хотів, щоб наступний клас बगу був CIMSSK13caughtMS.
Pattern' не новий споживацький продукт паралельно з вашим будівельний продукт, і споживайте свою власну інфраструктуру через споживача . Рівень błędów на шарі інфраструктури знизується в залежності від того, наскільки велика поверхня споживача клас Защитність на рівні інфраструктури зростає з кожним наступним моментом, коли споживач зауважує, що ви не думаєте написати тест для
StyloExtract / lucidVIEW - один із прикладів шаблону, який я запускаю на кожному проекті
flowchart LR
PB[visible product<br/>behaviour] --> TR[test/review<br/>loop]
TR --> AP[architectural<br/>primitive]
AP --> RL[reusable<br/>library]
RL --> WE[written<br/>explanation]
WE --> LG[LLM-readable<br/>grammar]
LG --> NP[next<br/>product]
NP --> PB
База błędów у продукті. Поправка перетворюється на структурне твердження M SK1тест МSK2відкладання циклу МSK3 Затвердження перетворується на примітив, який інші речі можуть використовувати . Примітив перетвориться на бібліотеку \ . Бібліотека пише про . Письмо створює LLM \ МSK7 читабельну граматику довкола кодової бази | МSK8 граматика робить наступний продукт швидшим для побудови | . Наступний продукт накладається на нові баги в бібліотеках, які залежать від нього \
Граф залежності, який це створює – МСК0 – в усіх проектах, які я запускаю. МСК1 – схожий на МСК2
flowchart TB
LV[lucidVIEW<br/>Avalonia markdown reader]
SB[StyloBot<br/>detection gateway]
SF[StyloFlow<br/>policy + flow runtime]
SE[StyloExtract<br/>HTML → Markdown]
NA[mostlylucid.Naiad<br/>Mermaid renderer fork]
DA[mostlylucid.dagre<br/>graph layout]
EP[mostlylucid.ephemeral<br/>signal + sketch primitives]
UT[Mostlylucid.Avalonia.UITesting<br/>Avalonia UI test framework]
SB --> SF
SB --> SE
LV --> SE
LV --> NA
NA --> DA
SE --> EP
SF --> EP
LV -.tests via.-> UT
Mostlylucid.Avalonia.UITesting закриває еквівалентну петлю на боці робочого столу. StyloExtractM SK1Playwright закриває її на безголовній стороні-web sideMSC3 Те ж саме візерунок , різна поверхня МSK5 тестування M SK6 автоматизація дозволяє аутентичній петлі фактично перевірити поведінку продукту, яку вона повинна була полагодити
Торгівля реальна. Граф неоднозначнаM SK1 Ошибка в mostlylucid.ephemeral протікає через StyloExtract і StyloFlow в StyloBot та lucidVIEW. злегшення - це часMSC1boxed releases M SK2не викривлення funkcji, версії рухаються, коли сфера, яку вони revendicaють, рухаєтьсяМSK4 і кожен шар має свій власний тестовий наборMST5 перевагою є те, що я можу працювати над усіма ними за тиждень, а вартість контексту - перемикання між ними залишається низькоюMSL7 тому що кожна пластина має однакову формуMСК8 примітивну МСК9 бібліотекуMSК10 пояснениеM СК11 споживача М СК12
Це також означає, що написання цієї статті - не "'", а "" МSK1 "", як результат транспортування "" StyloExtract "". МSK2 "". Письмо є одним із етапів.
Це працює для мене, тому що закриваючи цикли - ось як я думаю.
flowchart LR
URL[URL bar] --> Fetch[HttpClient GET<br/>Accept: text/markdown, text/html]
Fetch --> Sniff{Content-Type}
Sniff -->|text/markdown| Render[LiveMarkdown.Avalonia]
Sniff -->|text/html| Convert[HtmlToMarkdownService]
Convert --> Sparse{< 200 chars +<br/>SPA markers?}
Sparse -->|yes| Stub[Stub: needs JS,<br/>open in browser?]
Sparse -->|no| Render
Stub --> Render
Чотири описи пакетів і одна служба:
public sealed class HtmlToMarkdownService
{
private readonly IHtmlDomParser _parser = new AngleSharpHtmlDomParser();
private readonly IDomCleaner _cleaner = new DomCleaner();
private readonly IBlockSegmenter _segmenter = new BlockSegmenter();
private readonly IBlockClassifier _classifier =
HeuristicBlockClassifier.LoadFromEmbeddedResources();
private readonly IMarkdownRenderer _renderer = new TypedMarkdownRenderer();
public string Convert(string html, Uri? sourceUri = null)
{
var doc = _parser.Parse(html, sourceUri);
_cleaner.Clean(doc);
var blocks = _classifier.Classify(_segmenter.Segment(doc));
return _renderer.Render(blocks, ExtractionProfile.RagFull);
}
}
Те, що ' це те, що МSK1 Статус МSK2 іконка панелі показує, який шлях був запущений МSK3 прямий MD / конвертований एमСК5 SPAstub мСК6 так, що коли щось виглядає неправильно, пользователь може показати правильний шар МСК7

flowchart LR
HTML[HTML] --> P[AngleSharpHtmlDomParser]
P --> C[DomCleaner<br/>strip script/style]
C --> S[BlockSegmenter<br/>candidate subtrees]
S --> K[HeuristicBlockClassifier<br/>role + score]
K --> W[DomMarkdownWalker<br/>GFM per block]
W --> R[TypedMarkdownRenderer<br/>profile gate]
R --> MD[Markdown]
Розшифровувач + чистіший - це упаковники AngleSharp . Цікавий код починається з сегментації МSK2
Сегментер. Пройдіть тіло, зануріть будь-яку семантичну позначку M SK1main/article/section/h1-h6/ul/pre/...) плюс будь-яка <div>/<section> що МСК0 текст МSK1 важкий або має багато дітей . Все інше надто маленьке, щоб бути задоволеним
public IReadOnlyList<IElement> Segment(IDocument document)
{
if (document.Body is null) return Array.Empty<IElement>();
var result = new List<IElement>();
Walk(document.Body, result);
return result;
}
private static void Walk(IElement element, List<IElement> sink)
{
if (SemanticTags.Contains(element.TagName)) sink.Add(element);
else if (IsBlockyDiv(element)) sink.Add(element);
foreach (var child in element.Children) Walk(child, sink);
}
Классifier. Оцінка кожного кандидата: МСК0 , Не вибирайте "-". Перетинаються лауреати . BlockRole (Главний змістM SK1 ЗаголовокМSK2 Навігація, Котелляна плитаMSC4 Повторне об 'єктMska5 Мska6 Кожен вибраний блок отримує DOM, який переходить в структурований знакопадMска7
foreach (var element in selected)
{
var role = ClassifyRole(element);
yield return new ExtractedBlock
{
Role = role,
Text = element.TextContent.Trim(),
Markdown = ShouldRenderMarkdown(role) ? DomMarkdownWalker.Render(element) : "",
Links = ExtractLinks(element),
XPath = XPathBuilder.For(element),
// ...
};
}
Вокер. Один StringBuilder, один DOM pass. <a> це місце, де проживав баг v1.7.1
case "a":
var href = el.GetAttribute("href") ?? "";
if (href.Length == 0) { WriteInlineChildren(dest, el); return; }
dest.Append('[');
WriteInlineChildren(dest, el);
dest.Append("](").Append(href).Append(')');
return;
( Це був виправленням ' тут не було МSK2 Це було в AppendEscapedInline,, що fed провідного білого простору в dest до того, як цей випадок коли-небудь працював. Чотири місця попереду [ дозволяє CommonMark аналізувати строк як кодовий блок.)
Рендерер. Двері по профілі. RagFull зберігає статтю-контекст M SK1Breadcrumb, Спільні зв 'язкиMSC3 і викидає хром (FooterMST5 HeaderM ST6 CookieBannerM st7 NavMst8 MainContentOnly зберігає лише тіло. AgentNavigation зберігає тільки наві ( для плавання - відкриток зв 'язку M SK2
return p switch
{
ExtractionProfile.RagFull => b.Role is not (BlockRole.Footer or BlockRole.Header
or BlockRole.Advertisement or BlockRole.CookieBanner or BlockRole.Boilerplate
or BlockRole.Unknown or BlockRole.PrimaryNavigation or BlockRole.SecondaryNavigation),
ExtractionProfile.MainContentOnly => b.Role is BlockRole.MainContent or BlockRole.Article
or BlockRole.Heading or BlockRole.Summary or BlockRole.Table or BlockRole.CodeBlock
or BlockRole.RepeatedItem,
ExtractionProfile.AgentNavigation => b.Role is BlockRole.PrimaryNavigation
or BlockRole.SecondaryNavigation or BlockRole.Breadcrumb or BlockRole.Form,
_ => true
};
StyloExtract'his heuristic operates on the static HTML the server returned . ThatMSC2s fine for SSR sites M SK3Wikipedia, GitHubMska5 most news article URLsMSKA6 It breaks on SPA shells where the visible content is hydrated client Mska7side from a JSON blobM Ska8 __NEXT_DATA__, __NUXT__, __APOLLO_STATE__. Статичний HTML має мета-теги + скелет МSK2 і немає тіла для класифікатора, щоб знайти
Mostlylucid.StyloExtract.Playwright підключення вздовж трубопроводу. Він реалізує IRenderedHtmlFetcher, підштовхує безголовний хром через Playwright , чекає на впиту МSK2 і повертає постM SK3 JS HTML до решти экстрактора :
public async Task<RenderedHtmlResult> FetchAsync(
Uri uri, RenderOptions? options = null, CancellationToken cancellationToken = default)
{
var page = await _context.NewPageAsync();
await page.GotoAsync(uri.ToString(), new PageGotoOptions
{
WaitUntil = WaitUntilState.NetworkIdle,
Timeout = options?.NavigationTimeoutMs ?? 15000,
});
var html = await page.ContentAsync();
await page.CloseAsync();
return new RenderedHtmlResult { Html = html, FinalUrl = page.Url };
}
Те ж саме Parser, ,, чистіший, МSK1, сегментатор, МСК2, класифікатор, MСК3, ходівник, M СК4, рендератор вниз по течії, М СК5. Єдина різниця в тому, що вхідний HTML зараз містить гидратований DOM, який створив ДС
flowchart LR
URL[URL] --> Choice{Render mode}
Choice -->|static| HTTP[HttpClient]
Choice -->|js-required| PW[PlaywrightHtmlFetcher<br/>headless Chromium]
HTTP --> Pipeline[parse → clean → segment<br/>→ classify → walk → render]
PW --> Pipeline
Pipeline --> MD[Markdown]
Це правильне рішення, коли оператор запускає сервер StyloExtract-замість безголовного браузера є розумною залежністюM SK1 CLI відправляє два бінарні для точного поділу: stylo-extract МSK0AOT, МSK2MBM SK3 статичний- тількиMSC5 і stylo-extract-playwright (~120MB один раз Playwright ' пакет браузера політає МSK2 JS
lucidVIEW не використовує його. lucidVIEW - маркер-відрізок; його ідентичність M SK1 без хрома , без браузерного двигуна МSK3 без МSK4 Мб залежності від однієї характеристики M SK5 Bundling Playwright помістить безголовний браузер всередині додатку, чия тональність - відсутність однієї. . Стап SPA, що описаний poniżej, є правильним відповіддю lucidVIEW М SK7 з точки зору МSK8 сказати користувачам, що сторінка потребує браузеру.
Чотири не "-", що сформували lucidVIEW , МSK1 , невдачі ,
Спектр, який керував v1.7.0. Перші emitовані плоскі абзаци (element.TextContent.Trim() за блок. МСК0. Вікіпедія була нерозбірливою. МSK1. Карти блогу втратили кожну лінію. .. Натомість, я написав: docs/styloextract-markdown-spec.md вираховуючи, що бракувало: рівні заголовківM SK1 ланцюгові запуски , переліки МSK3 таблиці ГФМ МСК4 блокові зображення М СК5 з чотирма URL-адресами репродукторів M СК6 Структурований MСК7 пішохідна робота в vMСК8 реалізує це.
Страницы SPA. bbc.com/news Next.js: статичний HTML - це мета-теги + a __NEXT_DATA__ JS. StyloExtract правильно повертає M SK1 символ, тому що ' не має тіла МSK3 lucidVIEW тепер понюхає для відомих маркерів кар 'єри МSK4__NEXT_DATA__, __NUXT__, __APOLLO_STATE__, data-reactroot, ng-version=, __REMIX_DATA__) іM SK1 на вузькому выході + маркер МSK3 робить неправильний МSK4 "Ta сторінка використовує {フレーмワークM SK2 lucidVIEW не запускає JavaScript. Відкрий у браузеріMSC4 Article URLs (/news/articles/<id>) служи реальним <main> і перетворити чисто. Веб-сайт МSK1 асимметрія artykułуM SK2 не поганий конвертер.

Семантика-бесплатні сторінкиМSK1 example.com не має <main>, ні <article>. Хирологія правильно не повертає нічого . Такий же стрімкий потік запам 'ятовує це M SK2
Правильно-ноM SK1непотрібне випромінювання . Filtr категорії мого блогу' це <select><option>. Похідник не знаходить нічого <a href>, видає текст варіанту як один абзац "Це все МSK1NET МSK2 мSK3s M(1) АCP МСК5 штучний інтелект МК6 Правильно (можливими варіантами є МSK1 не пов 'язані с' язки МSK2 але візуально жахливі . майбутній прохідник може виявити <select> і видавати список визначення, або [42 categories] підсумок.
До того ж, одна галерея, що з 'явилася, опираючись на очевидний короткий шлях. . Коли видобуток є невеликим, спокушання наступне: " повертаєшся до Джина Reader МSK2 r МSK3 Джина мSK4 Ай एमSK5 Трафілатура \ ." \ lucidVIEW не робить \ МSK7 \ t \ . \ Перевод URL-адреса користувача через третю \ МSK9 \ сторонній читач робить читачем витіком конфіденциальності. | ; \ кожен URL, який відвідує користувача, проходить через якийсь інший оператор. ' \ журнали. ♪ МSK12 \ Лінія зворотнього зв' язку залишається локальною. ♫ : \ прямий відбиток \ мSK14 \ а потім HTML через StyloExtract | МSK15 \ і метаданніstub з <meta> / og: ярлики, потім M SK1открий у браузері ?" кожен крок StyloExtract інший вихід з одного і того ж джерела, або синтезує дані, які ми вже маємо
Що собакова ланцюжка добре знаходить, це поламаний результат на хорошому.
Я маю курити-бігача зараз, що бере дюжину реальнихМSK1світніх сайтів і відкидає экстрактораM SK2 виході. На структурно kooperatивній півкулі МSK4 новини ( BBCMSC6 ГуардіанMСК7 Вікіпедія МСК8 репозиція GitHub READMEsМСК9 Призрака М СК10 ҐорґМ СК11 журнал змін M СК12 хакерські новини | МССК13 герістичний класифікатор знаходить головний контент чисто, а ходівник виробляє читача | MСК14 рейтинги знизування маркеру | ССК15 десят до тридцяти кілобайт чистої прозі на сторінку | ВСК16
На іншій половині - Allbirds нічого. Нуль блоків контенту MainContent . Кожен кандидат отримує демоцію на boilerplate, тому що сторінка не використовує <main> або <article> і назви класів не співпадають з будь-якими шаблонами в рамках
Додавати більше записів до цього файлу JSON є очевидним кроком.. Це ' також ламати-aMSC3moleM SK4 Кожний тематичний магазин відправляє нові назви класів.МSK5 Кожна релізація Shopify змінює їх.
Справжньою справою є тренована модель. ПерМSK1дібні характеристики елементів M SK2 ідентифікація знаку МSK3 клас - назви хеш-букетів М SK5 текст M SK6 довжина , зв 'язок MSC8 щільність MSL9 фігура братів і сестер МСК10 присутність предків М СК11 до маленького відхилення М סК12 закріплений класифікатор М S К13 тренований на корпусі з маркуванням WCXB M С К 14 вивезений до ONNX М С К 15 викликаний з М С К 16 NET через Microsoft.ML.OnnxRuntime. Вektor властивості МSK1 на кожного кандидата МSK2 ~10μс висновків на один елемент \ , \ \ МSK5 \ MB модельного файлу , \ AOT \ мSK7 \ чистий \ . \ Модель збільшує геристичне число \ {\displaystyle {-} , воно не заміняє } МSK10 \ } не заміщає його \ '-\ , стимулюючи елементи герістичне число, що погіршується, коли рівень самодовіри є високим \
Дизайн для цього розроблений в repo StyloExtract (docs/ml-classifier-v2-design.md). Implementation is notM SK1t done. The thing it 's blocked on isnMSL4t engineering effortM SL5 itMsl6s the operator question of МSL7 ship a МSL8 MB ONNX Runtime native binary into the gatewayMKL9s deploymentMCL10 or keep ML as a separate optional pack the operator opts intoM CL11 The optional MKL12pack answer is the right one for a FOSS pack ecosystemM KL13 but it means the model is MSL14t on by defaultM LKL15 which means most operators won M CL16t get it М CL17 which mean the heuristic carries most of the production load anyway MCL18
В проміжній періоді - МСК0 - оператори отримують ручний escape hatch, :, оператор, МSK1, авторизовані шаблони YAML, МСК2, один файл на домашню установку, MСК3, розшифрований AOT, M СК4, чистий, М СК5, гарячий, М S К6, переважаючи провідник для цього домашнєї установки. weird-shopify-tenant.com виробляє пустий знак "" Markdown "", ",", пише файл YAML з п 'ятьма лініями "" МSK1 "", в якому написано: """ для цього хоста, "". .product-description-body", кидає його в config/templates/, і час запуску підбирає його через FileSystemWatcher за кілька секунд
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.