[Bug]: whitespace-only inline elements are removed from cleaned_html, merging words in raw_markdown (prose, not only <pre>/<code>)
Los mantenedores suelen responder en 1 día
Ya se ha fusionado un pull request relacionado.
- #2329 de @drakeo338 — fusionado
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 83/100
Línea de trabajo
Comienza en content_scraping_strategy.py, en remove_empty_elements_fast, y rastrea cómo se gestionan el texto y los tails de los elementos eliminados. Reproduce el problema con la entrada HTML sin procesar proporcionada de /crawl usando content_source="cleaned_html"; se considera terminado cuando los elementos inline que solo contienen espacios en blanco ya no unen palabras en raw_markdown, preservando el comportamiento existente para el resto del contenido.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
crawl4ai version
0.9.3 (Docker image, REST /crawl and /md)
Expected Behavior
Text whose words are split into inline elements keeps its word spacing in raw_markdown, as it does when the markdown is generated from the raw HTML.
Current Behavior
remove_empty_elements_fast (content_scraping_strategy.py) removes whitespace-only inline elements outside <pre>/<code>, and the whitespace inside them goes with them. With the default content_source="cleaned_html", raw_markdown then merges the words: Hi there becomes Hithere.
Real-world trigger: pages whose scripts split text into per-character or per-word spans for animation. Today https://example.com rewrites its paragraph into one <span> per character with each space in its own <span> </span>. Through /md or /crawl (default cleaned_html), the paragraph comes back as Thisdomainisforuseindocumentationexampleswithoutneedingpermission.. Text on the same page that is not split into spans keeps its spaces.
Is this reproducible?
Yes
Inputs Causing the Bug
POST /crawl
{
"urls": ["raw:<html><body><p><span>H</span><span>i</span><span> </span><span>t</span><span>h</span><span>e</span><span>r</span><span>e</span></p><p>plain text stays fine</p></body></html>"],
"crawler_config": {"type": "CrawlerRunConfig", "params": {"cache_mode": "bypass",
"markdown_generator": {"type": "DefaultMarkdownGenerator", "params": {"content_source": "cleaned_html"}}}}
}
Output
content_source |
raw_markdown |
|---|---|
cleaned_html (default) |
Hithere\nplain text stays fine |
raw_html |
Hi there\nplain text stays fine |
cleaned_html no longer contains the <span> </span>:
<p><span>H</span><span>i</span><span>t</span><span>h</span><span>e</span><span>r</span><span>e</span></p>
Root cause
In remove_empty_elements_fast, a childless element whose stripped text has fewer than word_count_threshold words is removed. A whitespace-only element has zero words, so it is always removed. The function preserves the removed element's .tail, but not its own .text, so the space disappears. #1181 hit the same thing inside code and was fixed (v0.7.8) by skipping elements inside <pre>/<code>. Prose split into inline elements has no such guard. #2110 reports the same family of failure in PruningContentFilter on the fit_markdown path.
Suggested fix
When removing an element whose text is whitespace-only, keep the whitespace: append a single space to the previous sibling's .tail (or to parent.text), as is already done for .tail. Alternatively, never remove whitespace-only inline phrasing elements (span, em, strong, b, i, …).
Workaround
DefaultMarkdownGenerator(content_source="raw_html") (via /crawl; /md cannot set it). On the pages we checked it keeps the same words and links as cleaned_html and restores the spacing. fit_html also keeps spacing, but it drops links and pruned content.
- Lenguaje dominante
- Python
- Estrellas
- 85.4k
- Forks
- 8.9k
- Merge medio
- 5 d 7 h
- PR fusionados (30 d)
- 23
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de unclecode/crawl4ai
-
[Bug]: Since 0.9.1, Linux launches chrome-headless-shell instead of ChromiumPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
[Bug]: BestFirstCrawlingStrategy fetches a full batch past max_pagesPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
unclecode/crawl4ai#2381 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[Bug]: CrawlerRunConfig.clone() drops fallback_fetch_function, so deep crawls never use itPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
[Bug]: Docker memory guard reads host RAM when no container limit is set — cgroup v2 "max" defeats get_container_memory_percentPosiblemente ocupada @Battleplus la tomó hace 55 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
unclecode/crawl4ai#2123 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[Bug]: After a streamed deep crawl is stopped early, the next deep crawl returns only the start pagePosiblemente ocupada @PiUnknown la tomó hace 2 días. Abierto
Dificultad 4/5 1-2 días Aptitud para principiantes 12/100
unclecode/crawl4ai#2380 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de unclecode/crawl4ai
Issues similares
-
Dificultad 1/5 1-3 horas Aptitud para principiantes 68/100
FavioVazquez/showtime#101 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
rossant/awesome-math#199 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
nautechsystems/nautilus_trader#5365 ·
Los mantenedores suelen responder en 1 día
-
Examples say cnxAbiertodocumentation embedded
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día