Pular para o conteúdo

Arcane.Html

Ler HTML de verdade: seletor CSS, tabela como dado, e as duas defesas contra XSS.

Ler uma página — um preço, uma tabela, os links — só dava por expressão regular, e HTML não é regular. A marcação que funciona no teste quebra no primeiro atributo fora de ordem, na primeira tag sem fechar, no primeiro <br> no meio.

Seletor CSS#

dataforge
adopt Arcane.Html as Html

doc := Html.ler(pagina)

out doc.achar("#p1 h2").texto
out [n.texto cycle n in doc.achar_todos("div.produto > h2")]
out doc.achar("a[href]").atributo("href")
EscritaCasa
diva tag
.classequem tem a classe
#idquem tem o id
[attr] · [attr=valor]por atributo
a bb em qualquer lugar dentro de a
a > bb filho direto de a

É CSS, e não XPath: div.preco > span é o que quem escreve HTML já sabe de cor.

O texto junta com espaço#

text
<span class="preco"><b>R$</b> <span>450,00</span></span>
dataforge
out doc.achar(".preco").texto        // "R$ 450,00"

Colado, isso viraria R$450,00. Com espaço é o que a página mostra — e é o que quem extrai quer.

Extrair#

dataforge
out doc.links("https://forja.br/loja/")
// [{texto: Ver, destino: https://forja.br/produto/1, titulo: }]

out doc.tabela()
// {cabecalho: [Item, Preço], linhas: [[Bigorna, 450], [Marreta, 75]]}

out doc.imagens()

As duas defesas#

Escapar — antes de mostrar#

dataforge
respond html $"<p>{Html.escapar(comentario)}</p>"

É a defesa contra XSS que mais se esquece: um texto que veio de fora, escrito direto na página, é código.

Limpar — tirar toda a marcação#

dataforge
assert Html.limpar("<p>ok</p><script>roubar()</script>") is "ok"

Podar — deixar alguma marcação#

Para comentário e conteúdo de usuário, onde negrito e link fazem sentido:

dataforge
seguro := Html.podar(comentario)
// <p>, <b>, <a>, <ul>… passam; <script>, <iframe>, <style> somem

HTML real não é bem formado#

Tag sem fechar, tag fechada que ninguém abriu, <br> solto: o leitor engole tudo isso, porque a página que você quer ler está cheia disso e derrubar a leitura não serve a ninguém.