Em um conjunto de fixtures com anotações e foco em artigos, o newspaper4k gerou saída em todas as 22 fixtures, recuperou 98,65% das unidades de artigo pontuadas e não incluiu nenhum dos tokens de boilerplate rotulados. Esses três fatores fazem da biblioteca uma candidata forte dentro das prioridades deste teste; isso, porém, não a transforma em vencedora universal.
Nenhuma outra ferramenta deste conjunto combinou esses três resultados observados. O Mozilla Readability recuperou todas as unidades de conteúdo pontuadas, mas incluiu mais boilerplate rotulado; o goose3 não incluiu boilerplate rotulado, porém retornou strings vazias duas vezes. Dependendo das regras de decisão, outra biblioteca pode ser a melhor escolha.
Antes de colocar em produção, há um padrão de fetching que merece atenção especial.
O que é o newspaper4k
newspaper4k é um fork mantido do newspaper3k, que por sua vez foi a continuação em Python 3 do projeto original newspaper. Essa linhagem importa quando você busca ajuda, porque grande parte do material disponível na internet ainda faz referência ao antecessor e parte da API mudou.
Referência oficial: repositório oficial do newspaper4k.

Um erro bem comum ao usar essa biblioteca, por exemplo, é tentar chamar set_html(). Esse método não existe. O HTML entra por download():
from newspaper import Article
a = Article(url="https://example.com/story")
a.download(input_html=html) # not set_html()
a.parse()
text = a.text
Eu errei isso na primeira execução e dei nota 0 de 22 fixtures para a biblioteca antes de checar se o problema era meu. E era.
A saída não é só texto. O objeto Article expõe campos como text, title, authors, publish_date, top_image, images, movies, meta_description, meta_lang, tags e article_html. keywords e summary exigem a instalação opcional de NLP e a configuração de corpus descrita abaixo. O conjunto de campos foi inventariado, mas a precisão dos metadados não foi pontuada.
Versão testada: 0.9.6, MIT, 1.135 estrelas no GitHub, com push no repositório datado de 2026-07-31. Essa atividade datada é só um retrato, não uma avaliação completa da saúde de manutenção. Python 3.14.2.
O resultado
| Biblioteca | Recall de artigos (22/22) | Vazamento de boilerplate | Precisão de tokens de conteúdo | Tokens contaminantes | Saída produzida |
|---|---|---|---|---|---|
| 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 unidade em cada fixture carrega um token sentinela exclusivo, então “recuperado” e “vazado” correspondem a pertencimento exato de substring, e não a uma medida de similaridade. O recall considera as 22 fixtures; vazamento e precisão consideram as 11 que contêm artigo e boilerplate ao mesmo tempo.
Há três colunas que valem separar.
Ele respondeu em todas as páginas. goose3 e jusText não conseguiram — 20 e 19 de 22. Isso importa mais do que parece, porque precisão e F1 nessa tabela são condicionais à geração de saída: uma biblioteca que retorna string vazia não contribui para nenhum dos lados da razão, então “não responder” vira uma saída gratuita. A precisão 1.0000 do goose3 foi medida em 10 de 11 fixtures; a do newspaper4k, 0.9452 em 11 de 11. Não é exatamente a mesma medição.
Não vazou nada. As fixtures incluem boilerplate deliberadamente adversarial — blocos promocionais classificados como neutros e colocados como irmãos do artigo, threads de comentários com nomes de classe inocentes, e blocos de anúncio que não dizem “ad”. O heurístico de anexar irmãos do Readability engoliu vários deles; o newspaper4k não levou nenhum.
Ele perdeu uma unidade em 74, e a unidade perdida é compartilhada.
A falha acontece na fixture sem prosa — uma página construída com tabelas, um bloco de código, itens curtos e uma legenda de imagem em vez de parágrafos — e a unidade descartada é a legenda. Ele não está sozinho nesse ponto:
| Biblioteca | Recall na página sem prosa | Unidades descartadas |
|---|---|---|
| Readability | 1.000 | — |
| jusText | 1.000 | — |
| trafilatura | 0.875 | a legenda |
| resiliparse | 0.875 | a legenda |
| newspaper4k | 0.875 | a legenda |
| goose3 | 0.250 | ambas as tabelas, o bloco de código, ambos os itens curtos, a legenda |
Três bibliotecas descartam a mesma legenda e nenhuma outra unidade, o que parece menos com três bugs distintos e mais com uma suposição herdada em comum sobre o valor de uma legenda. Se o seu conteúdo inclui documentação, receitas ou qualquer material em que a legenda carregue informação que o parágrafo não traz, vale testar isso antes de adotar — e tanto Readability quanto jusText preservaram esse conteúdo.
É na mesma fixture que o goose3 desmorona por completo, perdendo três quartos da página; portanto, “conteúdo sem prosa” é um eixo em que essas seis ferramentas diferem muito mais do que a tabela principal sugere.
Em velocidade, a mediana de extração do newspaper4k nas 22 fixtures foi 2,69 ms, a mais lenta das seis, com pior caso de 199,81 ms. Comparada à mediana de 0,06 ms do resiliparse, isso representa uma diferença de 45× nesta execução controlada. A mediana pode ser pequena em um fluxo de uma página só, mas throughput e latência de cauda sob carga não foram testados. O cold import é medido separadamente abaixo.
O padrão que eu mudaria na primeira linha

