Wiki script - Dump sorgenti delle guide (Python 3): differenze tra le versioni

dizionari + threading
mNessun oggetto della modifica
(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).<br/>
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 getPidTitoli():
def get_pid_and_titles():
         # Restituisce due valori: il primo valore è una lista di liste con i titoli di tutte le guide del Wiki e il
         # Restituisce un dizionario con i pageid (chiavi) e, come valori,
         # pageid del tipo: [ ["pageid1", "title1"], ["pageid2", "title2"], ...]
        # una lista di titolo + contenuto della guida (inizialmente vuoto)
         # Es. ->  [ ["1234", "titolo_guida"], ["5678", "altro_titolo", ... ] ]
        # esempio:
         # Come secondo valore viene restituita una lista di tutti i pageid. Es -> ["1234", "5678", "9012", ...]
        # {
         # Questo secondo valore è necessario per prelevare il contentuto della guida (contenuto, timestamp, etc)
         #   pageid1 : ['titolo1', ''],
        #    pageid2 : ['titolo2', ''],
         #   pageid3 : ['titolo3', ''],
        #    ...
         #   ...
         # }


         all_titles_params = {
         all_titles_params = {
                                        'action' : 'query',
                            'action' : 'query',
                                        'list' : 'allpages',
                            'list' : 'allpages',
                                        'aplimit' : '500',
                            'aplimit' : '500',
                                        'apfilterredir' : 'nonredirects',
                            'apfilterredir' : 'nonredirects',
                                        'format' : 'json',
                            'format' : 'json',
                                        'apfrom' : ''
                            'apfrom' : ''
                                        }
                            }
          
          
         lista = []
         # dizionario ordinato
         lista_pid = []
         mydict = collections.OrderedDict()
          
          
         while True:
         while True:
Riga 66: Riga 75:


             for x in dati['query']['allpages']:
             for x in dati['query']['allpages']:
                 lista.append(  x['title'] )
                 mydict[x['pageid']] = [x['title'], '']
                lista_pid.append(x['pageid'] )


             # 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 lista, lista_pid
         return mydict


      
      
def getContent(lista_pageid):
def get_content(dizionario):
     # accetta in ingresso una lista di tutti i pageid ( Es. [1234, 5678, 9012, ... ] )
     # accetta in ingresso il dizionario incompleto (senza contenuto delle guide)
     # e restituisce una lista di tuple. Es -> [ (content), (content), (content) ... ] di *tutte* le guide del Wiki
    # 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',
                        'action' : 'query',
                                        'prop' : 'revisions',
                        'prop' : 'revisions',
                                        'rvprop' : 'content',
                        'rvprop' : 'content',
                                        'pageids' : '',
                        'pageids' : '',
                                        'format' : 'json'
                        'format' : 'json'
                                        }
                        }
   
    # lista delle chiavi del dizionario (pageids)
    lista_pageid = list(dizionario.keys())
      
      
     # converte la lista in ingresso in una lista di liste (di max 50 valori ciascuna in
     # 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)]
      
      
     while True:
     q = queue.Queue()
       
            mylist = []


            for elem in listFifty:
    for elem in listFifty:
                # separatore tra gli elementi della lista (interi) è "|"
        # separatore tra gli elementi della lista (interi) è "|"
                # es. 1234, 5678, 9012 -> 1234|5678|9012
        # es. 1234, 5678, 9012 -> 1234|5678|9012
                listaid = "|".join(map(str,elem))
        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()


                # modifica il valore del dizionario
    return dizionario
                content_ts_params['pageids'] = listaid
                d_reply = api(content_ts_params)
               
                for subelem in elem:           
                    mycontent = d_reply['query']['pages'][str(subelem)]['revisions'][0]['*']
                    mylist.append( mycontent )
            break


    return mylist


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


def getAll():
    # viene restituita una lista di tuple. Es. -> [(pageid, titolo, content), (pageid, titolo, content), ... ]
   
    lista, listapid = getPidTitoli()
    listaCont = getContent(listapid)
   
    # si hanno ora due liste di tuple
    # 1) lista -> [ ("pageid", "title"), ("pageid", "title"), ("pageid", "title"), ... ]
    # 2) listaContTimest -> [ ("content"), ("content"), ... ]
    # Fondiamole in un'unica lista di tuple...
       
    l = list(zip(lista, listaCont))
   
    return(l)


print('Download delle guide...')
print('Download delle guide...')
mytuplelist = getAll()
mydict = create_dict()




print('Scrittura sul file...')
print('Scrittura sul file...')
with open(NOMEFILE, 'w') as f:
with open(NOMEFILE, 'w') as f:
     for elem in mytuplelist:
     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(elem[0])
         name_parsed = urllib.parse.quote(v[0])
         f.write('þþþþ\nguide.debianizzati.org/index.php?title=' + name_parsed + '&action=edit\n' + elem[1] + '\nøøøø\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]]
6 999

contributi