Scraper de precos sem backend/sem banco, com execucao diaria no GitHub Actions, persistencia em arquivos no proprio repositorio e dashboard estatico em GitHub Pages.
Tambem permite adicionar produtos pelo site via GitHub Issue.
- Fonte de produtos:
data/products.json - Cascata de engines:
engine1_http(axios+cheerio)engine2_browser(Playwright leve)engine3_hardmode(Playwright agressivo + fallback opcional de provider externo)
- Saida:
data/latest.jsondata/runs/YYYY-MM-DD.jsondata/errors/YYYY-MM-DD.jsondata/runs/index.json
- Espelho para GitHub Pages:
docs/data/*(sincronizado automaticamente pelo scraper/ingest) - Dashboard:
docs/(estatico, sem API) - Add-product sem backend: formulario do site abre Issue; workflow ingere e atualiza
data/products.json+docs/data/products.json.
- Node.js 20+
- npm 10+
- Instale dependencias:
npm ciNo PowerShell do Windows, se houver bloqueio de npm/npx:
npm.cmd ci- Copie e ajuste variaveis:
cp .env.example .env- Instale Chromium do Playwright:
npx playwright install --with-deps chromiumNo PowerShell do Windows:
npx.cmd playwright install chromium- Rode scraping local:
npm run scrapeNo PowerShell do Windows:
npm.cmd run scrape- Modo debug:
npm run dev- Rode testes:
npm testDEBUG:0ou1HTTP_TIMEOUT_MS: timeout HTTP/base das navegacoesCONCURRENCY: limite de paralelo (clamp 1..5)USER_AGENT: user-agent customPROXY_URL: proxy opcional para hard mode (http(s)://...ousocks5://...)SCRAPING_API_KEY: opcional para fallback externo no engine3 (ZenRows)
Sem SCRAPING_API_KEY, o sistema funciona apenas com engines locais.
- Trigger:
schedulediario +workflow_dispatch - Fluxo:
npm cinpx playwright install --with-deps chromiumnpm run scrape- commit/push de mudancas em
data/edocs/data/
Permissao necessaria do workflow:
contents: write
- Trigger: issue
opened - Processa apenas quando:
- label
add-productoumanage-product, ou - titulo com prefixo
[ADD PRODUCT]ou[MANAGE PRODUCT]
- label
- Script:
.github/scripts/ingest_issue.mjs - Resultado:
- valida payload
- suporta
action: add|edit|remove - evita duplicidade por URL normalizada
- atualiza
data/products.jsonedocs/data/products.json - comenta e fecha issue
Permissoes necessarias:
contents: writeissues: write
- No repositorio, abra
Settings->Pages. - Em
Build and deployment, selecione:Source:Deploy from a branchBranch:mainFolder:/docs
- Salve.
- A pagina sera publicada em
https://<owner>.github.io/<repo>/.
- Abra o dashboard em
/. - Clique em
Adicionar Produto. - Preencha formulario e envie.
- O site abre a tela de nova issue no GitHub ja preenchida.
- Confirme envio da issue.
- O workflow
ingest_issue.ymlvalida e adiciona nodata/products.jsonedocs/data/products.json.
O parser aceita:
- Bloco
```json ... ```no corpo da issue (preferencial) - Campos do Issue Form (
.github/ISSUE_TEMPLATE/add-product.yml) - Acao de gerenciamento por issue (
add,edit,remove) com labelmanage-producte titulo[MANAGE PRODUCT]
Nome: obrigatorio. Nome exibido no dashboard e snapshots.URL: obrigatorio. URL HTTP/HTTPS da pagina do produto.Categoria: opcional, mas recomendado para filtros e agrupamento.Unidades por pacote: opcional (> 0). Usado para calcularunit_price.Ativo: sefalse, o produto fica cadastrado mas nao entra no scraping.Repositorio (owner/repo): obrigatorio para abrir a issue no repositorio correto.Seletores CSS(um por linha): opcional. Ajuda em paginas com HTML dificil.JSON-LD paths(um por linha): opcional. Preferencial para extracao estavel.Regex hints(um por linha): opcional. Ultimo fallback.Observacoes: opcional. Campo livre para contexto humano.
{
"action": "add",
"name": "Mouse Logitech G203 Lightsync",
"url": "https://www.kabum.com.br/produto/166771/mouse-gamer-logitech-g203-lightsync-rgb-6-botoes-8000-dpi-preto-910-005793",
"category": "perifericos",
"units_per_package": 1,
"is_active": true,
"selectors": {
"price_css": [
"[data-testid='price-current']",
".finalPrice"
],
"jsonld_paths": [
"offers.price",
"price"
]
},
"notes": "Exemplo de cadastro"
}- Rode scraping local:
npm.cmd run scrape-
Confirme arquivos gerados/atualizados:
data/latest.jsondata/runs/YYYY-MM-DD.jsondata/errors/YYYY-MM-DD.jsondocs/data/latest.jsondocs/data/runs/YYYY-MM-DD.json
-
Suba servidor estatico local:
npx.cmd http-server -p 5500 .-
Abra:
- Dashboard:
http://localhost:5500/docs/ - Gestao:
http://localhost:5500/docs/manage.html
- Dashboard:
-
Crie um produto via UI (abre issue), confirme envio no GitHub e aguarde workflow.
-
Rode
git pulllocal para trazer as alteracoes emdata/products.jsonedocs/data/products.json. -
Rode
npm.cmd run scrapenovamente e atualize a tela.
npm testvalida funcoes unitarias, nao garante scraping real de sites externos.- Se
npxfalhar no PowerShell, usenpx.cmd(politica de execucao do Windows). - Se Chromium nao estiver instalado, engine2/engine3 falham com
Executable doesn't exist. - Alguns sites retornam
403/404por bloqueio anti-bot, geolocalizacao ou URL expirada. - Abrir HTML com
file://pode bloquearfetch; use servidor local (http://localhost:5500). - Fluxo add/edit/remove via UI abre issue; alteracao real ocorre no workflow remoto, depois exige
git pull.
Cada item suporta:
idurlnamecategory(opcional)units_per_package(opcional, >0)is_activeselectors(opcional):price_cssjsonld_pathsregex_hints
notes(opcional)
product_id,url,nameprice,currencyunit_priceengine_usedfetched_atsourceconfidencestatus: "ok"
- Scraping pode falhar por CAPTCHA, bloqueio por IP/datacenter, mudanca de HTML ou rate-limit.
- Respeite ToS e robots dos sites monitorados.
- Evite concorrencia alta desnecessaria; o padrao e 4.
- Use intervalos e lista de produtos razoavel.
- Para sites mais restritivos, considere
PROXY_URLe/ouSCRAPING_API_KEY.