Referência oficial: documentação do newspaper4k.
Ao ler o objeto Configuration que vem com a biblioteca, aparecem vinte e duas configurações. Uma delas é esta:

_honor_robotstxt = False
O newspaper4k não respeita robots.txt a menos que você diga explicitamente para isso. Se ele fizer o fetch — Article(url).download() sem input_html — vai buscar qualquer URL que você apontar, independentemente do que o arquivo robots do site diga.
Esse é um padrão de engenharia defensável para uma biblioteca cujo uso principal é fazer parse de HTML que você já possui, mas é um padrão perigoso de descobrir em produção depois de apontá-la para mil URLs. Defina honor_robotstxt=True na sua Configuration, ou passe input_html e faça o fetch por conta própria, que foi o que fiz em todo este teste.
Mais dois pontos que vale conhecer:
number_threads = 10. O paralelismo padrão dos helpers para múltiplos artigos é dez. Concorrência não é o mesmo que requisições por segundo, mas pode gerar picos de requisições simultâneas se você não definir limites explícitos por host e um esquema de agendamento.
fetch_images = True. O download de imagens vem ativado por padrão, o que levanta a questão do uso offline. Com socket.connect bloqueado, o caminho testado do newspaper4k 0.9.6 — download(input_html=…) seguido de parse() em um input com HTML já carregado — foi concluído, retornou 1.292 caracteres e tentou zero conexões de rede. Isso comprova esse caminho exato, não qualquer configuração, plugin, tipo de conteúdo ou versão futura.
O restante é sensato: 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.
Realidade da instalação
pip install newspaper4k baixa 22 pacotes e 47,5 MiB em cerca de seis segundos. Cold import em um subprocesso limpo: 2,812 s — o mais lento da comparação.
| Biblioteca | Pacotes | site-packages | Cold import | Extraction p50 |
|---|---|---|---|---|
| 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 foi executada em seu próprio virtualenv vazio, então nenhuma herda dependências de outra.
Importar em 2,812 segundos é 187 vezes mais lento que os 15 milissegundos do resiliparse. Em um worker de longa duração, esse custo é pago uma única vez e se torna irrelevante. Em uma função serverless, você o paga a cada cold start — e é aí que o newspaper4k deixa de ser a escolha certa, independentemente da qualidade da extração.
Há um detalhe chato na instalação. Ao importar, a biblioteca imprime um aviso:
UserWarning: nltk is not installed. Some NLP features will be unavailable. Install it with: pip install 'newspaper4k[nlp]'
Nada neste teste precisava desses recursos e a extração funcionou bem sem eles, mas a instalação base não é a instalação completa, e newspaper4k[nlp] traz uma árvore de dependências bem mais pesada, além de downloads de corpus. Só vale reservar esse custo se você quiser palavras-chave e resumos.
Memória e o que HTML quebrado faz com ela
Duas coisas que toda revisão deste lote listava como não testadas agora foram medidas.
O contexto mais amplo do stress test está na comparação de memória e HTML malformado entre dez bibliotecas.
Pico de memória residente, via /usr/bin/time -l, com um processo novo por célula — o piso de import é o custo da biblioteca carregada e ociosa; os picos incluem o documento.
| Biblioteca | Runtime | Piso de importação (MiB) | Pico com HTML de 226 KB (MiB) | Pico com 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. As bases de Python e Node não são comparáveis entre si; o interpretador faz parte de ambas.
O piso do newspaper4k é de 52,6 MiB e o pico com 10 MB de HTML chega a 668,5 MiB — o segundo mais pesado entre as bibliotecas Python. Nenhum dos dois números é um problema para páginas comuns; ambos importam se você processa documentos grandes em um worker com limite de memória.
HTML quebrado. Doze documentos, cada um quebrando exatamente uma coisa — tags não fechadas, elementos inline mal aninhados, atributos sem aspas com espaços, fechamentos sobrando, ausência total de <html>, atributos duplicados, documento truncado no meio de uma tag, entidades inválidas, <script> sem fechamento, declaração de charset mentirosa, um comentário contendo markup e 600 níveis de aninhamento — além de dois controles bem formados com tamanhos correspondentes, porque “não retornou nada” só diz algo sobre malformação se a biblioteca também não produzir saída em um documento limpo do mesmo tamanho.
Os controles e os casos malformados se separam claramente nos resultados brutos:
| Grupo | Documentos | Erro levantado | Saída vazia | Sentinelas pontuadas recuperadas |
|---|---|---|---|---|
| Controles bem formados com tamanhos correspondentes | 2 | 0 | 0 | não usado na pontuação de malformados |
| Fixtures malformadas | 12 | 0 | 10 | 5/33, excluindo o caso do <script> sem fechamento |
Os dois controles produziram 70 e 1.351 caracteres, enquanto dez dos doze inputs malformados geraram string vazia. Isso permite atribuir o silêncio à malformação dentro deste desenho de teste, e não apenas ao fato de o input ser curto. O avaliador verifica sentinelas de heading, parágrafo e link nos onze documentos malformados elegíveis. A fixture com </script> ausente é excluída porque, no parsing HTML5, o markup seguinte continua sendo conteúdo de script. Veja malformed-results.json. Isso é uma limitação de recuperação importante para a escolha, e não apenas um “não gerou erro”.
Prós e contras
A favor. Nenhum token rotulado de boilerplate nesta comparação, saída em todas as 22 fixtures controladas de artigo e recall de 0,9865 nas unidades de artigo pontuadas. Ele expõe texto do artigo e campos de metadados, embora a precisão dos metadados não tenha sido testada. O caminho com HTML já carregado não tentou conexão de rede com socket.connect bloqueado. No momento da checagem, o repositório tinha um push datado recente; a saúde mais ampla da manutenção não foi avaliada.
Contra. O cold import mais pesado do conjunto, com 2,812 s e 22 pacotes / 47,5 MiB de site-packages medidos. honor_robotstxt vem como False por padrão, e os helpers multi-artigo usam dez threads por padrão. A instalação base avisa sobre a ausência de NLTK, então palavras-chave e resumos exigem uma instalação opcional mais pesada. O mais importante: dez dos doze fixtures malformados voltaram vazios, embora os dois controles bem formados e correspondentes tivessem produzido texto.
Quem deve usar — e quem não deve
Considere o newspaper4k quando sua ordem de prioridade for: produzir texto não vazio em um corpus controlado e orientado a artigos, minimizar boilerplate rotulado nesse corpus e aceitar um cold import mais lento. Sob essa regra explícita, ele liderou esta comparação. Outra regra pode escolher o Readability para máxima retenção de conteúdo pontuado ou o resiliparse para startup e velocidade mediana de extração.
Evite ou teste com cuidado quando cold start dominar, quando 47,5 MiB de site-packages medidos forem relevantes, ou quando recuperação de HTML malformado for importante. O resiliparse importou 187× mais rápido neste teste, mas não empatou com a trafilatura em todas as colunas de qualidade: a trafilatura teve recall de artigo maior, enquanto seus perfis de vazamento e precisão também foram diferentes. O newspaper4k é focado em artigos; listagens de produtos e dashboards não foram testados, então nenhum comportamento é afirmado para esses casos.
Faça o que fizer, defina honor_robotstxt se a biblioteca for buscar conteúdo. Isso não é uma nota de performance.
Onde uma API gerenciada entra nessa equação
newspaper4k consegue analisar HTML fornecido pelo chamador e também possui caminhos de fetching. Já um serviço gerenciado de extração coloca aquisição, renderização e esquema de dados atrás de uma fronteira de fornecedor. Nós construímos o Thunderbit, mas ele não foi executado neste conjunto de fixtures, então esta revisão não sustenta comparação de qualidade, renderização, anti-bot, latência ou custo. Para HTML de artigo já carregado, a evidência aqui diz respeito apenas ao newspaper4k; alvos que não sejam artigos precisam da própria avaliação.
Para ver os mesmos fixtures comparados entre os seis extratores, consulte a comparação de extração entre seis bibliotecas.
Para a frente hospedada, nosso resumo de APIs de web scraping traz uma visão mais ampla; para alternativas self-hosted, veja o guia principal de scrapers open source. Se o texto vai seguir para um modelo, o artigo como converter HTML em Markdown em Python mostra onde a fidelidade se perde.
Experimente o Thunderbit para extração de dados da web
Vale a pena usar o newspaper4k?
Trate o newspaper4k como uma forte opção para extração de texto de artigos quando o HTML já estiver disponível e faça depois um teste real com seu próprio corpus antes de adotá-lo. O conjunto controlado mostra alto recall de conteúdo de artigo, ausência de boilerplate rotulado e saída não vazia em todas as 22 fixtures orientadas a artigos. Ele não cobre páginas reais nem precisão de metadados, e dez dos doze fixtures malformados retornaram vazio.
Se você usar o caminho de fetching, revise explicitamente honor_robotstxt=False, o paralelismo de dez threads e os limites por host. Se cold start ou o peso de dependências importarem, meça em sua própria implantação a observação de import local em 2,812 segundos e 47,5 MiB de site-packages, em vez de tratá-las como custos universais de contêiner.
Experimente o Thunderbit para extração de dados da web Get Started Free
Perguntas frequentes
Por que set_html() não funciona?
Porque esse método não existe no newspaper4k. O HTML entra por download(input_html=html), e depois você chama parse(). Pesquisas na web podem mostrar exemplos do newspaper3k, o que torna esse erro fácil de cometer; eu mesmo cometi isso na primeira execução e corrigi o harness antes da avaliação.
O newspaper4k respeita robots.txt?
Não por padrão. honor_robotstxt vem como False. Defina como True na sua Configuration se a biblioteca for fazer fetch, ou passe input_html e faça o fetch por conta própria. O processamento de múltiplos artigos também usa dez threads por padrão. Isso é paralelismo não escolhido, não uma taxa fixa de requisições; defina limites explícitos por host para o fetching.
parse() faz requisições de rede?
Na versão 0.9.6 do newspaper4k, o caminho testado download(input_html=…) + parse() não tentou nenhuma conexão para um input com HTML já carregado enquanto socket.connect estava bloqueado. Isso não prova que toda configuração de parser, plugin, tipo de conteúdo ou versão futura seja livre de rede.
O que significa o aviso sobre NLTK na importação?
A instalação base não inclui NLTK, então extração de palavras-chave e geração de resumos não ficam disponíveis e a biblioteca avisa isso ao importar. A extração em si não é afetada — tudo o que medimos aqui rodou na instalação base. pip install 'newspaper4k[nlp]' adiciona esses recursos, junto com uma árvore de dependências mais pesada e downloads de corpus.
O que esta revisão não testou? Páginas reais — estes são fixtures controlados com unidades rotuladas. Os campos de metadados foram inventariados, mas não pontuados quanto à precisão de título, autor, data ou imagem. Extração multilíngue, extras de NLP, crawling multi-thread de fontes e throughput sob carga também não foram testados. O pico de memória do processo foi medido em um input HTML de 226 KB e outro de 10 MB, não sob concorrência nem carga sustentada.


