Utente:BrolloBot/grabber new.py

Da Wikisource.

Script python3 utilizzati per lo scaricamento delle pagine della collana Rätoromanische chrestomathie dal sito www.crestomazia.ch, parziale pre-elaborazione, allineamento con le pagine djvu e caricamento in nsPagina.

Da utilizzare interattivamente, le funzioni base sono:

  • cr1(url) : dato l'url di una pagina del sito, scarica la pagina e le successive eseguendo il parsing del pulsante next; restituisce la lista dei testi delle pagine che viene salvato manualmente;
  • aggiustaPagine(): legge il file salvato, lo suddivide in pagine, esegue alcuni aggiustamenti (compreso il riconoscimento automatico, discretamente attendibile, delle pagine tipo poem)
  • appaia(fileDjvu, filePagine, ini, fin): estrae dal djvu il testo, suddiviso per pagine; per similitudine (simil(), vediSimil()) appaia le due serie di testi e restituisce le due liste di testi e le coppie di indici;
  • caricaCoppie(coppie,pagine): esegue il caricamento sulla base delle coppie di indici ottenuto con appaia()
#!/usr/bin/python
# -*- coding: utf-8  -*-

from urllib.request import FancyURLopener
from time import sleep
import bs4
import re
import os
from time import sleep
import pywikibot as bot
listaRiscrivi=[288, 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, \
               277, 276, 275, 274, 273, 272, 271, 270, 269, 268, 267, 266, \
               265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, \
               253, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 209, \
               208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, \
               196, 195, 194]


it=bot.Site("it","wikisource")
opener=FancyURLopener({})
##class MyOpener(FancyURLopener):
##    version = 'User-Agent: Alex (+http://it.wikisource.org/wiki/Utente:Alex_brollo)'

# estrae lo strato testo in datail page, e produce la lista data dei testi 

# delle pagine (pagina 1 in data[0]);

# il file djvu deve essere scaricato nella cartella locale
def extract_djvu_text(filename):
    print("extracting text layer")
    data = []
    comando='djvutxt --detail=page "%s"  text.txt' % (filename)
    result=os.system(comando)

    print(comando, result)
    text=open("text.txt").read()

    for t in re.finditer('\((page -?\d+ -?\d+ -?\d+ -?\d+[ \n]+"(.*)"[ ]*|)\)\n', text):
        t = re.sub('^page \d+ \d+ \d+ \d+[ \n]+"', '', t)
        t = re.sub('"[ ]*$', '', t)
        t = unquote_text_from_djvu(t)
        if len(t)<150:
            t=""
        data.append(t)
    return data

def extract(filename):
    comando='djvutxt --detail=page "%s"  text.txt' % (filename)
    result=os.system(comando)

    txt=open("text.txt",encoding="utf-8").read()
    print("extracting text layer")
    r=re.compile(r"^\(page \d+ \d+ \d+ \d+[\s\S]+?\" *\)|\(\)\n*",re.MULTILINE)
    l=r.findall(txt)
    for i in range(len(l)):
        if l[i].strip()=="()":
            l[i]=""
        else:
            l[i]=l[i][l[i].find('"')+1:l[i].rfind('"')-1]
            l[i]=re.sub(r'" *\)\n*',"",l[i])
        l[i]=unquote_text_from_djvu(l[i])           
    return [""]+l
        
# legge un file con separatori separatore, lo suddivide in pagine,
# elabora pagina per pagina e lo salva
def aggiustaPagine(fileName, separatore="\n==[[]]==\n"):
    r1=re.compile(r"^(\d*[05]) ", re.MULTILINE)
    
    pagine=open(fileName, encoding="utf-8").read().split(separatore)
    print("Pagine:", len(pagine))

    for p in range(len(pagine)):
        l=[]
        ll=0
        for linea in pagine[p].split("\n"):
            l.append(len(linea))
            ll+=len(linea)
        lm=ll/len(l)
        pagine[p]=pagine[p].replace("<poem>\n","").replace("\n</poem>","")
        if lm<55:
            pagine[p]="<poem>\n"+pagine[p]+"\n</poem>"
        if "<poem>" in pagine[p]:
            pagine[p]=re.sub(r1,r"{{R|\1}}",pagine[p])
##            print(pagine[p])
##            return
        else:
            pagine[p]=re.sub(r1,r"",pagine[p])
             

    testo=separatore.join(pagine)
    open(fileName,"w",encoding="utf-8").write(testo)
    return

