En un conjunto de pruebas con anotaciones y enfoque en artículos, newspaper4k generó salida en las 22 pruebas, recuperó el 98,65 % de las unidades de artículo evaluadas e incorporó cero tokens de relleno etiquetados. Esas tres dimensiones lo convierten en un candidato sólido según las prioridades de esta prueba; no lo convierten en un ganador universal.
Ninguna otra opción de este conjunto combinó esos tres resultados observados. Mozilla Readability recuperó todas las unidades de contenido evaluadas, pero incluyó más relleno etiquetado; goose3 no incluyó relleno etiquetado, pero devolvió cadenas vacías dos veces. Según el criterio de decisión, otra biblioteca puede ser preferible.
Hay un comportamiento de descarga por defecto que merece atención antes de ponerlo en producción.
Qué es newspaper4k
newspaper4k es una bifurcación mantenida de newspaper3k, que a su vez fue la continuación para Python 3 del proyecto original newspaper. Ese linaje importa cuando buscas ayuda, porque gran parte de lo que encontrarás en línea hace referencia a su antecesor y parte de su API ha cambiado de lugar.
Referencia oficial: repositorio oficial de newspaper4k.

La forma más común de usar mal esta biblioteca, por ejemplo, es intentar set_html(). Ese método no existe. El HTML se pasa mediante download():
from newspaper import Article
a = Article(url="https://example.com/story")
a.download(input_html=html) # no set_html()
a.parse()
text = a.text
Yo me equivoqué así en la primera ejecución y evalué la biblioteca con 0 de 22 pruebas antes de comprobar si el fallo era mío. Lo era.
Lo que devuelve no es solo texto. El objeto Article expone campos como text, title, authors, publish_date, top_image, images, movies, meta_description, meta_lang, tags y article_html. keywords y summary requieren la instalación opcional de NLP y la configuración del corpus que se describe más abajo. Se inventarió la superficie de campos, pero no se evaluó la precisión de los metadatos.
Versión probada: 0.9.6, licencia MIT, 1.135 estrellas en GitHub, con un push al repositorio fechado el 2026-07-31. Esa actividad fechada es una instantánea, no una evaluación completa del estado de mantenimiento. Python 3.14.2.
El resultado
| Biblioteca | Recall de artículos (22/22) | Fuga de relleno | Precisión de tokens de contenido | Tokens contaminantes | Generó salida |
|---|---|---|---|---|---|
| Readability | 1.0000 | 0.2353 | 0.9109 | 35 | 22/22 |
| trafilatura | 0.9865 | 0.0588 | 0.9411 | 4 | 22/22 |
| newspaper4k | 0.9865 | 0.0000 | 0.9452 | 0 | 22/22 |
| resiliparse | 0.9054 | 0.0588 | 0.9381 | 7 | 22/22 |
| jusText | 0.8378 | 0.4706 | 0.8760 | 74 | 19/22 |
| goose3 | 0.8243 | 0.0000 | 1.0000 | 0 | 20/22 |
sixway-scores.json. Cada unidad en cada prueba lleva un token centinela único, así que “recuperado” y “filtrado” son coincidencias exactas de subcadena, no una puntuación de similitud. El recall se calcula sobre las 22 pruebas; la fuga y la precisión, sobre las 11 que contienen tanto artículo como relleno.
Conviene separar tres columnas.
Respondió en todas las páginas. goose3 y jusText no lo hicieron: 20 y 19 de 22. Eso importa más de lo que parece, porque la precisión y el F1 en una tabla así dependen de que haya salida: si una biblioteca devuelve una cadena vacía, no contribuye a ninguno de los lados de la razón, así que no responder sale gratis. La precisión de goose3 de 1.0000 se calculó sobre 10 de 11 pruebas; la de newspaper4k, de 0.9452, sobre 11 de 11. No es exactamente la misma medición.
No filtró nada. Las pruebas incluyen relleno deliberadamente adversarial: bloques promocionales clasificados como neutrales situados como hermanos del artículo, hilos de comentarios con nombres de clase inocuos, y bloques publicitarios que no dicen “ad”. El heurístico de Readability que añade nodos hermanos absorbió varios de ellos; newspaper4k no filtró ninguno.
Solo dejó pasar una unidad de 74, y la unidad omitida es compartida.
La omisión está en la prueba sin prosa —una página formada por tablas, un bloque de código, elementos breves y un pie de imagen en lugar de párrafos— y la unidad que perdió es el pie de imagen. No es el único que falla ahí:
| Biblioteca | Recall en la página sin prosa | Unidades omitidas |
|---|---|---|
| Readability | 1.000 | — |
| jusText | 1.000 | — |
| trafilatura | 0.875 | el pie de imagen |
| resiliparse | 0.875 | el pie de imagen |
| newspaper4k | 0.875 | el pie de imagen |
| goose3 | 0.250 | ambas tablas, el bloque de código, ambos elementos breves, el pie de imagen |
Tres bibliotecas pierden el mismo pie de imagen y ninguna otra unidad, lo que suena menos a tres errores independientes y más a una suposición heredada compartida sobre el valor de un pie de imagen. Si tu contenido es documentación, recetas o cualquier formato en el que el pie de imagen aporte información que el párrafo no da, conviene probarlo antes de adoptarlo; Readability y jusText sí lo conservaron.
La misma prueba es donde goose3 se desmorona por completo, perdiendo tres cuartas partes de la página, así que el “contenido sin prosa” es un eje en el que estas seis opciones difieren mucho más de lo que sugiere la tabla principal.
En velocidad, la mediana de extracción de newspaper4k en las 22 pruebas fue de 2,69 ms, la más lenta de las seis, con un peor caso de 199,81 ms. Frente a la mediana de 0,06 ms de resiliparse, eso supone una brecha de 45× en esta ejecución controlada. La mediana puede parecer pequeña en un flujo de una sola página, pero no se probaron el rendimiento agregado ni la latencia de cola bajo carga. La importación en frío se mide por separado más abajo.
El valor por defecto que cambiaría desde la primera línea

