[Bash] Estrapolazione dati OPAC SBN [2a parte]

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
teomat
Prode Principiante
Messaggi: 76
Iscrizione: martedì 28 febbraio 2012, 13:33

[Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da teomat »

Buongiorno a tutt*,

ricollegandomi a questo post, anche sulla base del cosniglio di @rai, vi chiedo un aiuto per il seguente problema.
Avendo un file TXT o CSV con una lista di url che puntano ad altrettante schede dell'OPAC SBN, estrapolare da qualle pagine l'informazione su quante biblioteche possiedono il volume in questione.

Il file di origine avrebbe il seguente aspetto:

http://id.sbn.it/bid/RMS1703140
http://id.sbn.it/bid/LO10312795
...

oppure
https://opac.sbn.it/risultati-ricerca-a ... RMS1703140?
https://opac.sbn.it/risultati-ricerca-a ... LO10312795?

Vorrei come risultato un file CSV o TXT con l'idenficativo e il numero di biblioteche; una cosa del genere:

IT\ICCU\RMS\1703140, 2
IT\ICCU\LO1\0312795, 62
...


L'informazione è contenuta in questo punto delle schede OPAC, ma non riesco ad usare un sistema per esrtapolarla:
Immagine

Grazie in anticipo e a presto,
Matteo
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da crap0101 »

non è comodissimo perchè vedo che son dati generati da javascript, per cui soluzioni tipo wget o beautifulSoup (python) non funzionano.
Dovresti provare con qualcosa tipo Selenium o PhantonJs (quest'ultimo mi pare non più sviluppato ma potrebbe andar bene comunque) o direttamente in js.
*oppure* verificare che il servizio fornisca delle api o qualche altro metodo più comodo rispetto a parsare l'output testuale (e che potresti applicare anche per la prima parte del problema relativa all'altro thread).
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4444
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da UbuNuovo »

Ciao Crap, sì, sarebbe bene avere un formato non html.
Ho visto che con wget al volo, la pagina non si scarica, non ho provato le possibili opzioni.
Per il parsing ho usato i due file html di esempio duplicandone uno.

filtraggio con grep output adatto a csv

Codice: Seleziona tutto

while read f;do grep -Po '>\K.+\\.+\\.+\\\d+(?=<)' "$f";done < <(find . -type f -name '*.html')| uniq -c | awk '{print $2","$1}'

Codice: Seleziona tutto

8-) while read f;do grep -Po '>\K.+\\.+\\.+\\\d+(?=<)' "$f";done < <(find . -type f -name '*.html')| uniq -c | awk '{print $2","$1}'
IT\ICCU\RMS\1703140,2
IT\ICCU\LO1\0312795,1
un modo con filtraggio awk

Codice: Seleziona tutto

awk -F'<div[^>]+>|</div>' '/^\s+<div.*>.+\\.+\\.+\\[0-9]+<\/div>$/ {print $2}' $(find . -type f -name '*.html')| uniq -c | awk '{print $2","$1}'

Codice: Seleziona tutto

8-) awk -F'<div[^>]+>|</div>' '/^\s+<div.*>.+\\.+\\.+\\[0-9]+<\/div>$/ {print $2}' $(find . -type f -name '*.html')| uniq -c | awk '{print $2","$1}'
IT\ICCU\RMS\1703140,2
IT\ICCU\LO1\0312795,1
8-) 
se tutti i codici iniziano con 'IT\ICCU' sarebbe bene inserirli nelle regex

Sarebbe meglio fare uno script awk, ma con il codice sono un po' arrugginito, dovrei studiarci un po' :D
ma in questo periodo :nono:
Salva l'Ucraina! 🇺🇦
teomat
Prode Principiante
Messaggi: 76
Iscrizione: martedì 28 febbraio 2012, 13:33

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da teomat »

Grazie per i tentativi e i suggerimenti.
Forse si potrebbe aggirare il problema nel seguente modo.
Data questa scheda

http://id.sbn.it/bid/LO10312795 (o questa https://opac.sbn.it/risultati-ricerca-a ... LO10312795?),

l'url https://opac.sbn.it/risultati-ricerca-a ... LO10312795?

contiente le informazioni della scheda appunto in formato UNIMARC; nello specifico i tag 899 rappresentano le informazioni sulle biblioteche che possiedono il libro, quindi basterebbe far contare ai comondi quanti 899 ci sono in ciascuna pagina UNIMARC e produrre il risultato in un TXT/CSV.
Ho provato con

Codice: Seleziona tutto

curl --silent https://opac.sbn.it/risultati-ricerca-avanzata/-/opac-adv/unimarc/LO10312795? | grep -c -i 899
ma la risposta è 0.

Grazie ancora in anticipo
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da crap0101 »

teomat ha scritto:
giovedì 29 febbraio 2024, 8:28

Ho provato con

Codice: Seleziona tutto

curl --silent https://opac.sbn.it/risultati-ricerca-avanzata/-/opac-adv/unimarc/LO10312795? | grep -c -i 899
ma la risposta è 0.

