Come usare i file di webatla

Ogni file è in JSON Lines compresso con zstd, un dominio per riga. Ecco come aprirlo, interrogarlo e caricarlo nel suo stack. Ogni ricetta è stata eseguita sul campione gratuito di 10.000 righe e l’output che vede è quello che ha stampato.

Formato
JSON Lines, compresso con zstd
.jsonl.zst
Una riga per
Dominio, ogni chiave sempre presente
i valori possono essere null
Nome del file
Dataset e data di esportazione
all-data-2026-10-16.jsonl.zst
Aggiornamento
Una nuova esportazione ogni giorno
le stesse colonne ogni giorno

1 · Aprire il file

Guardi dentro senza decomprimerlo

Tutti e tre leggono il file compresso in streaming. Scelga lo strumento che ha già.

DuckDB

brew install duckdbwinget install DuckDB.cli

SELECT Domain, TLD, "Country by IP", "HTTP status"
FROM read_json('all-data-2026-10-16.jsonl.zst',
  columns = {Domain: 'VARCHAR', TLD: 'VARCHAR',
             "Country by IP": 'VARCHAR', "HTTP status": 'INTEGER'})
LIMIT 3;
Output reale sul campione gratuito di 10.000 righe
Domain       TLD  Country by IP  HTTP status
360.0.bg     bg   BG             200
digsys.0.bg  bg   NULL           200
dnssec.0.bg  bg   NULL           0

zstdcat + jq

brew install zstd jqapt install zstd jq