Referencia oficial: documentación de newspaper4k.
Al revisar el objeto Configuration que incluye la biblioteca, aparecen veintidós ajustes. Uno de ellos es este:

_honor_robotstxt = False
newspaper4k no respeta robots.txt a menos que se lo indiques. Si dejas que descargue —Article(url).download() sin input_html—, obtendrá lo que le apuntes, sin importar lo que diga el archivo robots del sitio.
Es un valor por defecto defendible para una biblioteca cuyo uso principal es analizar HTML que ya tienes, pero es indefendible descubrirlo en producción después de haberla apuntado a mil URLs. Establece honor_robotstxt=True en tu Configuration, o pasa input_html y realiza tú mismo la descarga, que es lo que hice en esta prueba.
Otros dos conviene conocerlos:
number_threads = 10. El paralelismo predeterminado de sus utilidades para múltiples artículos es de diez. La concurrencia no equivale a solicitudes por segundo, pero sí puede provocar ráfagas de peticiones simultáneas si no defines límites y programación por host.
fetch_images = True. La descarga de imágenes está activada por defecto, lo que abre la cuestión del uso sin conexión. Con socket.connect bloqueado, la ruta probada de newspaper4k 0.9.6 —download(input_html=…) seguido de parse() sobre una entrada HTML ya disponible— terminó correctamente, devolvió 1.292 caracteres y no intentó ninguna conexión de red. Esto valida esa ruta exacta, no todas las configuraciones, plugins, tipos de contenido ni futuras versiones.
El resto son razonables: min_word_count 300, min_sent_count 7, max_text 100.000, http_success_only True, memorize_articles True, follow_meta_refresh False, allow_binary_content False.
Realidad de la instalación
pip install newspaper4k descarga 22 paquetes y 47,5 MiB en unos seis segundos. Importación en frío en un subproceso nuevo: 2,812 s, la más lenta de la comparación.
| Biblioteca | Paquetes | site-packages | Importación en frío | p50 de extracción |
|---|---|---|---|---|
| resiliparse | 5 | 21.0 MiB | 0.015 s | 0.06 ms |
| jusText | 3 | 22.4 MiB | 0.777 s | 0.56 ms |
| goose3 | 16 | 44.3 MiB | 2.181 s | 1.85 ms |
| newspaper4k | 22 | 47.5 MiB | 2.812 s | 2.69 ms |
| trafilatura | 17 | 69.9 MiB | 1.584 s | 0.51 ms |
install-and-import.json. Cada biblioteca en su propio virtualenv vacío, de modo que ninguna hereda dependencias de otra.
2,812 segundos para importar son 187 veces los 15 milisegundos de resiliparse. En un worker de larga duración se paga una sola vez y deja de importar. En una función serverless lo pagas en cada arranque en frío, y ahí es donde newspaper4k es una mala elección, por muy buena que sea su extracción.
Un detalle incómodo de la instalación. Al importar, aparece una advertencia:
UserWarning: nltk is not installed. Some NLP features will be unavailable. Install it with: pip install 'newspaper4k[nlp]'
Nada en esta prueba necesitaba esas funciones y la extracción funcionó bien sin ellas, pero la instalación base no es la completa, y newspaper4k[nlp] incorpora un árbol de dependencias bastante más pesado más descargas de corpus. Reserva eso solo si quieres palabras clave y resúmenes.
Memoria y qué le hace el HTML roto
Dos aspectos que en todos los análisis de este lote figuraban como no probados, ahora están medidos.
El contexto más amplio de la prueba de estrés está en la comparación de memoria y HTML malformado de diez bibliotecas.
Memoria residente máxima, mediante /usr/bin/time -l, un proceso nuevo por celda: el piso de importación es lo que cuesta cargar y dejar la biblioteca inactiva; los picos incluyen el documento.
| Biblioteca | Runtime | Piso de importación (MiB) | Pico con HTML de 226 KB (MiB) | Pico con HTML de 10 MB (MiB) |
|---|---|---|---|---|
| html2text | python3.14 | 18.7 | 19.9 | 71.2 |
| pyquery | python3.14 | 30.3 | 33.9 | 172.5 |
| resiliparse | python3.14 | 20.5 | 25.1 | 225.1 |
| markdownify | python3.14 | 23.9 | 28.9 | 278.5 |
| goose3 | python3.14 | 44.1 | 52.4 | 398.5 |
| cheerio | node22 | 66.8 | 76.5 | 398.5 |
| justext | python3.14 | 30.3 | 36.6 | 431.2 |
| newspaper4k | python3.14 | 52.6 | 61.8 | 668.5 |
| trafilatura | python3.14 | 52.5 | 64.8 | 927.1 |
| turndown | node22 | 47.8 | 68.4 | 2947.1 |
memory-results.json. Las referencias base de Python y Node no son comparables entre sí; el intérprete está dentro de ambas.
El piso de newspaper4k es de 52,6 MiB y su pico con 10 MB es de 668,5 MiB, el segundo más pesado entre las bibliotecas de Python. Ninguna de las dos cifras es un problema para páginas normales; ambas importan si vas a procesar documentos grandes en un worker con límite de memoria.
HTML roto. Doce documentos rompen exactamente una cosa cada uno: etiquetas sin cerrar, elementos inline mal anidados, atributos sin comillas con espacios, cierres sueltos, ausencia total de <html>, atributos duplicados, un documento truncado a mitad de etiqueta, entidades incorrectas, un <script> sin cerrar, una declaración de charset engañosa, un comentario que contiene marcado y 600 niveles de anidamiento; además de dos controles bien formados de tamaño equivalente, porque “no devolvió nada” solo dice algo sobre la malformación si la biblioteca tampoco guarda silencio ante un documento limpio del mismo tamaño.
Los controles y los casos malformados se separan claramente en los resultados brutos:
| Grupo | Documentos | Lanzó excepción | Salida vacía | Sentinelas evaluados recuperados |
|---|---|---|---|---|
| Controles bien formados de tamaño equivalente | 2 | 0 | 0 | no usado en la puntuación de malformación |
| Pruebas malformadas | 12 | 0 | 10 | 5/33, excluyendo el caso de <script> sin cerrar |
Los dos controles produjeron 70 y 1.351 caracteres, mientras que diez de los doce inputs malformados devolvieron una cadena vacía. Eso permite atribuir el silencio a la malformación dentro de este diseño de pruebas y no simplemente a la brevedad del input. El evaluador comprueba sentinelas de encabezado, párrafo y enlace en los once documentos malformados elegibles. La prueba del <script> sin cerrar se excluye porque, según el análisis HTML5, el marcado posterior sigue siendo contenido del script. Ver malformed-results.json. Esta es una limitación de recuperación importante a tener en cuenta al elegir, no solo un éxito de “no lanzó excepción”.
Pros y contras
A favor. Cero tokens de relleno etiquetados en esta comparación, salida en las 22 pruebas controladas orientadas a artículos y 0,9865 de recall de artículos evaluados. Expone texto del artículo además de campos de metadatos, aunque la precisión de metadatos no se probó. La ruta probada con HTML ya disponible no realizó intentos de red con socket.connect bloqueado. El repositorio mostraba una actualización fechada reciente cuando se revisó; el estado general de mantenimiento no se evaluó.
En contra. La importación en frío más pesada del conjunto, con 2,812 s y 22 paquetes / 47,5 MiB de site-packages medidos. honor_robotstxt viene en False por defecto y las utilidades de varios artículos usan diez hilos por defecto. La instalación base avisa de que falta NLTK, así que las palabras clave y los resúmenes requieren una instalación opcional más pesada. Y, lo más importante, diez de las doce pruebas malformadas devolvieron salida vacía aunque ambos controles bien formados sí produjeron texto.
Quién debería usarlo y quién no
Considera newspaper4k si tu prioridad es: generar texto no vacío en un corpus controlado centrado en artículos, minimizar el relleno etiquetado en ese corpus y aceptar una importación en frío más lenta. Bajo esa regla explícita, lideró esta comparación. Con otra regla, Readability puede ser mejor para maximizar la retención de contenido evaluado, o resiliparse para el arranque y la velocidad media de extracción.
Evítalo o pruébalo con mucho cuidado cuando el arranque en frío domine, cuando 47,5 MiB de site-packages medidos sea relevante o cuando la recuperación ante HTML malformado sea importante. Resiliparse importó aquí 187× más rápido, pero no empató con trafilatura en todas las columnas de calidad: trafilatura tuvo mayor recall de artículos, aunque sus perfiles de fuga y precisión también difirieron. newspaper4k está orientado a artículos; las listas de productos y los paneles no se probaron, así que no se puede afirmar nada sobre ellos.
Hagas lo que hagas, configura honor_robotstxt si vas a permitir que descargue. Eso no es una nota de rendimiento.
Dónde encaja una API gestionada
newspaper4k puede analizar HTML proporcionado por el usuario y también tiene rutas de descarga. Un servicio de extracción gestionado sitúa la obtención, el renderizado y el trabajo de esquema detrás de un perímetro de proveedor. Nosotros construimos Thunderbit, pero no se ejecutó contra este conjunto de pruebas, así que esta revisión no respalda ninguna comparación de calidad, renderizado, anti-bot, latencia o coste. Para HTML de artículos ya obtenido, la evidencia aquí trata solo de newspaper4k; los objetivos que no son artículos necesitan su propia evaluación.
Para los mismos casos en los seis extractores, consulta la comparación de extracción de seis bibliotecas.
Para el campo gestionado, nuestro resumen de APIs de scraping web ofrece una visión más amplia; para alternativas autoalojadas, el artículo pilar sobre scrapers de código abierto. Si el texto va a entrar en un modelo, convertir HTML a Markdown en Python explica dónde se pierde fidelidad.
Probar Thunderbit para extracción de datos web
¿Deberías usar newspaper4k?
Tómalo como un candidato fuerte para extraer texto de artículos cuando el HTML ya está disponible y luego haz una prueba real con tu propio corpus antes de adoptarlo. El conjunto controlado respalda un recall alto de contenido evaluado, ausencia de relleno etiquetado y salida no vacía en las 22 pruebas orientadas a artículos. No cubre páginas reales ni la precisión de metadatos, y diez de las doce pruebas malformadas devolvieron salida vacía.
Si usas su ruta de descarga, revisa explícitamente honor_robotstxt=False, el paralelismo de diez hilos y los controles de tasa por host. Si el arranque en frío o el peso de dependencias te importan, mide en tu despliegue el inicio local de 2,812 segundos y los 47,5 MiB de site-packages observados, en lugar de asumirlos como costes universales del contenedor.
Probar Thunderbit para extracción de datos web Get Started Free
Preguntas frecuentes
¿Por qué no funciona set_html()?
Porque no existe en newspaper4k. El HTML se pasa mediante download(input_html=html), y después parse(). Los resultados de búsqueda pueden mostrar ejemplos de newspaper3k, así que es un error fácil; yo lo cometí en la primera ejecución y corregí el entorno antes de puntuar.
¿newspaper4k respeta robots.txt?
No por defecto. honor_robotstxt viene en False. Cámbialo a True en tu Configuration si vas a dejar que la biblioteca descargue, o pasa input_html y descarga tú mismo. El trabajo con varios artículos también usa diez hilos por defecto. Eso es paralelismo no elegido, no una tasa fija de solicitudes; define límites explícitos por host al descargar.
¿parse() hace peticiones de red?
En newspaper4k 0.9.6, la ruta probada download(input_html=…) más parse() no intentó ninguna conexión con una entrada HTML ya disponible mientras socket.connect estaba bloqueado. Eso no demuestra que todas las configuraciones del parser, plugins, tipos de contenido o futuras versiones estén libres de red.
¿Qué significa el aviso de NLTK al importar?
La instalación base no incluye NLTK, así que la extracción de palabras clave y los resúmenes no están disponibles y la biblioteca lo indica al importar. La extracción en sí no se ve afectada: todo lo medido aquí se ejecutó con la instalación base. pip install 'newspaper4k[nlp]' añade esas funciones junto con un árbol de dependencias más pesado y descargas de corpus.
¿Qué no probó esta revisión? Páginas reales: estos son fixtures controlados con unidades etiquetadas. Los campos de metadatos se inventariaron, pero no se evaluó la precisión de título, autor, fecha o imagen. Tampoco se probaron la extracción multilingüe, los extras de NLP, el rastreo multihilo de fuentes ni el rendimiento bajo carga. La memoria máxima del proceso se midió con un HTML de 226 KB y otro de 10 MB, no bajo concurrencia ni carga sostenida.


