Wiki script - Dump sorgenti delle guide (Python 3): differenze tra le versioni
Vai alla navigazione
Vai alla ricerca
mNessun oggetto della modifica |
S3v (discussione | contributi) (dizionari + threading) |
||
Riga 2: | Riga 2: | ||
Questo semplice [[script]] Python 3 si occupa di effettuare il download dei sorgenti delle guide di questo Wiki.<br/> | Questo semplice [[script]] Python 3 si occupa di effettuare il download dei sorgenti delle guide di questo Wiki.<br/> | ||
Il file creato si chiamerà "wikidump.txt" (o con qualsivoglia altro nome specificato nella variabile "NOMEFILE" del codice sorgente dello script). | Il file creato si chiamerà "wikidump.txt" (o con qualsivoglia altro nome specificato nella variabile "NOMEFILE" del codice sorgente dello script) e, se si desidera, è possibile modificare il numero di thread (variabile "NUMTHREAD") in base al numero di core/CPU della propria macchina. | ||
Salvare il codice in un file di testo con nome scelto a proprio piacimento e poi eseguirlo. Ad esempio, dopo averlo chiamato "wikidump.py": | Salvare il codice in un file di testo con nome scelto a proprio piacimento e poi eseguirlo. Ad esempio, dopo averlo chiamato "wikidump.py": | ||
<pre> | <pre> | ||
Riga 16: | Riga 17: | ||
import urllib.request | import urllib.request | ||
import json | import json | ||
import queue | |||
from threading import Thread | |||
import collections | |||
URL = 'http://guide.debianizzati.org/api.php' | URL = 'http://guide.debianizzati.org/api.php' | ||
NOMEFILE = 'wikidump.txt' | NOMEFILE = 'wikidump.txt' | ||
NUMTHREAD = 4 | |||
def api(parametri): | def api(parametri): | ||
Riga 43: | Riga 47: | ||
def | def get_pid_and_titles(): | ||
# Restituisce | # Restituisce un dizionario con i pageid (chiavi) e, come valori, | ||
# | # una lista di titolo + contenuto della guida (inizialmente vuoto) | ||
# | # esempio: | ||
# | # { | ||
# | # pageid1 : ['titolo1', ''], | ||
# pageid2 : ['titolo2', ''], | |||
# pageid3 : ['titolo3', ''], | |||
# ... | |||
# ... | |||
# } | |||
all_titles_params = { | all_titles_params = { | ||
'action' : 'query', | |||
'list' : 'allpages', | |||
'aplimit' : '500', | |||
'apfilterredir' : 'nonredirects', | |||
'format' : 'json', | |||
'apfrom' : '' | |||
} | |||
# dizionario ordinato | |||
mydict = collections.OrderedDict() | |||
while True: | while True: | ||
Riga 66: | Riga 75: | ||
for x in dati['query']['allpages']: | for x in dati['query']['allpages']: | ||
mydict[x['pageid']] = [x['title'], ''] | |||
# esiste un blocco successivo? Il limite di un blocco è 500. | # esiste un blocco successivo? Il limite di un blocco è 500. | ||
Riga 79: | Riga 87: | ||
# al titolo della prima guida del blocco successivo | # al titolo della prima guida del blocco successivo | ||
all_titles_params['apfrom'] = ''.join(last) | all_titles_params['apfrom'] = ''.join(last) | ||
return | return mydict | ||
def | def get_content(dizionario): | ||
# accetta in ingresso | # accetta in ingresso il dizionario incompleto (senza contenuto delle guide) | ||
# | # e restituisce il dizionario completo, cioè qualcosa del tipo: | ||
# { | |||
# pageid1 : ['titolo1', 'contenuto1'], | |||
# pageid2 : ['titolo2', 'contenuto2'], | |||
# pageid3 : ['titolo3', 'contenuto3'], | |||
# ... | |||
# ... | |||
# } | |||
# parametri | # parametri | ||
content_ts_params = { | content_ts_params = { | ||
'action' : 'query', | |||
'prop' : 'revisions', | |||
'rvprop' : 'content', | |||
'pageids' : '', | |||
'format' : 'json' | |||
} | |||
# lista delle chiavi del dizionario (pageids) | |||
lista_pageid = list(dizionario.keys()) | |||
# converte la lista | # converte la lista appena ottenuta in una lista di liste (di max 50 valori ciascuna in | ||
# quanto 50 è il max valore consentito dall'API del Wiki) | # quanto 50 è il max valore consentito dall'API del Wiki) | ||
# Qui viene usato il valore 40 per evitare possibili problemi | # Qui viene usato il valore 40 per evitare possibili problemi | ||
listFifty = [lista_pageid[start:start + 40] for start in range(0, len(lista_pageid), 40)] | listFifty = [lista_pageid[start:start + 40] for start in range(0, len(lista_pageid), 40)] | ||
q = queue.Queue() | |||
for elem in listFifty: | |||
# separatore tra gli elementi della lista (interi) è "|" | |||
# es. 1234, 5678, 9012 -> 1234|5678|9012 | |||
listaid = "|".join(map(str,elem)) | |||
# inserisce questa stringa in una coda | |||
q.put(listaid) | |||
def mythreaded_func(): | |||
while not q.empty(): | |||
# preleva un valore dalla coda | |||
mystr = q.get() | |||
# modifica il valore del dizionario | |||
content_ts_params['pageids'] = mystr | |||
d_reply = api(content_ts_params) | |||
for subelem in mystr.split('|'): | |||
mycontent = d_reply['query']['pages'][subelem]['revisions'][0]['*'] | |||
dizionario[int(subelem)][1] = mycontent | |||
q.task_done() | |||
for i in range(NUMTHREAD): | |||
t = Thread(target=mythreaded_func) | |||
t.start() | |||
q.join() | |||
return dizionario | |||
def create_dict(): | |||
# viene restituito il dizionario completo da inviare al file | |||
my_partial_dict = get_pid_and_titles() | |||
my_full_dict = get_content(my_partial_dict) | |||
return my_full_dict | |||
print('Download delle guide...') | print('Download delle guide...') | ||
mydict = create_dict() | |||
print('Scrittura sul file...') | print('Scrittura sul file...') | ||
with open(NOMEFILE, 'w') as f: | with open(NOMEFILE, 'w') as f: | ||
for | for k,v in mydict.items(): | ||
# parsing di caratteri non consentiti in URL (i.e. il carattere "+") | # parsing di caratteri non consentiti in URL (i.e. il carattere "+") | ||
name_parsed = urllib.parse.quote( | name_parsed = urllib.parse.quote(v[0]) | ||
f.write('þþþþ\nguide.debianizzati.org/index.php?title=' + name_parsed + '&action=edit\n' + | f.write('þþþþ\nguide.debianizzati.org/index.php?title=' + name_parsed + '&action=edit\n' + v[1] + '\nøøøø\n') | ||
</pre> | </pre> | ||
[[Categoria: Wiki]] | [[Categoria: Wiki]] | ||
[[Categoria: Python]] | [[Categoria: Python]] |