# legge un file con separatori separatore, lo suddivide in pagine,
# elabora pagina per pagina e lo salva
def aggiustaPagineWs(base,ini,fin):
    
    r1=re.compile(r"^(\d*[05]) ", re.MULTILINE)

    for p in range(ini,fin):
        pagina=bot.Page(it,base+str(p))
        if not pagina.exists():
            continue
        testo=pagina.get()
        header=testo[:testo.find("</noinclude>")+13]
        footer=testo[testo.rfind("<noinclude>"):]
        testo=testo.replace(header,"").replace(footer,"")
        if 'user=""' in header or 'user="BrolloBot"' in header:
            l=[]
            ll=0
            for linea in testo.split("\n"):
                l.append(len(linea))
                ll+=len(linea)
            lm=ll/len(l)
            if lm<55 and not "<poem>" in testo:
                testo="<poem>\n"+testo+"\n</poem>"
            if "<poem>" in testo:
                testo=re.sub(r1,r"{{R|\1}}",testo)
            pagina.put(header+testo+footer)

    return
    

def test(url="http://www.erasmo.it/baretti/jpg/B0001.JPG"):
    #f=MyOpener.open(url).read()
    with opener.open(url) as f:
        html=f.read().decode("utf-8")
    return html
def simil(a,b,c=10):
    punti=0
    try:
                for i in range(len(a)-c):
                        if a[i:i+c]in b:
                                punti+=1

                s1=punti*100/(len(a)-c)
                punti=0
                x=a
                a=b
                b=x
                for i in range(len(a)-c):
                        if a[i:i+c]in b:
                                punti+=1

                s2=punti*100/(len(a)-c)
                return int((s1+s2)/2)
    except:
        return -1
def vediSimil(testo,lista):
    Max=0
    for i in range(len(lista)):
        similit=simil(testo,lista[i],3)
        if similit>Max:

            Max=similit
            maxItem=(i, Max)

    return maxItem

def estraiListePagine(fileDjvu,filePagine):
    pagineDjvu=extract(fileDjvu)
    pagine=open(filePagine, encoding="utf-8").read().split("\n==[[]]==\n")
    return (pagineDjvu, pagine)

# estrae le pagine dal djvu e le associa alle pagine ch che vengono splittate
# in corrispondenza dei separatori "\n==[[]]==\n"
# filePagine viene generato da cr1()
def appaia(fileDjvu,filePagine, ini, fin):
    pagineDjvu, pagine=estraiListePagine(fileDjvu,filePagine)
    #pagineDjvu, pagine=estraiListePagine(pagineDjvu, pagine)
    coppie=[]
    matchDone=False
    s1,s2=vediSimil(pagineDjvu[ini], pagine)
    #coppie.append((i,s[0],s[1]))
    print((ini,s1,s2))
    delta=s1-ini
    for i in  range(ini,fin):
        s2=simil(pagineDjvu[i], pagine[i+delta],3)
        print(i,i+delta,s2)
        coppie.append((i,i+delta,s2))
        if s2<45:
            break
    return (coppie,pagine,pagineDjvu)

def caricaCoppie(coppie,pagine, base=None):
    if base==None:
        print("Manca base")
        return
    for c in coppie:
        p=bot.Page(it,base+str(c[0]))
        if not p.exists():
            p.put(pagine[c[1]])
            print (p.title(),"salvata")
        else:
            print(p.title(), "esiste")
    return
    
        

    
    

# elimina l'escaping dei caratteri speciali nel djvu text

def unquote_text_from_djvu(text):
    text = text.replace('\\n', '\n')
    text = text.replace('\\"', '"')
    text = text.replace('\\\\', '\\')
    text = text.replace('\\037', '\n')
    text = text.replace('\\035', '')
    text = text.replace('\\013', '')
    text = text.replace('\\01', '')
    text = text.replace('\\t', ' ')
    text = text.rstrip('\n')
    return text

# non utilizzato
def cr():
    testo=[]
    r=re.compile(r"\t+")
    for n in range(1,334):
        url=f'http://maalr2.spinfo.uni-koeln.de:4562/xmlSelected?pageNumber={n}&volume=PPN345572629_0038'
        with opener.open(url) as f:
            html=f.read().decode("utf-8")
            parsed=bs4.BeautifulSoup(html,"lxml")
            text=parsed.find("text").get_text()
            text=r.sub("\n",text)
            np=n+30
            nomePagina=f'==[[Pagina:Decurtins - Rätoromanische chrestomathie, XII.djvu/{np}]]==\n'
            testo.append(nomePagina+text)
            print(n,len(text))
            sleep(5)
    return testo