Grazie ancora in anticipo
eh certo.... come dicevo: quelli sono dati generati *dinamicamente*, se curli o wgetti l'url, vedrai un qualche tag <script> che punta al codice che verrà eseguito, al più potrebbe esserci del js direttamente nel sorgente, ma non ti cambia molto. Quello che serve a te è qualcosa che faccia quello che fa firefox, chrome o qualsiasi altro web browser che utilizzi, cioè interpretare tutta quella robaccia :D e presentare a chi sta davanti allo schermo un risultato sensato.

Codice: Seleziona tutto

crap0101@orange:/tmp/foo$ cat s.py
from selenium import webdriver

url = 'https://opac.sbn.it/risultati-ricerca-avanzata/-/opac-adv/unimarc/LO10312795'

ch = webdriver.ChromeOptions()
ch.headless = True
browser = webdriver.Chrome(options=ch)
browser.get(url)
print(browser.page_source)
browser.close()
crap0101@orange:/tmp/foo$ python s.py | grep 899
              <p></p><li>LEADER 03382nam0 22010573i 4500</li><li>001 IT\ICCU\LO1\0312795</li><li>003 http://id.sbn.it/bid/LO10312795</li><li>005 20171108115433.9</li><li>020   $aIT$b691350</li><li>100   $a19930920d1969    ||||0itac50      ba</li><li>101   $aita</li><li>102   $aIT</li><li>181  1$6z01$ai $bxxxe  </li><li>182  1$6z01$an</li><li>183  1$6z01$anc$2RDAcarrier</li><li>200 1 $aIndagini di storia della filosofia$eda Leibniz a Moore$fAdriano Bausola</li><li>210   $aMilano$cVita e pensiero$dstampa 1969</li><li>215   $a327 p.$d21 cm.</li><li>606   $aNeopositivismo$2FI $3IT\ICCU\CFIC\012119</li><li>606   $aFilosofia$xStoria$xSec. 18.-20.$2FI $3IT\ICCU\SBLC\003618</li><li>676   $a190$cFILOSOFIA MODERNA$v16</li><li>676   $a190$cFILOSOFIA MODERNA$v17</li><li>699   $aEmpirismo logico$yNeopositivismo</li><li>699   $aEmpirismo logico$zNeopositivismo</li><li>699   $aPensiero filosofico$yFilosofia</li><li>699   $aConcezione filosofica$zFilosofia</li><li>699   $aPensiero filosofico$zFilosofia</li><li>700  1$aBausola$b, Adriano$3IT\ICCU\CFIV\005627$4070</li><li>801  3$aIT$bICCU$c20240226</li><li>899   $1AP0014$2PBE 21$fP$eN</li><li>899   $1AR0042$2ARE SS$fP$eN</li><li>899   $1BA0017$2BA1 21$fP/G$qN</li><li>899   $1BA0018$2BA1 BA$fP/G</li><li>899   $1BA0127$2PBE 97$fP$eN</li><li>899   $1BA0354$2PBE 42$fP$eN</li><li>899   $1BG0026$2LO1 02$fP/G$eN</li><li>899   $1BN0015$2NAP PB$fP/G$eN</li><li>899   $1BN0098$2NAP CU$fP/G</li><li>899   $1BO0304$2UBO GA$fP/G$eN</li><li>899   $1BO0345$2PBE F2$fP$eN</li><li>899   $1BO0445$2UBO FI$fP/G</li><li>899   $1BO0461$2UBO PI$fP/G</li><li>899   $1BR0056$2PUG PW$fP/G</li><li>899   $1BS0031$2PBE O0$fP$eN</li><li>899   $1CB0098$2MOL BU$fP/G</li><li>899   $1CH0029$2UDA EP$fP/G</li><li>899   $1CO0213$2PBE 18$fP$eN</li><li>899   $1CS0080$2CSA PS$fP/G$qN</li><li>899   $1FI0098$2CFI CF$fP/G$eN</li><li>899   $1FI0213$2SBT MG$fP$eN</li><li>899   $1FI0597$2SBT KE$fP$eN</li><li>899   $1GE0038$2LIG 01$fP/G$qN</li><li>899   $1LU0022$2LUA BL$fP/G</li><li>899   $1MC0168$2UMC DF$fP/G</li><li>899   $1MI0185$2MIL NB$fP/G$eN</li><li>899   $1MI1261$2USM N5$fP/G$eN</li><li>899   $1MI1992$2PCM 01$fP/G$eN</li><li>899   $1MO0089$2MOD BE$fP/G$eN</li><li>899   $1NA0075$2NAP GE$fP/G</li><li>899   $1NA0267$2CAM BD$fP/G$qN</li><li>899   $1NA0666$2NAP GV$fP/G$eN$qN</li><li>899   $1PD0077$2PUV 48$fP/G</li><li>899   $1PD0090$2PUV 55$fP/G</li><li>899   $1PD0258$2PUV 25$fP/G$eN</li><li>899   $1PD0280$2PUV 32$fP/G$eN</li><li>899   $1PE0062$2UDA PE$fP/G</li><li>899   $1PG0438$2UM1 86$fP/G</li><li>899   $1PI0112$2PIS R1$fP/G</li><li>899   $1PR0028$2PAR 01$fP/G</li><li>899   $1PR0072$2PAR PA$fP/G</li><li>899   $1PR0171$2PAR LL$fP/G</li><li>899   $1PV0079$2PAV C2$fP/G</li><li>899   $1PV0291$2MIL UP$fP/G$eN$qN</li><li>899   $1RA0017$2RAV SC$fP/G</li><li>899   $1RM0267$2BVE CR$fP/G$eN</li><li>899   $1RM0289$2RML 04$fP/G$eN</li><li>899   $1RM0989$2RMS 2L$fP/G$eN</li><li>899   $1RM1189$2IEI SP$fP/G$eN</li><li>899   $1RM1399$2PBE D6$fP$eN</li><li>899   $1RN0044$2PBE 30$fP$eN</li><li>899   $1RO0042$2ROV SV$fP/G</li><li>899   $1SV0003$2LIG 79$fP/G$qN</li><li>899   $1TO0240$2BCT 01$fP/G</li><li>899   $1TO0324$2UTO 17$fP/G</li><li>899   $1TO0326$2UTO 97$fP/G$eN</li><li>899   $1TO0646$2UTO B7$fP/G</li><li>899   $1TS0162$2TSA DV$fP/G</li><li>899   $1TS0216$2TSA DI$fP/G</li><li>899   $1TS0276$2TSA SG$fP/G</li><li>899   $1TV0113$2VIA TS$fP/G</li><li>899   $1VI0095$2VIA AP$fP/G</li><p></p>
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
rai
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2848
Iscrizione: domenica 11 maggio 2008, 18:03
Desktop: plasma
Distribuzione: 22.04
Località: Palermo

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da rai »

