Compare commits

..

5 commits

Author SHA1 Message Date
df85e43b5e borrar script que no funciona 2023-12-27 23:50:59 -03:00
254a068091 *** son warcs no tar 2023-12-27 22:16:20 -03:00
c217161d21 documentación básica
fixes #4
2023-12-27 19:55:08 -03:00
ecbf126619 agregar script para pushear container 2023-12-27 19:18:55 -03:00
bf0313a4b6 añadir productos de ejemplo en index 2023-12-27 19:18:55 -03:00
7 changed files with 81 additions and 12 deletions

4
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"spellright.language": ["es_AR"],
"spellright.documentTypes": ["markdown", "latex", "plaintext"]
}

View file

@ -1,13 +1,11 @@
import type { Config } from "drizzle-kit"; import type { Config } from "drizzle-kit";
if (!process.env.DB_PATH) throw new Error("no hay DB_PATH"); export const DB_PATH = process.env.DB_PATH ?? "../scraper/sqlite.db";
export const DB_PATH = process.env.DB_PATH;
export default { export default {
schema: "./schema.ts", schema: "./schema.ts",
out: "./drizzle", out: "./drizzle",
dbCredentials: { dbCredentials: {
url: process.env.DB_PATH, url: DB_PATH,
}, },
} satisfies Config; } satisfies Config;

View file

@ -5,7 +5,6 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"migrate": "bun migrate.ts",
"generate": "drizzle-kit generate:sqlite" "generate": "drizzle-kit generate:sqlite"
}, },
"keywords": [], "keywords": [],

42
readme.md Normal file
View file

@ -0,0 +1,42 @@
# preciazo
scrapeo "masivo" de precios y datos en supermercados argentinos
## componentes (en orden de proceso)
- los link scrapers ([coto-link-scraper](./coto-link-scraper/), [dia-link-scraper](./dia-link-scraper/) y [userscripts/carrefour.js](./userscripts/carrefour.js)) crean listas de links a productos para scrapear
(no hace falta correrlos porque ya hay listas armadas en [data/](./data/))
- se usa wget (potencialmente reemplazado por algo custom en el futuro) que genera un archivo [WARC](https://iipc.github.io/warc-specifications/specifications/warc-format/warc-1.0/) con todas las paginas de productos
- el [scraper](./scraper/) procesa estos WARCs, extrayendo varios datos y guardandolos en una base de datos SQLite (definida en [db-datos](./db-datos/schema.ts))
- el [sitio](./sitio/) renderiza páginas a partir de la base de datos y hace gráficos lindos
## setup
hay que instalar [Bun](https://bun.sh/), que lo estoy usando porque hacía que el scraper corra más rápido. quizás en el futuro lo reemplace con good old Node.js.
aparte, se necesita zstd, que se usa para comprimir los WARCs eficientemente. seguro está disponible en las repos de tu distro favorita :)
empezá descargando un WARC con 50 páginas de sample, y recomprimilo con zstd:
```
wget --no-verbose --tries=3 --delete-after --input-file ./data/samples/Dia.txt --warc-file=dia-sample
gzip -dc dia-sample.warc.gz | zstd --long -15 --no-sparse -o dia-sample.warc.zst
```
después, scrapealo a una BD:
```
cd scraper/
bun install
bun cli.ts scrap ../dia-sample.warc.zst
```
ahora miralo en el sitio:
```
cd sitio/
bun install
bun --bun dev
```

View file

@ -6,6 +6,7 @@
"dev": "vite dev", "dev": "vite dev",
"build": "vite build", "build": "vite build",
"build:container": "bun --bun vite build && podman build -t gitea.nulo.in/nulo/preciazo/sitio .", "build:container": "bun --bun vite build && podman build -t gitea.nulo.in/nulo/preciazo/sitio .",
"push:container": "bun build:container && podman push gitea.nulo.in/nulo/preciazo/sitio",
"preview": "vite preview", "preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",

View file

@ -3,7 +3,7 @@ import { drizzle } from "drizzle-orm/bun-sqlite";
import * as schema from "db-datos/schema.js"; import * as schema from "db-datos/schema.js";
import { env } from "$env/dynamic/private"; import { env } from "$env/dynamic/private";
const sqlite = new Database(env.DB_PATH); const sqlite = new Database(env.DB_PATH ?? "../scraper/sqlite.db");
export const db = drizzle(sqlite, { schema }); export const db = drizzle(sqlite, { schema });
export * as schema from "db-datos/schema.js"; export * as schema from "db-datos/schema.js";

View file

@ -6,7 +6,31 @@
<h1 class="text-xl">WIP</h1> <h1 class="text-xl">WIP</h1>
<ul> <section>
<h2 class="text-lg font-bold">Ejemplos</h2>
<ul>
<li>
<a href="/ean/7790070410795">
Cookies Sabor Vainilla Con Chips De Chocolate Exquisita Paq 300 Grm
</a>
</li>
<li>
<a href="/ean/7794000006911">
Sopa Instantánea KNORR QUICK Zapallo Romero Sobres 5 Un.
</a>
</li>
<li>
<a href="/ean/7798062540253">Agua Saborizada Levité Pera 1,5 Lts.</a>
</li>
<li>
<a href="/ean/7790895000430">Gaseosa Coca-Cola Sabor Original 1,5 Lts.</a>
</li>
</ul>
</section>
<section>
<h2 class="text-lg font-bold">Random</h2>
<ul>
{#each data.precios as product} {#each data.precios as product}
<li> <li>
<a href={`/ean/${product.ean}`}> <a href={`/ean/${product.ean}`}>
@ -14,4 +38,5 @@
</a> </a>
</li> </li>
{/each} {/each}
</ul> </ul>
</section>