#estrattore testo pagine Crestom.
def cr1(url):
    continua=True
    lista_pagine=[]
    r=re.compile(r"\t+")
    base=url.split("/")[:-1]
    baseUrl="/".join(base) # estrazione porzione base url
    while continua:
        with opener.open(url) as f:
            testo=f.read().decode("utf-8")
        html=bs4.BeautifulSoup(testo,"lxml")
        bottoni=html.find_all("a","btn")
        nextUrl=""
        for b in bottoni:
            if b.get_text()=="next":
                nextUrl=baseUrl+b["href"].replace(" ","%20")
        if nextUrl=="":
            break
        print(url)
        url=nextUrl
        print(url)
        print()
        text=html.find("text").get_text()
        text=r.sub("\n",text)
        lista_pagine.append(text)
        sleep(5)
        
    return lista_pagine
    

def crr():
    testo=[]
    lista=['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX', 'XXI', 'XXII']
    r=re.compile(r"\t+")
    np=9
    for n in lista:
        url=f'http://maalr2.spinfo.uni-koeln.de:4562/xmlSelected?pageNumber={n}&volume=PPN345572629_0038'
        with opener.open(url) as f:
            html=f.read().decode("utf-8")
            parsed=bs4.BeautifulSoup(html,"lxml")
            text=parsed.find("text").get_text()
            text=r.sub("\n",text)
            
            nomePagina=f'==[[Pagina:Decurtins - Rätoromanische chrestomathie, XII.djvu/{np}]]==\n'
            np+=1
            testo.append(nomePagina+text)
            print(n, np,len(text))
            sleep(5)
    return testo

        
        

def go(urlBase="http://www.erasmo.it/baretti/jpg/B%s.JPG", cartella="baretti"):
    for i in range(100,121):
        nf="00"+str(i)

        f=opener.open(urlBase % (nf)).read()
        open("jpg/"+nf,"wb").write(f)
        print(nf, " salvato")

def digi(prima, ultima):
    
    n=1
    for i in range(prima,ultima):
        sleep(1)
        f=opener.open("http://www.digitami.it/risorsa.srv?imgId=%d" % (i)).read()
        if len(f)>0:
            jpg="jpg/p%s.jpg" % (str(n).zfill(3))
            open(jpg,"wb").write(f)
            
            print(n, jpg, " salvata")
            n+=1
    return
    
def IA(fileUrl,path):
    f=opener.open(fileUrl).read()
    open(path,"wb").write(f)
    print("Salvato ",path)
    return

    
def tirab(pdf):
   base="http://www.opal.unito.it/psixsite/Miscellanea%20di%20testi%20di%20genere%20diverso/Elenco%20opere/"
   f=opener.open(base+pdf).read()
   open("tirab/"+pdf,"wb").write(f)
   print("tirab/"+pdf, "salvato")
   return

def opalGrab(base, listaId,cartella):
    # base: url base senza /
    # listaId: lista degli identificatori opal
    # cartella: url cartella senza /
    f=[]
    for i in listaId:
        f.append(base+"/"+i+".pdf")
    for url in f:
        url=url.strip()
        fileContent=opener.open(url).read()
        nomePdf=url[url.rfind("/")+1:]
        print(url)
        open(cartella+"/"+nomePdf,"wb").write(fileContent)

    return
    
def find_stringa(stringa,idi,idf,dc=0,x=None,side="left"):
    if side=="right":
        idip=stringa.rfind(idi)
    else:
        idip=stringa.find(idi)
    idfp=stringa.find(idf,idip+len(idi))+len(idf)
    if idip>-1 and idfp>0:
        if x!=None:
            while stringa[idip:idfp].count(x)>stringa[idip:idfp].count(idf):
                if stringa[idip:idfp].count(x)>stringa[idip:idfp].count(idf):
                    idfp=stringa.find(idf,idfp)+len(idf)
                
        if dc==0:
            vvalore=stringa[idip+len(idi):idfp-len(idf)]
        else:
            vvalore=stringa[idip:idfp]
    else:
        vvalore=""
    return vvalore

def pagineRosse(url):
    with opener.open(url) as f:
        testo=f.read().decode("utf-8")
    html=bs4.BeautifulSoup(testo,"lxml")
    href=html.find_all("a")
    l=[]
    for pagina in href:
        try:
            if  pagina["class"][0]=="new":
                l.append(pagina)
        except:
            continue
    dati=[]
    for pagina in l:
        dati.append((pagina.get_text().strip(), find_stringa(str(pagina),".djvu/","&",0)))
    return dati