zstdcat dns-2026-10-16.jsonl.zst | head -n 1 | jq .
Output reale sul campione gratuito di 10.000 righe
{
  "Domain": "360.0.bg",
  "TLD suffix": "0.bg",
  "TLD": "bg",
  "Domain type": "ICANN",
  ...

Python

pip install zstandard

import io, json, zstandard
with open("dns-2026-10-16.jsonl.zst", "rb") as fh:
    stream = zstandard.ZstdDecompressor().stream_reader(fh, read_across_frames=True)
    for line in io.TextIOWrapper(stream, encoding="utf-8"):
        row = json.loads(line)
        mx = (row["DNS records"] or {}).get("MX") or []
        if any((m.get("host") or "").lower().endswith(".google.com") for m in mx):
            print(row["Domain"])
Output reale sul campione gratuito di 10.000 righe
edu5.0.bg
shopping.9guacu.br
ffe.a.se
...

2 · Rispondere a domande

Le domande a cui risponde il file giornaliero

Prima la risposta, con la query DuckDB a un clic di distanza. Apra un terminale nella cartella del download, digiti duckdb e incolli la query.

Vendite Technologies

Quali negozi WooCommerce sono ospitati in Germania?

Output reale sul campione gratuito di 10.000 righe
ariana.acDE
fjak.acDE
empower.abudhabiDE

Ordinati per PR value, salvati come woocommerce-de.csv con 12 righe. Un CSV che il suo CRM o foglio di calcolo sa aprire.

Mostrare la query
COPY (SELECT Domain, "PR value" FROM read_json('technologies-2026-10-16.jsonl.zst',
    columns = {Domain: 'VARCHAR', "Country by IP": 'VARCHAR',
               Technologies: 'JSON', "PR value": 'DOUBLE'})
  WHERE "Country by IP" = 'DE' AND list_contains(CASE json_type(Technologies)
    WHEN 'OBJECT' THEN json_keys(Technologies)
    WHEN 'ARRAY' THEN from_json(Technologies, '["VARCHAR"]') END, 'WooCommerce')
  ORDER BY "PR value" DESC
) TO 'woocommerce-de.csv';
Dataset Technologies →
Marketing di prodotto Technologies

Quale site builder è alla base del maggior numero di siti web?

Output reale sul campione gratuito di 10.000 righe
WordPress628 · 80,6%
Wix52 · 6,7%
Squarespace45 · 5,8%
Drupal22 · 2,8%
Webflow20 · 2,6%
Joomla12 · 1,5%

Quota calcolata tra questi sei builder, non tra tutti i siti web. La esegua su un taglio per paese per confrontare un singolo mercato.

Mostrare la query
SELECT tech, count(*) AS sites,
       round(100 * count(*) / sum(count(*)) OVER (), 1) AS pct
FROM (SELECT unnest(CASE json_type(Technologies)
        WHEN 'OBJECT' THEN json_keys(Technologies)
        WHEN 'ARRAY' THEN from_json(Technologies, '["VARCHAR"]') END) AS tech
      FROM read_json('technologies-2026-10-16.jsonl.zst', columns = {Technologies: 'JSON'}))
WHERE tech IN ('WordPress', 'Wix', 'Squarespace', 'Webflow', 'Drupal', 'Joomla')
GROUP BY tech ORDER BY sites DESC;
Dataset Technologies →
Protezione del marchio RDAP & WHOIS

Quali nuovi domini contengono il nome del suo marchio?

Output reale sul campione gratuito di 10.000 righe, eseguito il 16 ott 2026
kayorashop.store2026-10-11
moonovaactivewearshop.com2026-10-10
shopcastava.com2026-10-01

Registrati negli ultimi 30 giorni, con il registrar. Sostituisca shop con il nome del suo marchio.

Mostrare la query
SELECT "Domain creation date"[:10] AS created, Domain, Registrar
FROM read_json('rdap-whois-2026-10-16.jsonl.zst', columns = {Domain: 'VARCHAR',
  "Domain creation date": 'VARCHAR', Registrar: 'VARCHAR'})
WHERE Domain LIKE '%shop%'
  AND "Domain creation date" >= CAST(current_date - 30 AS VARCHAR)
ORDER BY created DESC;
Dataset RDAP & WHOIS →
Investimento in domini Websites + Ranking

Quali siti web in classifica scadono nei prossimi 30 giorni?

Output reale sul campione gratuito di 10.000 righe, eseguito il 16 ott 2026
adamcadre.ac2026-10-24
ama.ab.ca2026-10-31
psychologistsassociation.ab.ca2026-11-09

Ordinati per PR value. Molti registri rinnovano in automatico, quindi lo consideri una lista di monitoraggio e non un elenco dei drop.

Mostrare la query
SELECT Domain, "Domain expiration date"[:10] AS expires
FROM read_json('websites-ranking-2026-10-16.jsonl.zst', columns = {Domain: 'VARCHAR',
  "Domain expiration date": 'VARCHAR', "PR value": 'DOUBLE'})
WHERE "Domain expiration date"
  BETWEEN CAST(current_date AS VARCHAR) AND CAST(current_date + 30 AS VARCHAR)
ORDER BY "PR value" DESC LIMIT 3;
Dataset Websites + Ranking →
Email & infrastruttura DNS

Chi gestisce il DNS di questi domini?

Output reale sul campione gratuito di 10.000 righe
cloudflare.com2277 · 25,1%
registrar-servers.com704 · 7,7%
domaincontrol.com622 · 6,8%

Quota di domini con un record NS utilizzabile, raggruppata per le ultime due etichette del nome host.

Mostrare la query
CREATE OR REPLACE MACRO provider(h) AS
  array_to_string(string_split(lower(rtrim(h, '.')), '.')[-2:], '.');
SELECT provider(json_extract_string("DNS records", '$.NS[0]')) AS dns,
  count(*) AS domains, round(100 * count(*) / sum(count(*)) OVER (), 1) AS pct
FROM read_json('dns-2026-10-16.jsonl.zst', columns = {"DNS records": 'JSON'})
WHERE dns <> '' GROUP BY dns ORDER BY domains DESC, dns LIMIT 3;
Dataset DNS →

3 · Creare un elenco

Un file per foglio di calcolo o CRM, partendo da un taglio

Il file completo non entra in un foglio di calcolo, quindi parta da un taglio: una tecnologia, un TLD, un suffisso di TLD o un paese come file a sé, dalla sua pagina webatla o dall’API. Con l’accesso a Technologies o All data, ogni pagina di tecnologia ha un riquadro di download per il proprio taglio.

Vendite

Prospect in un unico mercato

Il taglio WooCommerce, poi si tiene un solo paese.

COPY (
  SELECT Domain AS Website, "Country by IP" AS Country
  FROM read_json('webatla-technologies-WooCommerce-2026-10-16.jsonl.zst',
    columns = {'Domain': 'VARCHAR', 'Country by IP': 'VARCHAR', 'PR value': 'DOUBLE'})
  WHERE "Country by IP" = 'DE'
  ORDER BY "PR value" DESC
) TO 'woocommerce-germany.csv';
Output reale sul campione gratuito di 10.000 righe
Website,Country
ariana.ac,DE
fjak.ac,DE
empower.abudhabi,DE
Agenzie

Elenco upsell: siti HubSpot che usano anche WordPress

Il taglio HubSpot, poi si tengono gli stack con WordPress.

COPY (
  SELECT Domain AS Website, "Country by IP" AS Country
  FROM read_json('webatla-technologies-HubSpot-2026-10-16.jsonl.zst', columns = {
    'Domain': 'VARCHAR', 'Country by IP': 'VARCHAR', 'Technologies': 'JSON'})
  WHERE list_contains(CASE json_type(Technologies) WHEN 'OBJECT' THEN json_keys(Technologies)
    ELSE json_extract_string(Technologies, '$[*]') END, 'WordPress')
) TO 'hubspot-on-wordpress.csv';
Output reale sul campione gratuito di 10.000 righe
Website,Country
ateliercrescendo.ac,US
Sales ops

Un file per territorio

Si divide un taglio in un CSV per paese del server.

COPY (
  SELECT Domain AS Website, coalesce("Country by IP", 'unknown') AS Country
  FROM read_json('webatla-technologies-WooCommerce-2026-10-16.jsonl.zst',
    columns = {'Domain': 'VARCHAR', 'Country by IP': 'VARCHAR'})
) TO 'woocommerce-by-country'
  (FORMAT csv, PARTITION_BY (Country), WRITE_PARTITION_COLUMNS true, OVERWRITE);
Output reale sul campione gratuito di 10.000 righe
woocommerce-by-country/Country=DE/data_0.csv
woocommerce-by-country/Country=US/data_0.csv
...
Entra in un foglio di calcolo?Un foglio Excel contiene 1.048.576 righe
Siti HubSpot 375.063 Entra in un foglio
Siti WordPress 23.798.524 Filtrare o dividere
All data, il file completo 420.933.308 Troppo grande per qualsiasi foglio di calcolo

4 · Caricarlo

Postgres, Parquet o un join con il suo elenco

PostgreSQL

psql

Ogni riga diventa una riga jsonb, con un indice GIN su Technologies.

psql -c 'CREATE TABLE domains (doc jsonb)'
zstdcat technologies-2026-10-16.jsonl.zst \
  | psql -c "\copy domains FROM STDIN WITH (FORMAT csv, QUOTE e'\x01', DELIMITER e'\x02')"
psql -c "CREATE INDEX ON domains USING gin ((doc->'Technologies'))"
psql -c "SELECT doc->>'Country by IP' AS country, count(*) AS sites FROM domains
         WHERE doc->'Technologies' ? 'WordPress' GROUP BY 1 ORDER BY 2 DESC, 1 LIMIT 5"
Output reale sul campione gratuito di 10.000 righe
COPY 10000
 country | sites
---------+-------
 US      |   300
 DE      |   110
 CA      |    29

Parquet

DuckDB

Colonne tipizzate, con Technologies come elenco di nomi. Può essere caricato in BigQuery, Snowflake, Spark o pandas.

CREATE OR REPLACE MACRO techs(t) AS CASE json_type(t) WHEN 'OBJECT'
  THEN json_keys(t) WHEN 'ARRAY' THEN t->>'$[*]' ELSE []::VARCHAR[] END;
COPY (SELECT "Domain" AS domain, "Country by IP" AS country,
             "PR value" AS pr_value, techs("Technologies") AS technologies
      FROM read_json('technologies-2026-10-16.jsonl.zst', columns = {
        'Domain': 'VARCHAR', 'Country by IP': 'VARCHAR',
        'PR value': 'DOUBLE', 'Technologies': 'JSON'}))
TO 'technologies.parquet' (FORMAT parquet);
Output reale sul campione gratuito di 10.000 righe
technologies.parquet: 10000 rows
domain · country · pr_value · technologies (list of names)

Arricchire il suo elenco

DuckDB

Il suo CSV da un lato, l’esportazione dall’altro, abbinati su Domain.

SELECT c.domain, w."Country by IP" AS country, w."Registrar" AS registrar,
       w."HTTP status" AS http, w."Domain creation date"[:10] AS created
FROM read_csv('my-domains.csv') c
LEFT JOIN read_json('all-data-2026-10-16.jsonl.zst', columns = {
    'Domain': 'VARCHAR', 'Country by IP': 'VARCHAR', 'Registrar': 'VARCHAR',
    'HTTP status': 'INTEGER', 'Domain creation date': 'VARCHAR'}) w
  ON w."Domain" = lower(trim(c.domain))
ORDER BY 1;
Output reale sul campione gratuito di 10.000 righe
domain              country  registrar                    http  created
Tamm.AbuDhabi       AE       ADSIC Registry Operator      200   2018-07-09
easy.ac             US       MarkMonitor Inc.             200   2014-02-27
global.abb          US       CSC Corporate Domains, Inc.  301   2019-10-03

5 · Aggiornamenti giornalieri

Veda cosa è cambiato nella notte

Ogni giorno arriva una nuova esportazione. Confronti due giorni su Domain e passi a valle solo le modifiche. Inverta i due file per elencare i domini che sono usciti.

COPY (
  SELECT "Domain" FROM read_json('all-active-domains-2026-10-16.jsonl.zst',
                                 columns = {'Domain': 'VARCHAR'})
  EXCEPT
  SELECT "Domain" FROM read_json('all-active-domains-2026-10-15.jsonl.zst',
                                 columns = {'Domain': 'VARCHAR'})
) TO 'new-since-yesterday.csv' (HEADER false);

6 · Consigli pratici

Quattro cose da sapere

Technologies ha due forme

Una mappa di nomi e versioni, oppure un elenco di nomi. Legga le chiavi di una mappa e gli elementi di un elenco, e ottiene comunque un unico elenco.

jq: (.Technologies // []) | if type == "object" then keys else . end

I nomi dei campi contengono spazi

Li metta tra virgolette in SQL e usi le parentesi quadre in jq.

SQL: "Country by IP"jq: .["Country by IP"]

Controlli le prime righe

In DuckDB un nome di colonna scritto male restituisce NULL, non un errore.

La dimensione prima della scansione

Il file All data completo pesa circa 34 GB compresso e ha 420.933.308 righe. Quando basta una sola dimensione, scarichi invece il suo taglio.

Ogni ricetta funziona sul file giornaliero completo

Accesso mensile o annuale, una nuova esportazione ogni giorno e un’API per i tagli. Ogni account può anche scaricare un campione gratuito di 10.000 righe di ogni dataset.