Discussioni Wikipedia:Elenchi generati offline/Redirect da grafia senza caratteri speciali da creare

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca

Programma in Python 3[modifica wikitesto]

Scaricare più o meno una volta al mese da dumps.wikimedia il file dei titoli chiamato "itwiki-yyyymmdd-page.sql.gz" (es. itwiki-20200401-page.sql) e decomprimerlo, poi lanciare il seguente programma correggendo le directory. Copiare il risultato nella pagina Wikipedia:Elenchi generati offline/Redirect da grafia senza caratteri speciali da creare

import re
import urllib.request
import urllib.parse
import xml.etree.ElementTree as ET
from urllib.parse import quote 
from urllib.request import urlopen

''' 
Restituisce il titolo senza disambiguante
Elimina il disambiguante dal titolo, 
la parentesi chiusa deve essere l'ultimo carattere
ci deve essere almeno una parentesi aperta
''' 
def DelDisambiguation(Titolo):
    lunghezza = len(Titolo);
    if Titolo[0]=='(': return Titolo
    if (Titolo[lunghezza-1:] == ")"):
        da=Titolo.rfind("(")
        if (da <= 0):
            return Titolo
        else:
            if len(Titolo[0:da-1])==0:
                return Titolo
            return Titolo[0:da-1]
    return Titolo

'''
Restituisce un dizionario con chiave = titolo e valore = n° di link in entrata in ns0
'''
def PuntanoQuiConta(Titoli):
    n_link = {} # dizionario titolo, n° di link
    Titoli = quote(Titoli.replace(' ','_')).replace("%7C", "|")
    url = "https://it.wikipedia.org/w/api.php?action=query"
    data = {
        'format': 'xml', 
        'prop': 'linkshere', 
        'lhprop': 'title', 
        'lhnamespace': '0', 
        'lhlimit': '500',
        'titles': Titoli
        }

    data = urllib.parse.urlencode(data).encode("utf-8")
    req =  urllib.request.Request("https://it.wikipedia.org/w/api.php?action=query")
    xml = ""
    with urllib.request.urlopen(req,data=data) as f:
        xml += f.read().decode("utf-8")

    root = ET.fromstring(xml)
    pages = root.findall("./query/pages/page")
    for page in pages:
        titolo = page.attrib['title']
        links = len(page.findall(".//linkshere/lh"))
        n_link[titolo] = links
    return n_link

