Executando verificação de segurança...
3

Pitch: Fiz um Parser de HTML em Rust para Node.js

Uns tempos atrás quando procurava bibliotecas para a manipuação de imagens em Node.js, conheci o @napi-rs/canvas que é uma biblioteca escrita em Rust; fiquei curioso sobre e vi que NAPI-RS é um framework que faz essa ponte entre Rust e Node.js, permitindo que você crie bibliotecas rápidas em Rust e as use no Node.js até com tipagens prontas.

Ontem, querendo fazer um teste, para ver se eu conseguiria criar a biblioteca mais rápida de parsing de HTML no ecossistema do Node.js, iniciei o Xcrap HTML Parser e, eu consegui:

Comparação com as outras bibliotecas do ecossitema Node.js:

@xcrap/html-parser         :0.246214 ms/file ± 0.136808
html-parser                :36.8255 ms/file ± 28.8551
htmljs-parser              :0.501577 ms/file ± 1.21080
html-dom-parser            :2.18028 ms/file ± 1.79617
html5parser                :1.67464 ms/file ± 1.22279
cheerio                    :8.67998 ms/file ± 6.32852
parse5                     :4.82118 ms/file ± 2.66822
htmlparser2                :1.49739 ms/file ± 1.39804
htmlparser                 :16.1712 ms/file ± 109.076
high5                      :2.98229 ms/file ± 1.92748
node-html-parser           :2.90167 ms/file ± 1.90804

Claro que eu não fiz tudo do zero, na verdade, foi pouca coisa até. Utilizei essas bibliotecas já existentes no ecossistema do Rust:


Instalação

A instalação é muito simples, você pode usar o NPM ou qualquer outro gerenciador de pacotes de sua escolha: como PNPM, Yarn, etc.

npm i @xcrap/html-parser

Como Usar

import { HtmlParser, css, xpath } from "@xcrap/html-parser"

// HTML de exemplo
const html = `
    <div>
        <h1 class="title">Hello World</h1>
        <p>Web scraping com Rust é rápido!</p>
        <ul>
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
        </ul>
    </div>

`

// Instanciamos o parser
const parser = new HtmlParser(html)

// Selecionando um elemento
const heading1 = parser.selectFirst({ query: xpath("//h1") })

console.log(heading1.text)

// Selecionando vários elementos
const listItems = parser.selectMany({ query: css("ul li"), limit: 2 })
const texts = listItems.map(item => item.text)

console.log(texts)

Se tiverem interesse em contribuirem/ajudarem na documentação, fiquem à vontade para subir um PR ;)

Carregando publicação patrocinada...