- O Html Agility Pack permite análise e consulta robustas de HTML com XPath/LINQ.
- PowerShell e C# cobrem scraping estático; Selenium resolve páginas com JavaScript.
- CsvHelper e IronPDF facilitam a exportação de dados para CSV ou a geração de relatórios em PDF.
- O uso de proxies reduz bloqueios e permite a coleta de dados com foco regional.

Se você está procurando uma maneira prática de extrair dados estruturados Sem precisar exagerar nas expressões regulares, combinar o PowerShell com o HTML Agility Pack é uma daquelas soluções que economiza tempo e trabalho. Essa pilha permite navegar pelo DOM, localizar nós usando XPath ou LINQ e ler texto, atributos ou HTML de forma confiável, mesmo quando a marcação não é perfeita.
Nas linhas a seguir combinamos o melhor de várias abordagens: PowerShell, C# e Selenium para cobrir conteúdo estático e dinâmico, exemplos do mundo real (como extrair o corpo de anúncios do Craigslist), exportação para CSV e até mesmo a capacidade de converter resultados para PDF com o IronPDF. Tudo com Truques útil como o uso de proxies para evitar travamentos e recomendações para manter seus seletores robustos ao longo do tempo.
O que é o HTML Agility Pack e por que ele é tão útil?
HTML Agility Pack (HAP) é uma biblioteca .NET que analisa HTML em um árvore de nós que você pode navegar, consultar e manipular. Ao contrário de outras abordagens mais frágeis, o HAP tolera HTML mal formatado e permite navegar no DOM com XPath ou LINQ usando uma API simples.
Entre seus pontos fortes estão: análise leniente (engole HTML imperfeito), manipulação de DOM (adicionando, excluindo ou modificando nós/atributos), suporte para XPath e LINQ, e bom desempenho mesmo em documentos grandes. Além disso, seu design é extensível, permitindo que você implemente filtros ou manipuladores personalizados sempre que necessário.
Carregar e analisar HTML com HAP: arquivo, string ou web
Para começar, você pode carregar conteúdo HTML de um arquivo local, de uma string na memória ou diretamente de uma URL. A classe-chave é Documento HTML, e para a web é muito confortável de usar Web HTML e seu método Load().
// Desde archivo
var doc = new HtmlDocument();
doc.Load(filePath);
// Desde cadena
var doc2 = new HtmlDocument();
doc2.LoadHtml(htmlString);
// Desde la web
var web = new HtmlWeb();
var doc3 = web.Load("http://example.com/");
Depois que o documento for carregado, você acessa o nó raiz com Nó de Documento. A partir daí, você pode selecionar nós por XPath ou com LINQ, e leia propriedades como OuterHtml, InnerText, Name ou a coleção de atributos com total conforto.
Selecionando e lendo nós: XPath, atributos e limpeza de texto
Com XPath, você pode localizar elementos específicos sem se preocupar com HTML. A biblioteca oferece SelectSingleNode() para um único resultado e SelecionarNós() quando você espera vários.
// Un solo nodo (por ejemplo, el <title> de la página)
var titleNode = doc.DocumentNode.SelectSingleNode("//head/title");
// Varios nodos (por ejemplo, todos los <article>)
var articles = doc.DocumentNode.SelectNodes("//article");
// Lectura de información útil
var name = titleNode.Name; // etiqueta del nodo
var html = titleNode.OuterHtml; // HTML completo del nodo
var text = titleNode.InnerText; // texto plano del nodo
Quando seu texto contém entidades HTML, você pode “limpar” o conteúdo usando utilitários como HtmlEntity.DeEntitize() ou, se preferir BCL, Sistema.Net.WebUtility.HtmlDecode()Isso lhe dá um texto mais natural, pronto para ser processado como dados.
// Limpieza de entidades HTML en texto extraído
var limpio = HtmlEntity.DeEntitize(titleNode.InnerText);
// o
var limpio2 = System.Net.WebUtility.HtmlDecode(titleNode.InnerText);
PowerShell + HTML Agility Pack: Inspeção, Métodos e Extração do Mundo Real
Muitas equipes preferem o PowerShell porque ele permite uma prototipagem de scraping muito rápida. Você pode carregar a DLL do HAP (por exemplo, versão 1.11.59) e usar suas classes a partir de scripts. Se você já trabalhou com módulos como PSParseHTML, na verdade você tem usado HAP por baixo.
# Cargar la DLL (ajusta la ruta a tu entorno)
$hapPath = 'C:\ruta\a\HtmlAgilityPack.dll'
[Reflection.Assembly]::LoadFile($hapPath) | Out-Null
# Descargar una página y cargarla en HtmlDocument
$dest = '$env:TEMP\page.htm'
$wc = New-Object System.Net.WebClient
$wc.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$wc.DownloadFile('http://localhost/mihtml.html', $dest)
$doc = New-Object HtmlAgilityPack.HtmlDocument
$doc.Load($dest)
$root = $doc.DocumentNode
# Por ejemplo, recorrer filas de una tabla
$rows = $root.Descendants('tr')
foreach ($row in $rows) {
$cells = $row.Descendants('td')
if ($cells.Count -ge 2) {
Write-Host ($cells[0].InnerText + ' - ' + $cells[1].InnerText)
}
}
Uma pergunta comum ao explorar objetos no PowerShell é de onde eles vêm ObterValorDoAtributo() e por que várias assinaturas aparecem. No HtmlAgilityPack, os nós expõem esse método com sobrecargas que aceitam o nome do atributo e um valor padrão para converter para string, int, bool, etc. O PowerShell pode exibi-lo como um método genérico (T) ou várias sobrecargas dependendo do mecanismo de digitação, mas para fins práticos, você o usará assim:
# Obtener un atributo (con valor por defecto si no existe)
$href = $node.GetAttributeValue('href', $null)
$tabIndex = $node.GetAttributeValue('tabindex', -1)
$esActivo = $node.GetAttributeValue('data-active', $false)
Regex para HTML? Melhor não. Se você quiser extrair o corpo de um anúncio envolto em um com um id específico, é mais estável de usar xpath do que lutar com padrões frágeis. Por exemplo, para um caso como … :
# Seleccionar el <section> por id (incluso si hay espacios en el id)
$section = $root.SelectSingleNode("//section[@id='posting body']")
if ($section) {
$texto = $section.InnerText
}
Esta abordagem é limpa e sustentável: se a estrutura mudar, você ajusta a xpath E pronto. Você evita erros típicos de expressões regulares em HTML (aninhamento, espaços, atributos em ordens diferentes, etc.).
Uma rápida olhada no VB.NET e outro exemplo no PowerShell
A mesma ideia se aplica em VB.NET ou C#: baixamos o HTML, carregamos em Documento HTML, localizamos linhas e células e extraímos seu texto com muito pouco código.
' VB.NET: recorrer una tabla simple
Using client As New Net.WebClient()
Dim tmp = IO.Path.GetTempFileName()
client.Credentials = CredentialCache.DefaultNetworkCredentials
client.DownloadFile(_URL, tmp)
Dim doc = New HtmlAgilityPack.HtmlDocument()
doc.Load(tmp)
Dim root = doc.DocumentNode
Dim filas = root.Descendants("tr").ToList()
For Each fila In filas
Dim tds = fila.Descendants("td").ToList()
If tds.Count >= 2 Then
Console.WriteLine(tds(0).InnerText & ": " & tds(1).InnerText)
End If
Next
End Using
Como você pode ver, o HAP oferece uma mecanismo de análise sólida e versátil. A diferença entre as linguagens está na sintaxe; o fluxo de trabalho é idêntico: carregar, selecionar nós e ler conteúdo.
Scraping estático em C# passo a passo: do XPath ao CSV
Para sites com conteúdo estático (o HTML já contém os dados), basta baixar a página e analisar seus nós. Vejamos o fluxo completo: instalar o HAP, carregar uma página, selecionar linhas por XPath, mapear para objetos e exportar para CSV com CsvHelper.
1) Instale o HtmlAgilityPack do NuGet. 2) Carregue a URL com HtmlWeb.Load(). 3) Obtenha os nós usando XPath. 4) Extraia o texto de cada célula. 5) Exporte os objetos para CSV com CsvHelperName.
using HtmlAgilityPack;
using System.Collections.Generic;
// URL de ejemplo (Wikipedia)
var url = "https://en.wikipedia.org/wiki/List_of_SpongeBob_SquarePants_episodes";
var web = new HtmlWeb();
var document = web.Load(url);
// XPath que selecciona filas de las tablas de episodios
var nodes = document.DocumentNode.SelectNodes(
"//*[@id='mw-content-text']/div[1]/table[position()>1 and position()<15]/tbody/tr[position()>1]");
// Clase para mapear resultados
public class Episode {
public string OverallNumber { get; set; }
public string Title { get; set; }
public string Directors { get; set; }
public string WrittenBy { get; set; }
public string Released { get; set; }
}
var episodes = new List<Episode>();
foreach (var node in nodes) {
episodes.Add(new Episode {
OverallNumber = HtmlEntity.DeEntitize(node.SelectSingleNode("th[1]").InnerText),
Title = HtmlEntity.DeEntitize(node.SelectSingleNode("td[2]").InnerText),
Directors = HtmlEntity.DeEntitize(node.SelectSingleNode("td[3]").InnerText),
WrittenBy = HtmlEntity.DeEntitize(node.SelectSingleNode("td[4]").InnerText),
Released = HtmlEntity.DeEntitize(node.SelectSingleNode("td[5]").InnerText)
});
}
Para escrever o CSV, o CsvHelper simplifica muito a saída. Basta criar um StreamWriter e chamar Gravar Registros() com sua lista fortemente tipada.
using CsvHelper;
using System.Globalization;
using System.IO;
using (var writer = new StreamWriter("output.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture)) {
csv.WriteRecords(episodes);
}
Dessa forma, qualquer pessoa pode abrir o CSV no Excel e trabalhar com ele dados estruturados sem mexer no código. É um fluxo simples, confiável e fácil de manter caso a estrutura da página mude: basta atualizar seu XPath e pronto.
Quando o HTML não traz os dados: dinâmico, AJAX e Selenium
Em sites dinâmicos, o HTML inicial pode estar vazio e o JavaScript renderiza os dados após as solicitações XHR. Como o HAP não executa JavaScript, você precisa de um navegador headless como o Selenium para renderizar primeiro e extrair depois.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
var url = "https://en.wikipedia.org/wiki/List_of_SpongeBob_SquarePants_episodes";
var chromeOptions = new ChromeOptions();
chromeOptions.AddArguments("headless");
var driver = new ChromeDriver(chromeOptions);
driver.Navigate().GoToUrl(url);
var rows = driver.FindElements(By.XPath(
"//*[@id='mw-content-text']/div[1]/table[position()>1 and position()<15]/tbody/tr[position()>1]"));
foreach (var row in rows) {
var title = row.FindElement(By.XPath("td[2]")).Text;
// ...
}
Em cenários com carregamento lento ou solicitações lentas, adicione um WebDriverEspere esperar que os nós apareçam ou que o Ajax seja concluído. É mais pesado que o HAP, mas para páginas dinâmicas, é o caminho certo a seguir.
Limitação de HAP principal e alternativa ao WebView
O HAP analisa o DOM conforme ele chega do servidor, ou seja, não executa JSSe o seu site de destino exigir scripts para renderizar seu conteúdo, além do Selenium, você pode carregar a página em um controle WebView/Navegador da Web que executa JavaScript e, uma vez pronto, passa o HTML resultante para o HtmlAgilityPack. Dessa forma, você combina renderização real com análise sintática robusta.
Casos de uso: o que fazer com os dados
Uma vez que você tenha seus objetos na memória, o limite é sua imaginação: salvá-los em um banco de dados, transformá-los em JSON para invocar APIs, gerar CSVs para a equipe de negócios ou enviá-los para relatórios periódicos. O segredo é traduzir os resultados para formatos que sua organização já utiliza.
Privacidade, bloqueio e raspagem regional usando proxies
Ao raspar em escala, os sites podem detectar padrões e bloquear seu IPO uso de proxies (de preferência com endereço rotativo) ajuda a evitar banimentos, distribuir a carga e acessar versões regionais do mesmo site. Um bom provedor permite que você escolha o local de saída, ideal para pesquisa de mercado ou precificação internacional.
Os procuradores rotativo Eles atribuem endereços IP diferentes a cada solicitação, dificultando o rastreamento por sistemas antibot. Além disso, se você precisar visualizar catálogos ou preços que variam de acordo com o país, escolha o local do proxy para obter a visualização exata que um usuário real naquela região teria.
Integre o HtmlAgilityPack com o IronPDF: do HTML ao PDF
Existem cenários em que você precisa empacotar os resultados em um documento. É aí que entra o IronPDF: com o HAP, você extrai e compõe o HTML desejado e com IronPDF Você pode convertê-lo para PDF, mantendo os estilos e o layout. É perfeito para relatórios ou entregas compartilhadas fora da equipe técnica.
Instalar o IronPDF é tão simples quanto adicionar o pacote NuGet. Se preferir, também existe a opção de integrar o DLL Manualmente. Após a referência, você cria um HtmlToPdf e renderiza uma string HTML gerada por você a partir do conteúdo extraído.
using HtmlAgilityPack;
using System.Text;
// using IronPdf; // Asegúrate de referenciar IronPDF
var web = new HtmlWeb();
var doc = web.Load("https://ironpdf.com/");
var nodes = doc.DocumentNode.SelectNodes(
"//h1[@class='product-homepage-header product-homepage-header--ironpdf']");
var htmlContent = new StringBuilder();
foreach (var n in nodes) {
htmlContent.Append(n.OuterHtml);
}
var renderer = new IronPdf.HtmlToPdf();
var pdf = renderer.RenderHtmlAsPdf(htmlContent.ToString());
pdf.SaveAs("output.pdf");
Se você precisar adicionar cabeçalhos, rodapés, numeração ou compor páginas com seções extraídas de URLs diferentes, você pode personalizar a saída antes de passá-la para o mecanismo. PDF para um resultado mais polido.
Boas práticas para seletores e manutenção
- Prefira atributos estáveis (IDs ou classes significativas) em vez de índices frágeis como div[3]/extensão[2].
- Evite regex em HTML quando houver uma alternativa DOM/XPath.
- Use HtmlEntity.DeEntitize/HtmlDecode para limpar entidades.
- Centralize XPaths em constantes e documente sua intenção.
- Implementa controles de erro: nós nulos, tempos limite, mudanças estruturais.
- Para dinâmica, adicione esperas explícitas e condições de presença de elementos.
Também é uma boa ideia registrar amostras reais de HTML em testes para detectar falhas quando o site muda. Manter um pequeno conjunto de testes para seus XPaths e mapeamentos é barato e evita problemas de produção, especialmente quando há vários. fontes De dados.
Dicas de desempenho e extensibilidade
O HAP é otimizado para lidar com documentos grandes com uso razoável de memória. No entanto, se você estiver processando muitas páginas, considere a paralelização. Download com limites (por exemplo Semáforo Slim) e normaliza o HTML antes da extração. Se precisar de regras especiais, você pode estender o pipeline com seus próprios filtros antes de construir seus objetos.
Em ambientes mistos, o PowerShell é ideal para orquestrar tarefas (downloads, rotação de proxy, execução de analisadores Scripts compilados em C#) e consolidar resultados. Combinar scripts com utilitários .NET proporciona agilidade sem sacrificar o desempenho.
Se você está começando com expressões regulares, notará que DOM/XPath requer menos manutenção e é muito mais legível. É comum que um seletor bem pensado sobreviva por meses, mesmo com pequenos ajustes. marcação do site de destino.
Todo esse ecossistema (HtmlAgilityPack para análise, Selenium para renderização, se necessário, CsvHelper para exportação e IronPDF para apresentação) se adapta perfeitamente aos fluxos de trabalho de extração e geração de relatórios do mundo real. Com PowerShell, C# ou VB.NET, você pode criar soluções escaláveis e, com o suporte de proxies, operar de forma mais resiliente diante de bloqueios, mudanças regionais ou picos de carga.
Escritor apaixonado pelo mundo dos bytes e da tecnologia em geral. Adoro compartilhar meu conhecimento por meio da escrita, e é isso que farei neste blog, mostrar a vocês tudo o que há de mais interessante sobre gadgets, software, hardware, tendências tecnológicas e muito mais. Meu objetivo é ajudá-lo a navegar no mundo digital de uma forma simples e divertida.