crap0101 ha scritto:
mercoledì 28 febbraio 2024, 22:46
non è comodissimo perchè vedo che son dati generati da javascript
eh già, ma ci deve essere dell'altro perché sia lo script con selenium sia il seguente che fa uso delle librerie Qt5 danno solo randomicamente l'output desiderato (cioè l'html popolato dalla esecuzione di Javascript): per lo più _a me_ viene fuori l'html "vuoto".

Codice: Seleziona tutto

import sys
from PyQt5.QtCore import  QUrl, QEventLoop
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView

url = 'https://opac.sbn.it/risultati-ricerca-avanzata/-/opac-adv/detail/RMS1703140?'

def callback_print(html):
    print(html)
    while html is None:
        app.processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
    app.quit()

def on_load_finished():
    web.page().runJavaScript("document.documentElement.outerHTML", callback_print)

app = QApplication(sys.argv)
web = QWebEngineView()
web.load(QUrl(url))
web.loadFinished.connect(on_load_finished)

sys.exit(app.exec_())
Se lo script funziona con quella url, dall'output si deve potere greppare la parola Gramsci
Sono consapevole del fatto che i comandi nelle app Qt sono eseguiti in modo asincrono ma la funzione callback_print() dovrebbe eseguita solo dopo che runJavaScript() ha terminato (e infatti a volte funziona)
Spiegazioni?
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4444
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da UbuNuovo »

Ho provato ad usare il client yaz per accedere all'opac sbn via z39.50
funzionare funziona, non ho approfondito molto, non mi intendo di catalogazione di libri, forse per te è tutto più chiaro.
Non ho trovato molta documentazione per l'utilizzo pratico.
Ti passo gli appunti delle mie prove, non so di preciso cosa devi fare, se ti pare un metodo utilizzabile poi si può fare il parsing e/o creare il file dei comandi dinamicamente.

Codice: Seleziona tutto

dopo aver installato yaz dai repo di ubuntu

alla pagina:
https://opac.sbn.it/web/opacsbn/accesso-z39.50-a-opac-sbn 
vedere i dati per impostare la connessione al databae di OPAC SBN che sono:

Indirizzo web: opac.sbn.it
Porta: 2100 e 3950
Database: nopac
Sintassi record: UNIMARC, MARC21 o SUTRS
Set di attributi (profilo): BIB1 (parte)
Set di caratteri: UTF-8

scaricare gli attributi, utilizzati da OPAC SBN per le query, da:
https://opac.sbn.it/documents/20122/73988/Attributi_Bib1_ed_estensioni_del_profilo_SBN.pdf/3a4a7d77-cd15-9407-d6b4-7127395af169?t=1611590449322&download=true

per capire meglio come usare gli attributi BIB1 vedere:
https://www.loc.gov/z3950/agency/BIB1.html

in pratica ogni attributo va numerato in base al tipo di attributo, 
    Use attributes          (type = 1)
    Relation attributes     (type = 2)
    Position attributes     (type = 3)
    Structure attributes    (type = 4)
    Truncation attributes   (type = 5)
    Completeness attributes (type = 6)

seguito da = e dal codice BIB1 e poi dal valore (se è previsto), tipo:

find @ago 1=cod_BIB1 [valore] 2=cod_BIB1 [valore] 3=cod_BIB1 [valore] ...

l'unica documentazione, con esempi concreti, che ho trovato:
https://federicolevaeu.wordpress.com/2016/10/21/scarico-schede-sbn-via-z39-50-con-yaz-client/

INTERATTIVAMENTE COMANDI DA ESEGUIRE:

yaz-client opac.sbn.it:2100/nopac
# dopo il prompt Z> inserire:
format unimarc
charset utf8
elements f

# controllare le impostazioni con
list_all 
# se va bene fare la query
find @attr 1=1032 ITICCUUM1E006894
# ottengo:
Sent searchRequest.
Received SearchResponse.
Search was a success.
Number of hits: 1, setno 1
records returned: 0
Elapsed: 0.181610

# per vedere i dati:
show
# ottengo:
Sent presentRequest (1+1).
Records: 1
[nopac]Record type: Unimarc
03557nam2 22004933i 4500
001 IT\ICCU\UM1E\006894
003 http://id.sbn.it/bid/UM1E006894
005 20170413095927.6
012    $a i-am S..a orto olDo (3) 1607 (R) $2 fei $9 Vol.2
100    $a 20020225d1607    ||||0itac50      ba
101    $a lat
102    $a IT
181  1 $6 z01 $a i  $b xxxe  
182  1 $6 z01 $a n
183  1 $6 z01 $a nc $2 RDAcarrier
200 1  $a [2]: 	Continuatio ephemeridum coelestium motuum Io. Antonij Magini Patauini ... Ab anno Domini 1610. vsque ad annum 1630. iuxta Copernici obseruationes accuratissimè supputatarum ... Quibus addita sunt eiusdem supplementum isagogicarum ephemeridum, ... Astrologicae circa agricolturam, & nauigatoriam obseruationes, & praecepta. De mutatione aëris libellus
210    $a Venetijs $c apud hæredem Damiani Zenarij $d 1607 $e Venetijs $g ex officina haeredis Damiani Zenarij $h 1606 mense Martij
215    $a [6], 28, 149, [3] carte $c ill. $d 4º
300    $a Fascicolo a identico a quello del vol. 3 con frontespizio non ricomposto, ma con data 1610 al posto di 1620
300    $a Marche sul frontespizio (O856) e nel colophon (O608)
300    $a Segnatura: a⁴ b² A-G⁴, ²A-T⁸(T7,8 bianche).
327    $a Contiene le efemeridi dal 1611 al 1620; le 28 c. contengono il "Supplementum isagogicarum ephemeridum" e "De mutatione aeris"
461  1 $1 001IT\ICCU\UM1E\006886 $1 2001  $a Ephemerides coelestium motuum Io. Antonij Magini Patauini, ab anno Domini 1608. vsque ad annum 1630. secundum Copernici obseruationes accuratissimè supputatae, correctae, & auctae, ad longitudinem inclytae Venetiarum vrbis. Eiusdem tractatus duo absolutissimi, nempe Isagoge in astrologiam, & De vsu ephemeridum denuo correcti, & insigniter aucti. Atque etiam directionum eiusdem auctoris pro directionibus noua ratione, ac facili secundum rationalem modum conficiendis ... $v 2 $1 700 1 $a Magini $b , Giovanni Antonio $f  <1555-1617> $3 IT\ICCU\MILV\069558 $4 070 $1 71202 $a Zenaro, Damiano erede $3 IT\ICCU\MILV\163239 $4 650
700  1 $a Magini $b , Giovanni Antonio $f  <1555-1617> $3 IT\ICCU\MILV\069558 $4 070
712 02 $a Zenaro, Damiano erede $3 IT\ICCU\MILV\163239 $4 650
790  1 $a Bonhombra $b , Lodovico $3 IT\ICCU\BVEV\092908 $z Magini, Giovanni Antonio <1555-1617>
791 02 $a Rodella, Bartolomeo $3 IT\ICCU\RMGV\010777 $z Zenaro, Damiano erede
801  3 $a IT $b ICCU $c 20240226
899    $1 AR0070 $2 ARE BA $f P $e N
899    $1 FR0084 $2 RML 25 $f P/G $4 1 esemplare $e N
899    $1 LE0131 $2 PUG LW $f P/G $4 v. [2], 1 es. $e N $q N
899    $1 MO0089 $2 MOD BE $f P/G $4 1 esemplare $e N $q N
899    $1 MT0024 $2 PBE 26 $f P $e N
899    $1 NA0079 $2 NAP BN $f P/G $4 1 esemplare  $e N $q N
899    $1 PG0040 $2 UM1 39 $f P/G $e N
899    $1 PG0109 $2 UM1 01 $f P/G
899  1 $1 RM0267 $2 BVE CR $f P/G $4 Vol. 2 : 2 esemplari di cui 1 Var.B mutila. $e S $q S $t 1 $u http://books.google.com/books?vid=IBNR:CR001091845 | http://books.google.com/books?vid=IBNR:CR000695585
899    $1 RM0280 $2 RML 01 $f P/G
899    $1 TO0324 $2 UTO 17 $f P/G
899    $1 VE0099 $2 VEA VE $f P/G $4 v. 2, 1 esemplare
921    $a IT\ICCU\PUV\M000294 $b Una salamandra coronata in mezzo alle fiamme. In una cornice figurata. Motto: Virtuti sic cedit invidia. $c O856 $d Sul front. $f VIRTUTISIC $f SALAMANDRA $f FIAMME $f CORONA
921    $a IT\ICCU\PUV\M000619 $b Una salamandra coronata in mezzo alle fiamme. In una cornice figurata. Motto: Virtuti sic cedit invidia. $c O608 $d A c. 2T6v. $f VIRTUTISIC $f SALAMANDRA $f FIAMME $f CORONA
999    $1 cnc 00 $2 CNC 00 $3 MILV069558 $9 CNCA007049
999    $1 cnm 00 $2 CNM 00 $3 MILV069558 $9 CNMN\0000038000

nextResultSetPosition = 2
Elapsed: 0.206778

c'è l'indirizzo
003 http://id.sbn.it/bid/UM1E006894
che ti reindirizza al sito https://opac.sbn.it (alla pagina con i risultati della ricerca in base a UM1E006894) :
https://opac.sbn.it/risultati-ricerca-avanzata/-/opac-adv/detail/UM1E006894?

poi vedo molte righe '899' che spero siano i dati voluti.

-------
CON COMANDI SU FILE E OUTPUT SU FILE:

comandi da inserire nel file "in.txt":

open tcp:opac.sbn.it:2100/nopac
format unimarc
charset utf8
elements f
f @attr 1=1032 ITICCUANAE010355
show
f @attr 1=1032 ITICCUANAE013892
show
# prova commento e poi esco con quit
quit

eseguire:
yaz-client -f in.txt -m out.unimarc -a - | tee info.log

il file "info.log" contiene i dati in testo semplice; out.unimarc in formato unimarc
Salva l'Ucraina! 🇺🇦
Avatar utente
Actarus5
Prode Principiante
Messaggi: 220
Iscrizione: mercoledì 3 luglio 2013, 17:15
Desktop: Mate
Distribuzione: Fedora
Località: Abutalabashuneba

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da Actarus5 »

Ho provato a fare un tentativo con Python e Selenium, non ho avuto modo di testarlo per bene ma coi due esempi nel post iniziale funziona, ho inserito dei commenti per spiegare un po' il perché di certe scelte, purtroppo con lo scraping si è vincolati alla struttura del sito e quindi la logica non sempre è chiarissima:

Codice: Seleziona tutto

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Constants
AGENT = 'your user agent'
CHROMEDRIVER_PATH = 'path to chromedriver'
ATTR_VALUE = By.CLASS_NAME, 'table-text'
ATTR_TEXT_ITEM = By.CLASS_NAME, 'table-text-item'

def initialize_driver():
    # Start the selenium driver
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument(f'--user-agent={AGENT}')
    chrome_options.add_argument('--log-level=3')

    service = Service(CHROMEDRIVER_PATH)
    driver = webdriver.Chrome(service=service, options=chrome_options)
    
    return driver

def get_id_code(url, driver):
    driver.get(url)

    wait = WebDriverWait(driver, 10)
    attr_list = wait.until(EC.presence_of_all_elements_located((ATTR_VALUE)))
    
    # L'ultimo elemento della lista degli attributi 
    # è il codice identificativo del libro

    return attr_list[-1].text

def get_lib_num(url, driver, id_code):
    driver.get(url)

    # Col tag ATTR_TEXT_ITEM ritrovo tutti gli attributi del libro e l'elenco delle biblioteche
    # Rimuovo eventuali stringhe vuote e spazi etc

    wait = WebDriverWait(driver, 10)
    lib_list = [item.text.strip() for item 
                in wait.until(EC.presence_of_all_elements_located(ATTR_TEXT_ITEM)) if item.text.strip()]

    # Siccome la lista segue l'ordine che c'è nella pagina uso il codice identificativo
    # per capire quando ho raggiunto l'elenco delle biblioteche
    try:
        index = lib_list.index(id_code)
        return len(lib_list[index + 1:])
    except ValueError:
        raise(f'{id_code} not found in the list.')


def main():
    url_list = ['http://id.sbn.it/bid/RMS1703140', 'http://id.sbn.it/bid/LO10312795']

    with initialize_driver() as driver:
        for url in url_list:
            id_code = get_id_code(url, driver)
            lib_num = get_lib_num(url, driver, id_code)
            print(f'{id_code}, {lib_num}')
        
if __name__ == '__main__':
    main()
"An extremely helpful console message: “SPANK! SPANK! SPANK! Naughty programmer!”. Really, I’m not joking about that one."
teomat
Prode Principiante
Messaggi: 76
Iscrizione: martedì 28 febbraio 2012, 13:33

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da teomat »

UbuNuovo ha scritto:
giovedì 29 febbraio 2024, 19:28
Ho provato ad usare il client yaz per accedere all'opac sbn via z39.50
funzionare funziona, non ho approfondito molto, non mi intendo di catalogazione di libri, forse per te è tutto più chiaro.
Non ho trovato molta documentazione per l'utilizzo pratico.
Ti passo gli appunti delle mie prove, non so di preciso cosa devi fare, se ti pare un metodo utilizzabile poi si può fare il parsing e/o creare il file dei comandi dinamicamente.

Codice: Seleziona tutto

dopo aver installato yaz dai repo di ubuntu

alla pagina:
https://opac.sbn.it/web/opacsbn/accesso-z39.50-a-opac-sbn 
vedere i dati per impostare la connessione al databae di OPAC SBN che sono:

Indirizzo web: opac.sbn.it
Porta: 2100 e 3950
Database: nopac
Sintassi record: UNIMARC, MARC21 o SUTRS
Set di attributi (profilo): BIB1 (parte)
Set di caratteri: UTF-8

scaricare gli attributi, utilizzati da OPAC SBN per le query, da:
https://opac.sbn.it/documents/20122/73988/Attributi_Bib1_ed_estensioni_del_profilo_SBN.pdf/3a4a7d77-cd15-9407-d6b4-7127395af169?t=1611590449322&download=true

per capire meglio come usare gli attributi BIB1 vedere:
https://www.loc.gov/z3950/agency/BIB1.html

in pratica ogni attributo va numerato in base al tipo di attributo, 
    Use attributes          (type = 1)
    Relation attributes     (type = 2)
    Position attributes     (type = 3)
    Structure attributes    (type = 4)
    Truncation attributes   (type = 5)
    Completeness attributes (type = 6)

seguito da = e dal codice BIB1 e poi dal valore (se è previsto), tipo:

find @ago 1=cod_BIB1 [valore] 2=cod_BIB1 [valore] 3=cod_BIB1 [valore] ...

l'unica documentazione, con esempi concreti, che ho trovato:
https://federicolevaeu.wordpress.com/2016/10/21/scarico-schede-sbn-via-z39-50-con-yaz-client/

INTERATTIVAMENTE COMANDI DA ESEGUIRE:

yaz-client opac.sbn.it:2100/nopac
# dopo il prompt Z> inserire:
format unimarc
charset utf8
elements f

# controllare le impostazioni con
list_all 
# se va bene fare la query
find @attr 1=1032 ITICCUUM1E006894
# ottengo:
Sent searchRequest.
Received SearchResponse.
Search was a success.
Number of hits: 1, setno 1
records returned: 0
Elapsed: 0.181610

# per vedere i dati:
show
# ottengo:
Sent presentRequest (1+1).
Records: 1
[nopac]Record type: Unimarc
03557nam2 22004933i 4500
001 IT\ICCU\UM1E\006894
003 http://id.sbn.it/bid/UM1E006894
005 20170413095927.6
012    $a i-am S..a orto olDo (3) 1607 (R) $2 fei $9 Vol.2
100    $a 20020225d1607    ||||0itac50      ba
101    $a lat
102    $a IT
181  1 $6 z01 $a i  $b xxxe  
182  1 $6 z01 $a n
183  1 $6 z01 $a nc $2 RDAcarrier
200 1  $a [2]: 	Continuatio ephemeridum coelestium motuum Io. Antonij Magini Patauini ... Ab anno Domini 1610. vsque ad annum 1630. iuxta Copernici obseruationes accuratissimè supputatarum ... Quibus addita sunt eiusdem supplementum isagogicarum ephemeridum, ... Astrologicae circa agricolturam, & nauigatoriam obseruationes, & praecepta. De mutatione aëris libellus
210    $a Venetijs $c apud hæredem Damiani Zenarij $d 1607 $e Venetijs $g ex officina haeredis Damiani Zenarij $h 1606 mense Martij
215    $a [6], 28, 149, [3] carte $c ill. $d 4º
300    $a Fascicolo a identico a quello del vol. 3 con frontespizio non ricomposto, ma con data 1610 al posto di 1620
300    $a Marche sul frontespizio (O856) e nel colophon (O608)
300    $a Segnatura: a⁴ b² A-G⁴, ²A-T⁸(T7,8 bianche).
327    $a Contiene le efemeridi dal 1611 al 1620; le 28 c. contengono il "Supplementum isagogicarum ephemeridum" e "De mutatione aeris"
461  1 $1 001IT\ICCU\UM1E\006886 $1 2001  $a Ephemerides coelestium motuum Io. Antonij Magini Patauini, ab anno Domini 1608. vsque ad annum 1630. secundum Copernici obseruationes accuratissimè supputatae, correctae, & auctae, ad longitudinem inclytae Venetiarum vrbis. Eiusdem tractatus duo absolutissimi, nempe Isagoge in astrologiam, & De vsu ephemeridum denuo correcti, & insigniter aucti. Atque etiam directionum eiusdem auctoris pro directionibus noua ratione, ac facili secundum rationalem modum conficiendis ... $v 2 $1 700 1 $a Magini $b , Giovanni Antonio $f  <1555-1617> $3 IT\ICCU\MILV\069558 $4 070 $1 71202 $a Zenaro, Damiano erede $3 IT\ICCU\MILV\163239 $4 650
700  1 $a Magini $b , Giovanni Antonio $f  <1555-1617> $3 IT\ICCU\MILV\069558 $4 070
712 02 $a Zenaro, Damiano erede $3 IT\ICCU\MILV\163239 $4 650
790  1 $a Bonhombra $b , Lodovico $3 IT\ICCU\BVEV\092908 $z Magini, Giovanni Antonio <1555-1617>
791 02 $a Rodella, Bartolomeo $3 IT\ICCU\RMGV\010777 $z Zenaro, Damiano erede
801  3 $a IT $b ICCU $c 20240226
899    $1 AR0070 $2 ARE BA $f P $e N
899    $1 FR0084 $2 RML 25 $f P/G $4 1 esemplare $e N
899    $1 LE0131 $2 PUG LW $f P/G $4 v. [2], 1 es. $e N $q N
899    $1 MO0089 $2 MOD BE $f P/G $4 1 esemplare $e N $q N
899    $1 MT0024 $2 PBE 26 $f P $e N
899    $1 NA0079 $2 NAP BN $f P/G $4 1 esemplare  $e N $q N
899    $1 PG0040 $2 UM1 39 $f P/G $e N
899    $1 PG0109 $2 UM1 01 $f P/G
899  1 $1 RM0267 $2 BVE CR $f P/G $4 Vol. 2 : 2 esemplari di cui 1 Var.B mutila. $e S $q S $t 1 $u http://books.google.com/books?vid=IBNR:CR001091845 | http://books.google.com/books?vid=IBNR:CR000695585
899    $1 RM0280 $2 RML 01 $f P/G
899    $1 TO0324 $2 UTO 17 $f P/G
899    $1 VE0099 $2 VEA VE $f P/G $4 v. 2, 1 esemplare
921    $a IT\ICCU\PUV\M000294 $b Una salamandra coronata in mezzo alle fiamme. In una cornice figurata. Motto: Virtuti sic cedit invidia. $c O856 $d Sul front. $f VIRTUTISIC $f SALAMANDRA $f FIAMME $f CORONA
921    $a IT\ICCU\PUV\M000619 $b Una salamandra coronata in mezzo alle fiamme. In una cornice figurata. Motto: Virtuti sic cedit invidia. $c O608 $d A c. 2T6v. $f VIRTUTISIC $f SALAMANDRA $f FIAMME $f CORONA
999    $1 cnc 00 $2 CNC 00 $3 MILV069558 $9 CNCA007049
999    $1 cnm 00 $2 CNM 00 $3 MILV069558 $9 CNMN\0000038000

nextResultSetPosition = 2
Elapsed: 0.206778

c'è l'indirizzo
003 http://id.sbn.it/bid/UM1E006894
che ti reindirizza al sito https://opac.sbn.it (alla pagina con i risultati della ricerca in base a UM1E006894) :
https://opac.sbn.it/risultati-ricerca-avanzata/-/opac-adv/detail/UM1E006894?

poi vedo molte righe '899' che spero siano i dati voluti.

-------
CON COMANDI SU FILE E OUTPUT SU FILE:

comandi da inserire nel file "in.txt":

open tcp:opac.sbn.it:2100/nopac
format unimarc
charset utf8
elements f
f @attr 1=1032 ITICCUANAE010355
show
f @attr 1=1032 ITICCUANAE013892
show
# prova commento e poi esco con quit
quit

eseguire:
yaz-client -f in.txt -m out.unimarc -a - | tee info.log

il file "info.log" contiene i dati in testo semplice; out.unimarc in formato unimarc
Grazie mille davvero. Lunedì farò dei tentativi usando il client yaz e cerco di venirne a capo: però la strada mi sembra molto promettente

A presto,
Matteo
teomat
Prode Principiante
Messaggi: 76
Iscrizione: martedì 28 febbraio 2012, 13:33

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da teomat »

Actarus5 ha scritto:
venerdì 1 marzo 2024, 5:03
Ho provato a fare un tentativo con Python e Selenium, non ho avuto modo di testarlo per bene ma coi due esempi nel post iniziale funziona, ho inserito dei commenti per spiegare un po' il perché di certe scelte, purtroppo con lo scraping si è vincolati alla struttura del sito e quindi la logica non sempre è chiarissima:

Codice: Seleziona tutto

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Constants
AGENT = 'your user agent'
CHROMEDRIVER_PATH = 'path to chromedriver'
ATTR_VALUE = By.CLASS_NAME, 'table-text'
ATTR_TEXT_ITEM = By.CLASS_NAME, 'table-text-item'

def initialize_driver():
    # Start the selenium driver
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument(f'--user-agent={AGENT}')
    chrome_options.add_argument('--log-level=3')

    service = Service(CHROMEDRIVER_PATH)
    driver = webdriver.Chrome(service=service, options=chrome_options)
    
    return driver

def get_id_code(url, driver):
    driver.get(url)

    wait = WebDriverWait(driver, 10)
    attr_list = wait.until(EC.presence_of_all_elements_located((ATTR_VALUE)))
    
    # L'ultimo elemento della lista degli attributi 
    # è il codice identificativo del libro

    return attr_list[-1].text

def get_lib_num(url, driver, id_code):
    driver.get(url)

    # Col tag ATTR_TEXT_ITEM ritrovo tutti gli attributi del libro e l'elenco delle biblioteche
    # Rimuovo eventuali stringhe vuote e spazi etc

    wait = WebDriverWait(driver, 10)
    lib_list = [item.text.strip() for item 
                in wait.until(EC.presence_of_all_elements_located(ATTR_TEXT_ITEM)) if item.text.strip()]

    # Siccome la lista segue l'ordine che c'è nella pagina uso il codice identificativo
    # per capire quando ho raggiunto l'elenco delle biblioteche
    try:
        index = lib_list.index(id_code)
        return len(lib_list[index + 1:])
    except ValueError:
        raise(f'{id_code} not found in the list.')


def main():
    url_list = ['http://id.sbn.it/bid/RMS1703140', 'http://id.sbn.it/bid/LO10312795']

    with initialize_driver() as driver:
        for url in url_list:
            id_code = get_id_code(url, driver)
            lib_num = get_lib_num(url, driver, id_code)
            print(f'{id_code}, {lib_num}')
        
if __name__ == '__main__':
    main()
Grazie anche per questa prova: python è al momento un po' fuori dalla mia portata, ma testerò anche questa via.

Grazie davvero,
Matteo
Avatar utente
Actarus5
Prode Principiante
Messaggi: 220
Iscrizione: mercoledì 3 luglio 2013, 17:15
Desktop: Mate
Distribuzione: Fedora
Località: Abutalabashuneba

Re: [Bash] Estrapolazione dati OPAC SBN [2a parte]

Messaggio da Actarus5 »

Figurati, se vuoi fare una prova con un file vero di input, puoi usare questo. Il file 'url_list.txt' deve stare nella stessa directory dello script e si aspetta degli url così:

Codice: Seleziona tutto

http://id.sbn.it/bid/RMS1703140
http://id.sbn.it/bid/LO10312795
Il file 'results.txt' viene aperto sempre nella stessa directory dello script. Nella variabile CHROMEDRIVER_PATH devi mettere il path a chromedriver, si possono scaricare da qui, ovviamente va unzippato: https://googlechromelabs.github.io/chrome-for-testing/

Nel mio caso è questo, sono su Windows:

Codice: Seleziona tutto

CHROMEDRIVER_PATH = r'C:\Users\User\Downloads\chromedriver-win64\chromedriver.exe'

Codice: Seleziona tutto

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Constants
AGENT = 'Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.43'
CHROMEDRIVER_PATH = 'your path to chromedriver'
ATTR_VALUE = By.CLASS_NAME, 'table-text'
ATTR_TEXT_ITEM = By.CLASS_NAME, 'table-text-item'

def initialize_driver():
    # Start the selenium driver
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument(f'--user-agent={AGENT}')
    chrome_options.add_argument('--log-level=3')

    service = Service(CHROMEDRIVER_PATH)
    driver = webdriver.Chrome(service=service, options=chrome_options)
    
    return driver

def get_id_code(url, driver):
    driver.get(url)

    wait = WebDriverWait(driver, 10)
    attr_list = wait.until(EC.presence_of_all_elements_located((ATTR_VALUE)))
    
    # L'ultimo elemento della lista degli attributi 
    # è il codice identificativo del libro

    return attr_list[-1].text

def get_lib_num(url, driver, id_code):
    driver.get(url)

    # Col tag ATTR_TEXT_ITEM ritrovo tutti gli attributi del libro e l'elenco delle biblioteche
    # Rimuovo eventuali stringhe vuote e spazi etc

    wait = WebDriverWait(driver, 10)
    lib_list = [item.text for item 
                in wait.until(EC.presence_of_all_elements_located(ATTR_TEXT_ITEM)) if item.text.strip()]

    # Siccome la lista segue l'ordine che c'è nella pagina uso il codice identificativo
    # per capire quando ho raggiunto l'elenco delle biblioteche
    try:
        index = lib_list.index(id_code)
        return len(lib_list[index + 1:])
    except ValueError:
        raise(f'{id_code} not found in the list.')


def main():
    # Read the list of URLs from a file
    with open('url_list.txt', 'r') as file:
        url_list = [line.strip() for line in file.readlines()]

    with initialize_driver() as driver:
        with open('results.txt', 'w') as results_file:
            for url in url_list:
                id_code = get_id_code(url, driver)
                lib_num = get_lib_num(url, driver, id_code)
                
                results_file.write(f'{id_code}, {lib_num}\n')
        
if __name__ == '__main__':
    main()
"An extremely helpful console message: “SPANK! SPANK! SPANK! Naughty programmer!”. Really, I’m not joking about that one."
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: nik1404 e 13 ospiti