Skip to content

Converter HTML para Markdown em PHP com league/html-to-markdown

Introdução

Converter HTML para Markdown é uma necessidade comum ao trabalhar com web scraping, migrações de CMS, processamento de feeds RSS ou preparação de conteúdo para LLMs. A biblioteca league/html-to-markdown oferece uma solução robusta e testada, com mais de 24 milhões de downloads.

Este artigo cobre instalação, opções de configuração, suporte a tabelas e considerações de segurança para entrada não confiável.

Instalação

Instale via Composer:

bash
composer require league/html-to-markdown

A biblioteca requer PHP 7.2+ com as extensões xml, libxml e dom (habilitadas por padrão na maioria das distribuições).

Uso Básico

php
use League\HTMLToMarkdown\HtmlConverter;

$converter = new HtmlConverter();

$html = '<h1>Olá Mundo</h1><p>Este é um <strong>teste</strong>.</p>';
$markdown = $converter->convert($html);

echo $markdown;
// # Olá Mundo
//
// Este é um **teste**.

Opções de Configuração

O conversor aceita um array de opções:

php
$converter = new HtmlConverter([
    'strip_tags' => true,
    'remove_nodes' => 'script style',
    'hard_break' => true,
    'strip_placeholder_links' => true,
]);

Principais Opções Explicadas

OpçãoPadrãoDescrição
strip_tagsfalseRemove tags HTML sem equivalente em Markdown, mantendo seu conteúdo
remove_nodes''Lista de tags separadas por espaço para remover completamente (incluindo conteúdo)
hard_breakfalseConverte <br> para \n em vez de \n (estilo GFM)
strip_placeholder_linksfalseRemove tags <a> sem atributo href
header_style'setext'Use 'atx' para headers com # em H1/H2
preserve_commentsfalseMantém comentários HTML na saída

Configuração Recomendada para Web Scraping

Ao converter HTML extraído da web, você geralmente quer remover navegação, scripts e outros elementos que não são conteúdo:

php
$converter = new HtmlConverter([
    'strip_tags' => true,
    'remove_nodes' => 'script head style noscript nav footer aside header',
    'hard_break' => true,
    'strip_placeholder_links' => true,
]);

Adicionando Suporte a Tabelas

A conversão de tabelas não é habilitada por padrão porque tabelas não fazem parte da especificação original do Markdown. Adicione suporte com o TableConverter:

php
use League\HTMLToMarkdown\HtmlConverter;
use League\HTMLToMarkdown\Converter\TableConverter;

$converter = new HtmlConverter(['strip_tags' => true]);
$converter->getEnvironment()->addConverter(new TableConverter());

$html = '
<table>
    <tr><th>Nome</th><th>Função</th></tr>
    <tr><td>Alice</td><td>Desenvolvedora</td></tr>
    <tr><td>Bob</td><td>Designer</td></tr>
</table>';

echo $converter->convert($html);
// | Nome | Função |
// | --- | --- |
// | Alice | Desenvolvedora |
// | Bob | Designer |

Exemplo Prático: Pipeline de Web Scraping

Aqui está uma função utilitária completa para converter HTML extraído em Markdown limpo:

php
use League\HTMLToMarkdown\Converter\TableConverter;
use League\HTMLToMarkdown\HtmlConverter;

function htmlParaMarkdown(string $html): string
{
    $converter = new HtmlConverter([
        'strip_tags' => true,
        'remove_nodes' => 'script head style noscript nav footer aside header',
        'hard_break' => true,
        'strip_placeholder_links' => true,
    ]);

    $converter->getEnvironment()->addConverter(new TableConverter());

    return $converter->convert($html);
}

// Uso
$html = file_get_contents('https://exemplo.com/artigo');
$markdown = htmlParaMarkdown($html);

Pré-processamento: Limpando Código com Syntax Highlighting

Ao extrair sites de documentação, blocos de código frequentemente contêm tags <span> para destaque de sintaxe. Isso pode poluir sua saída Markdown. Limpe antes da conversão:

php
function removerSpansDoCode(string $html): string
{
    $dom = new DOMDocument('1.0', 'UTF-8');

    libxml_use_internal_errors(true);
    $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    libxml_clear_errors();

    $xpath = new DOMXPath($dom);
    $spans = $xpath->query('//pre//span | //code//span');

    foreach ($spans as $span) {
        while ($span->childNodes->length > 0) {
            $span->parentNode->insertBefore($span->childNodes->item(0), $span);
        }
        $span->parentNode->removeChild($span);
    }

    return trim($dom->saveHTML());
}

// Uso: limpe o HTML antes de converter
$htmlLimpo = removerSpansDoCode($html);
$markdown = htmlParaMarkdown($htmlLimpo);

Considerações de Segurança

Importante

Por padrão, a biblioteca preserva tags não reconhecidas como <script>, <iframe> e <div>. Ao processar entrada de usuários não confiáveis, sempre habilite strip_tags ou remove_nodes.

Para conteúdo gerado por usuários, combine com HTML Purifier para segurança adicional:

php
use HTMLPurifier;
use HTMLPurifier_Config;
use League\HTMLToMarkdown\HtmlConverter;

function htmlSeguroParaMarkdown(string $htmlNaoConfiavel): string
{
    // Primeiro, sanitize com HTML Purifier
    $config = HTMLPurifier_Config::createDefault();
    $purifier = new HTMLPurifier($config);
    $htmlLimpo = $purifier->purify($htmlNaoConfiavel);

    // Depois converta para Markdown
    $converter = new HtmlConverter([
        'strip_tags' => true,
        'remove_nodes' => 'script style iframe object embed',
    ]);

    return $converter->convert($htmlLimpo);
}

Problemas Comuns

DOMDocument Não Encontrado

No CentOS ou instalações PHP mínimas, você pode ver:

Fatal error: Class 'DOMDocument' not found

Corrija instalando a extensão PHP XML:

bash
# CentOS/RHEL
sudo yum install php-xml

# Ubuntu/Debian
sudo apt-get install php-xml

Avisos de HTML Malformado

Suprima avisos para HTML malformado (comum com conteúdo extraído):

php
$converter = new HtmlConverter(['suppress_errors' => true]);

Conclusão

A biblioteca league/html-to-markdown lida com a complexidade da conversão HTML-para-Markdown com padrões sensatos e ampla personalização. Pontos principais:

  • Use strip_tags e remove_nodes para limpar elementos indesejados
  • Adicione TableConverter para suporte a tabelas
  • Sempre sanitize entrada não confiável antes de processar
  • Pré-processe blocos de código com syntax highlighting para saída mais limpa

Para pipelines de LLM ou processamento de conteúdo, essa combinação de opções de configuração fornece Markdown limpo e legível de quase qualquer fonte HTML.