def main():
    print("== INIZIO ==")

    dumpfile="C:\\Wiki\\Dump\\itwiki-20230901-page.sql" # file scaricato da dumps.wikimedia
    path = "C:\\Wiki\\Redirect\\" # directory dove caricare i file dell'elaborazione
    
    ''' Creo file con titolo e l'indicazione se è un redirect di tutti i titoli in ns0 '''
    fileIn = open(dumpfile, "r", encoding="utf-8")
    fileOut = open(path + "Titoli.txt", "w",encoding="utf-8")
    for line in fileIn:
        if "INSERT INTO `page` VALUES " in line: # linea con i dati
            line = line.replace("INSERT INTO `page` VALUES (", "")
            chunks = line.split("),(")
            for chunk in chunks:        
                result = chunk.split(",")
                title = ""
                redirect = ""
                if result[1] == "0": # solo ns=0
                    if len(result) == 12: # se lungo 12 non ha virgole nel titolo
                        title += result[2]
                    else: # altrimenti ha delle virgole nel titolo e  devo riunire le singole parti
                        for cnt in range(2,len(result)-12+3):
                            title += result[cnt] + ",";
                        title =  title[:-1]
                    title = title[1:-1]
                    title = title.replace("\\'", "'").replace("\\\"", "\"").replace("\\\\", "\\").replace("_"," "); # rimuovo escape e metto spazi al posto di _
                    redirect = result[3 + len(result) - 12];
                    fileOut.write(title+'\t'+redirect+'\n')
    fileIn.close()
    fileOut.close()

    ''' Dizionario con i caratteri sostitutivi,
    si potrebbe leggere da una pagina Wiki 
    pattern1 sono i caratteri speciali
    pattern2 sono i caratteri sostitutivi '''
    subs = {} 
    pattern1 = "À,Á,Â,Ã,Ä,Å,Ā,Ă,Ą,Æ,á,â,ã,ä,å,ā,ă,ą,æ,Ç,Ć,Č,ç,ć,č,Ď,Đ,đ,È,É,Ê,Ë,Ē,Ė,Ę,Ě,Ĕ,ê,ë,ē,ė,ę,ě,ĕ,Ģ,Ğ,ģ,ğ,Î,Í,Ì,Į,Ī,Ï,î,í,ı,į,ī,ï,Ķ,ķ,Ł,Ļ,Ĺ,ł,ļ,ĺ,Ň,Ņ,Ń,Ñ,ň,ņ,ń,ñ,Õ,Ô,Ó,Ò,Ő,Ø,Ö,Œ,õ,ô,ó,ő,ø,ö,œ,Ŕ,Ř,ŕ,ř,Ś,Š,Ş,ś,š,ş,Þ,Ť,Ț,Ţ,þ,ț,ţ,Ü,Û,Ú,Ù,Ų,Ű,Ů,Ū,ü,û,ú,ų,ű,ů,ū,µ,Ý,Ÿ,ý,ÿ,Ź,Ż,Ž,ź,ż,ž";
    pattern2 = "A,A,A,A,A,A,A,A,A,Ae,a,a,a,a,a,a,a,a,ae,C,C,C,c,c,c,D,D,d,E,E,E,E,E,E,E,E,E,e,e,e,e,e,e,e,G,G,g,g,I,I,I,I,I,I,i,i,i,i,i,i,K,k,L,L,L,l,l,l,N,N,N,N,n,n,n,n,O,O,O,O,O,O,O,Oe,o,o,o,o,o,o,oe,R,R,r,r,S,S,S,s,s,s,T,T,T,T,t,t,t,U,U,U,U,U,U,U,U,u,u,u,u,u,u,u,u,Y,Y,y,y,Z,Z,Z,z,z,z";
    pat1 = pattern1.split(',');
    pat2 = pattern2.split(',');
    for i in range(0,len(pat1)):
        subs[pat1[i]] = pat2[i]
    pat3="["+pattern1.replace(',','')+"]"

    ''' File con tutti i titoli con caratteri speciali che non sono redirect '''
    pattern="^[a-zA-Z0-9 ]*$";
    fileOut = open(path + "ListaTitoliSpeciali.txt", "w",encoding="utf-8") # elenco di titoli con caratteri speciali   
    fileIn = open(path + "Titoli.txt", "r",encoding="utf-8")
    for line in fileIn:
        tmp = line.split('\t')
        if tmp[1] == '0\n': # escludo i redirect
            if re.search(pat3, tmp[0]):
                fileOut.write(tmp[0]+'\n')    
    fileIn.close()
    fileOut.close()  
    
    ''' Dizionario con tutti i titoli
    la chiave è il titolo senza disambiguante
    il valore è il titolo completo, se ce n'è più di uno sono separati da \t '''
    titoli = {}
    fileIn = open(path + "Titoli.txt", "r", encoding="utf-8")
    for line in fileIn:
        tmpTitle = DelDisambiguation(line.split('\t')[0]).replace('\n','')
        if tmpTitle in titoli.keys():
            titoli[tmpTitle] = titoli[tmpTitle] + '\t' + line.replace('\n','')
        else:
            titoli[tmpTitle] = line.replace('\n','')
    fileIn.close()

    ''' Dizionario con titolo corretti
    la chiave è il titolo
    il valore è il titolo con i carattere speciali corretti '''
    regex = "^[a-zA-Z0-9 \-'\?]*$" # si prende in considerazione solo i titoli che contengono questi caratteri
    titolimodificati = {}
    fileIn = open(path + "ListaTitoliSpeciali.txt", "r",encoding="utf-8")
    for line in fileIn:
        newline = ""
        for c in line: # loop sui caratteri del titolo
            if c in subs.keys():
                newline += subs[c]
            else:
                newline += c
        newlineNodab = DelDisambiguation(newline).replace('\n','') # il titolo corretto non deve avere il disambiguante
        if newlineNodab not in titoli:
            if re.search(regex, newline.replace('\n','')):
                titolimodificati[line.replace('\n','')] = newline.replace('\n','')
    fileIn.close()

    ''' Dizionario con titoli e n° link in entrata
    la chiave è il titolo con i caratteri speciali sostituiti
    il valore è il nç di link in entrata
    '''
    cont = 0
    maxLink = 50 # n° massimo di titoli da passare all'API linkshere
    tmpTitles = ""
    PuntanoQuiCount={}
    for entry in titolimodificati:
        tmpTitles += titolimodificati[entry] + "|"; # elenco dei titoli separati da |
        cont += 1
        if cont == maxLink or entry == list(titolimodificati.keys())[-1]:
            tmpTitles = tmpTitles[:-1] # rimuovo il | finale
            tmp = PuntanoQuiConta(tmpTitles)
            for linkcount in tmp:
                if linkcount not in PuntanoQuiCount:
                    PuntanoQuiCount[linkcount]=tmp[linkcount]

            cont = 0
            tmpTitles = ""
    
    ''' Creo lista del risultato '''
    res = ""
    PQ = "https://it.wikipedia.org/w/index.php?title=Speciale:PuntanoQui&namespace=0&target="
    for titolo in titolimodificati:
        if titolimodificati[titolo] in PuntanoQuiCount:
            if PuntanoQuiCount[titolimodificati[titolo]] > 0: # se ha almeno un link
                link="[" + PQ + DelDisambiguation(titolimodificati[titolo]).replace(' ','_') + " N° Link: " + str(PuntanoQuiCount[DelDisambiguation(titolimodificati[titolo])]) + "]"
                res += "* [[" + titolo + "]] - [[" + DelDisambiguation(titolimodificati[titolo]) + "]] - " + link + '\n'

    fileOut = open(path + "Redirect_da_grafia_senza_caratteri_speciali_da_creare.txt", "w",encoding="utf-8")
    fileOut.write(res)
    fileOut.close()
    print("== FINE ==")
main()