Come ho costruito un database SQLite parsificando i dati dei pokemon disponibili sulle guide online
Partendo dall'esperienza del precedente articolo ( che vi riporto ) possiamo decidere di concentrarci su alcune pagine specifiche che contengono i dati che ci interessano.
In particolare voglio :
In particolare voglio :
- la lista completa dei pokemon di prima generazione
- la lista delle mn e di quali pokemon possono impararle
1. lista pokemon
Per estrarre la lista dei pokemon e crearne un json potete fare riferimento al precedente post.
Ne otterremo un json che potete trovare a questo indirizzo : github.com/pokedex_list.json
Ne otterremo un json che potete trovare a questo indirizzo : github.com/pokedex_list.json
2. mn e quali pokemon possono impararle
In modo del tutto simile al primo ho estratto i dati dalle pagine html della wiki di pokemoncentral. Per fare un esempio dalla pagina relativa al MN Taglio ( https://wiki.pokemoncentral.it/Taglio ) potete estrarre le informazioni necessarie con il seguente script:
In modo del tutto simile al primo ho estratto i dati dalle pagine html della wiki di pokemoncentral. Per fare un esempio dalla pagina relativa al MN Taglio ( https://wiki.pokemoncentral.it/Taglio ) potete estrarre le informazioni necessarie con il seguente script:
function getPkList(tbl, array){$(tbl).find('tr').each(function (i) { //loop on each tr in table// SKIP HEADERif(i===0) return;//CREATE POKEMON OBJECTvar poke = {};var $tds = $(this).find('td'); //get all td tagspoke.strid = $tds.eq(1).text(); //access first td and get text contentpoke.strid = poke.strid.replace('#','');poke.id = parseInt(poke.strid, 10);poke.imageUrl = $tds.eq(2).find('img')[0].getAttribute('src'); //access second td and get src attribute of the img tagpoke.name = $tds.eq(3).find('a')[0].text;poke.type1 = $tds.eq(4)[0].innerText;if($tds.eq(5)[0])poke.type2 = $tds.eq(5)[0].innerText;array.push(poke); //save object to the array});}
Il codice completo lo potete trovare a questo indirizzo: https://github.com/mcmaur/MyPokedex/blob/master/data/parser/parse_mn_list.js
Probabilmente dovrete adattarlo un poco a secondo della struttura delle altre pagine delle MN.
Una volta che lo avete eseguito su ogni MN vi troverete questo json:
https://github.com/mcmaur/MyPokedex/blob/master/data/MN_list.json
Struttura del database
Cosa facciamo di questi due json? Bhè a sto punto studiamo una configurazione del database più adatta ai nostri dati e li importiamo.Risulta piuttosto evidente che il cuore è il POKEMON. Ogni pokemon ha 1 o 2 TIPI.
Ci sono 5 MN e per ognuna c'è una lista di pokemon compatibili. Per questo motivo il database avrà questa struttura:
Import dei dati in database
Nell'ambito della sperimentazione ho voluto provare Node.js .
Il codice contenuto nell'app.js fai i seguenti passaggi:
Il codice contenuto nell'app.js fai i seguenti passaggi:
- crea le tabelle del database
db.prepare(`CREATE TABLE IF NOT EXISTS \`types\` (\`id\` INT NOT NULL, \`name\` VARCHAR(100) NOT NULL,PRIMARY KEY (\`id\`));`).run();
- leggo il json e ciclo su ogni valore
let pokelist = JSON.parse(fs.readFileSync('./data/pokedex_list.json', 'utf8'));for (let index in pokelist) {
- verifico se il tipo è già presente altrimenti l'aggiungo
let t1 = -1, t2 = -1;for (let i in types) {if(pokelist[index].type1 === types[i]) t1 = i;if(pokelist[index].type2 === types[i]) t2 = i;}if(t1 === -1) t1 = (types.push(pokelist[index].type1))-1;if(pokelist[index].type2 !== undefined && t2 === -1) t2 = (types.push(pokelist[index].type2))-1;
- inserisco il pokemon nel database
const stmt = db.prepare('INSERT INTO pokemon(id, imageurl, name, type1, type2) VALUES(?, ?, ?, ?, ?)');
let info;
if(t2 === -1)
info = stmt.run(pokelist[index].id, pokelist[index].imageUrl, pokelist[index].name, t1, null);
- al termine del ciclo su tutti i pokemon salvo i tipi che avevo temporaneamente tenuto in un array
for (var i in types) {
const info = db.prepare('INSERT INTO types(id, name) VALUES(?, ?)').run(i, types[i]);
Adesso invece leggiamo i dati delle MN e importiamo anche quelli in maniera molto simile
let mnlist = JSON.parse(fs.readFileSync('./data/MN_list.json', 'utf8'));
mnlist = mnlist['MN'];
for (let key in mnlist) {
console.log("Id " + mnlist[key].id +': '+mnlist[key].name+'| '+mnlist[key].pokes);
const stmt = db.prepare('INSERT INTO mn(id, name) VALUES(?, ?)');
let info = stmt.run(mnlist[key].id, mnlist[key].name);
console.log("insert MN: "+info.changes);
let compatible_pokemons = mnlist[key].pokes;
for (let k in compatible_pokemons) {
const stmt = db.prepare('INSERT INTO mn_pokemon(mn_id, pokemon_id) VALUES(?, ?)');
let info = stmt.run(mnlist[key].id, compatible_pokemons[k]);
console.log("insert MN-POKEMON: "+info.changes);
}
}
FINITO: il codice completo lo potete trovare a questo indirizzo: https://github.com/mcmaur/MyPokedex/blob/master/app.js
Database scaricabile
Al termine avrete un database sqlite con tutti i dati. Il mio è disponibile a questo indirizzo: https://github.com/mcmaur/MyPokedex/blob/master/pokebase.db
Volete sapere qual'è il pokemon che può imparare più MN di tutti?
Facile! Eseguite la seguente query :
Volete sapere qual'è il pokemon che può imparare più MN di tutti?
Facile! Eseguite la seguente query :
select p.id, p.name, count(m.id) as mnlearnable -- , p.name, m.name-- select *from pokemon p join mn_pokemon mnp on p.id = mnp.pokemon_idleft join mn m on mnp.mn_id = m.idgroup by p.id order by mnlearnable desc
ed otterrete questi risultati:
Have Fun!