
Wprowadzenie
Od 2014 roku Polska Akademia Umiejętności digitalizuje swoje zbiory oraz umieszcza je w witrynie PAUart. Szczególne miejsce w zbiorach PAU zajmuje Gabinet Rycin. To licząca prawie 100 tys. obiektów kolekcja dawnych grafik, z której część dostępna jest online. Wśród udostępnionych skanów znajdują się cyfrowe wizerunki drzeworytów, miedziorytów i akwafort Albrechta Dürera. Obiekty te publikowane są jako domena publiczna, co oznacza, że możemy swobodnie wykorzystywać je do własnych celów.
W tej lekcji w praktyce skorzystamy ze statusu domeny publicznej i masowo pobierzemy z witryny PAUart zbiór grafik Dürera. Użyjemy do tego do kwerend w języku XPath oraz program Wget.
Masowe pobieranie plików z muzeów czy archiwów cyfrowych nie powinno zakłócać normalnego funkcjonowania witryny dla innych użytkowników. W przypadku korzystania w ten sposób ze zbiorów udostępnianych przez instytucje dziedzictwa trzeba też pamiętać o różnorodnych przepisach prawa. Oprócz kwestii prawa autorskiego i domeny publicznej, obowiązują także przepisy chroniące bazy danych. Te regulacje prawne mogą ograniczać swobodę ponownego wykorzystania skanów i opisów interesujących nas kolekcji.
Cele lekcji
Celem lekcji jest:
- ćwiczenie z posługiwania się językiem XPath,
- zdobycie wiedzy na temat witryn internetowych generowanych w pamięci przeglądarki (tzw. Client-Side Rendering, CSR),
- nauka korzystania z programu Wget,
- podkreślenie znaczenia statusu domeny publicznej w prawie do swobodnego korzystania ze zdigitalizowanego dziedzictwa.
Efekty
Efektem lekcji jest podstawowa umiejętność masowego pobierania plików z witryn muzeów czy archiwów na podstawie samodzielnie przygotowanych list adresów URL.
Wymagania
Do korzystania z lekcji konieczna jest przeglądarka internetowa - najlepiej Chrome lub Chromium, w której zainstalować można wtyczkę XPath Helper. Konieczne jest także pobranie i instalacja programu Wget, dostępnego dla wszystkich systemów operacyjnych. Do skorzystania z lekcji wymagana jest także podstawowa wiedza na temat instalowania i korzystania z programów w wybranym przez siebie systemie operacyjnym.
Część merytoryczna
W momencie przygotowywania lekcji, w cyfrowych zbiorach PAUart znajduje się 498 prac Dürera. Jeśli w ustawieniach listy przeglądania wybierzemy 80 miniatur na stronę, to do przepracowania będziemy mieli 7 stron.
Szukanie punktu zaczepienia
Pierwszym naszym celem będzie zdobycie bezpośrednich adresów skanów. Nie interesują nas miniatury, widoczne na liście przeglądania, ale pliki dobrej jakości, które podglądać można na stronie każdego z obiektów.
Jeden z pierwszych obiektów na liście to Tarcza herbowa z lwem i kogutem - odbitka ze wzoru z 1502/1503 roku. Po wejściu na stronę obiektu możemy zapoznać się z metadanymi - jest wśród nich informacja o statusie dzieła (domena publiczna). Po lewej stronie znajduje się wizerunek obiektu z lupą, która pozwala na niewielkie powiększenie szczegółów skanu. Ponieważ chcemy pobrać pliki odpowiedniej jakości, musimy na stronie obiektu znaleźć miejsce, w którym są one linkowane. Potrzebne nam adresy URL.
Adres ten znajdziemy pod ikoną pobierania tuż nad metadanymi:
Odwiedzenie stron kilku obiektów i sprawdzenie odnośników pod ikoną pobierania pozwoliło nam uchwycić pewien schemat budowania adresów plików skanów:
http://www.pauart.pl/api/assets/BGR_000014/huge/download
http://www.pauart.pl/api/assets/BGR_000019/huge/download
http://www.pauart.pl/api/assets/BGR_000025/huge/download
http://www.pauart.pl/api/assets/BGR_000039/huge/download
Widać wyraźnie, że adresy te różnią się wyłącznie identyfikatorem obiektu (BGR_000014, BGR_000019 itd.). Gdyby udało się nam zebrać identyfikatory wszystkich grafik Dürera w witrynie PAUArt, moglibyśmy użyć ChatGPT do wygenerowania na ich podstawie listy linków. Skąd jednak wziąć te identyfikatory?
Praca z adresami URL
Uważnie analizując strukturę i linki witryny PAUArt możemy zauważyć, że niektóre strony obiektów mają w swoim adresie identyfikator. Tak jest np. z linkowaną już wyżej Tarczą herbową:
Identyfikator obiektu | BGR_000014 |
Adres URL strony | http://www.pauart.pl/app/artwork?id=BGR_000014 |
Adres pliku | http://www.pauart.pl/api/assets/BGR_000014/huge/download |
Niestety, w strukturze witryny jest pewna niekonsekwencja. Zobaczmy obiekt Fryderyk III Mądry (1463-1525):
Identyfikator obiektu | BGR_000047 |
Adres URL strony | http://www.pauart.pl/app/artwork?id=553549db0cf22871cc1774fe |
Adres pliku | http://www.pauart.pl/api/assets/BGR_000047/huge/download |
Okazuje się, że w niektórych przypadkach adres strony obiektu nie ma bezpośredniego powiązania z jego identyfikatorem! Nie możemy więc po prostu wyciągnąć linków do wszystkich obiektów i to z nich zrobić listę adresów plików do pobrania. Na szczęście w kodzie strony znajduje się element, który pozwoli nam na przygotowanie takiej listy i skorzystanie z Wget.
Jeśli najedziemy myszą na miniaturę dzieła i wybierzemy opcję Zbadaj, w przeglądarce pojawi się panel dewelopera, w którym wyświetlony zostanie kod źródłowy:
<div class="box album-item ng-scope" ng-repeat="artwork in artworks.content">
<a ng-href="/app/artwork?id=553549db0cf22871cc1774fe" href="/app/artwork?id=553549db0cf22871cc1774fe">
<div class="thumbnail" ng-attr-style="background-image: url()" style="background-image: url(api/assets/BGR_000047/square_cutout_small/raw)"></div>
</a>
<div class="box-footer">
<a ng-href="/app/artwork?id=553549db0cf22871cc1774fe" href="/app/artwork?id=553549db0cf22871cc1774fe">
<div class="item-author">
<ul>
<!-- ngRepeat: el in artwork.authors -->
<li ng-repeat="el in artwork.authors" class="ng-scope">
<span ng-bind-html="el.author | translate" class="ng-binding">Nieokreślony</span>
</li>
<!-- end ngRepeat: el in artwork.authors -->
</ul>
</div>
<div class="item-title ng-binding">Fryderyk III Mądry (1463-1525)</div>
<div class="item-date ng-binding">1524-1600</div>
</a>
<div class="item-add" ng-show="config.navigart.albumEnabled && !UserprofileService.isInAlbum(artwork._id)" ng-click="UserprofileService.addToAlbum(artwork._id)"></div>
<div class="item-remove ng-hide" ng-show="UserprofileService.isInAlbum(artwork._id)" ng-click="removeFromAlbum(artwork._id)"></div>
</div>
</div>
Interesować nas będzie element o klasie thumbnail, który odpowiada za wyświetlanie miniaturki. W atrybucie style znajdziemy fragment jego adresu, zawierający identyfikator obiektu. Musieliśmy wykonać nieco detektywistycznej pracy, ale udało nam się w końcu znaleźć element, z którego pobierzemy identyfikatory interesujących nas obiektów.
<div class="thumbnail" ng-attr-style="background-image: url()" style="background-image: url(api/assets/BGR_000047/square_cutout_small/raw)"></div>
Warto zwrócić uwagę, że wyświetlenie źródła strony za pomocą opcji Wyświetl źródło strony niewiele nam da. Witryna PAUart jest publikowana metodą Client-Side Rendering (CSR), co oznacza, że większa część kodu tworzącego strukturę, estetykę i dane każdej strony tej witryny generowane jest bezpośrednio w pamięci przeglądarki użytkownika i użytkowniczki, a nie na serwerze. Taki sposób publikowania witryn stanowić może wyzwanie przy automatycznym pobieraniu z nich danych - na szczęście są rozwiązania, które pozwalają sobie z tym poradzić. Ponieważ jednak w tej lekcji ręcznie pozyskujemy identyfikatory i korzystamy z przeglądarki, problemy te nas nie dotyczą.
Co nam udostępni XPath
Skoro wiemy, że identyfikatory obiektów znajdują się w adresie miniaturek, musimy pozyskać je za pomocą kwerendy XPath. W tym celu uruchamiamy wtyczkę i wpisujemy zapytanie:
//div[@class='thumbnail']/@style
Kwerenda jest zbudowana następująco: wskazujemy wszystkie elementy DIV o klasie thumbnail, niezależnie od ich miejsca w strukturze strony. Dla każdego z tych elementów wyświetlamy wartość atrybutu style. W efekcie otrzymujemy listę - w momencie przygotowywania tej lekcji, kwerenda zwróciła 67 odpowiedzi, przy czym nie wszystkie są dla nas użyteczne:
background-image: url(api/assets/BGR_000014/square_cutout_small/raw)
background-image: url(api/assets/BGR_000015/square_cutout_small/raw)
background-image: url(api/assets/BGR_000018/square_cutout_small/raw)
background-image: url(api/assets/BGR_000019/square_cutout_small/raw)
background-image: url(api/assets/BGR_000020/square_cutout_small/raw)
background-image: url(api/assets/BGR_000021/square_cutout_small/raw)
background-image: url(api/assets/BGR_000022/square_cutout_small/raw)
background-image: url(api/assets/BGR_000023/square_cutout_small/raw)
background-image: url(api/assets/BGR_000025/square_cutout_small/raw)
background-image: url(api/assets/BGR_000026/square_cutout_small/raw)
background-image: url(api/assets/BGR_000027/square_cutout_small/raw)
background-image: url(api/assets/BGR_000028/square_cutout_small/raw)
background-image: url(api/assets/BGR_000030/square_cutout_small/raw)
background-image: url(api/assets/BGR_000033/square_cutout_small/raw)
background-image: url(api/assets/BGR_000034/square_cutout_small/raw)
background-image: url(api/assets/BGR_000035/square_cutout_small/raw)
background-image: url(api/assets/BGR_000037/square_cutout_small/raw)
background-image: url(api/assets/BGR_000038/square_cutout_small/raw)
background-image: url(api/assets/BGR_000039/square_cutout_small/raw)
background-image: url(api/assets/BGR_000040/square_cutout_small/raw)
background-image: url(api/assets/BGR_000041/square_cutout_small/raw)
background-image: url(api/assets/BGR_000042/square_cutout_small/raw)
background-image: url(api/assets/BGR_000044/square_cutout_small/raw)
background-image: url(api/assets/BGR_000045/square_cutout_small/raw)
background-image: url(api/assets/BGR_000046/square_cutout_small/raw)
background-image: url(api/assets/BGR_000047/square_cutout_small/raw)
background-image: url(api/assets/BGR_000049/square_cutout_small/raw)
background-image: url(api/assets/BGR_000051/square_cutout_small/raw)
background-image: url(api/assets/BGR_000052/square_cutout_small/raw)
background-image: url(api/assets/BGR_000053/square_cutout_small/raw)
background-image: url(api/assets/BGR_000054/square_cutout_small/raw)
background-image: url(api/assets/584679ee0cf2844219bffe31/square_cutout_small/raw)
background-image: url(api/assets/BGR_000056/square_cutout_small/raw)
background-image: url(api/assets/BGR_000057/square_cutout_small/raw)
background-image: url(api/assets/BGR_000058/square_cutout_small/raw)
background-image: url(api/assets/BGR_000059/square_cutout_small/raw)
background-image: url(api/assets/BGR_000060/square_cutout_small/raw)
background-image: url(api/assets/BGR_000061/square_cutout_small/raw)
background-image: url(api/assets/BGR_000063/square_cutout_small/raw)
background-image: url(api/assets/BGR_000064/square_cutout_small/raw)
background-image: url(api/assets/BGR_000065/square_cutout_small/raw)
background-image: url(api/assets/BGR_000066/square_cutout_small/raw)
background-image: url(api/assets/58467d410cf2844219bffe33/square_cutout_small/raw)
background-image: url(api/assets/BGR_000068/square_cutout_small/raw)
background-image: url(api/assets/BGR_000069/square_cutout_small/raw)
background-image: url(api/assets/BGR_000070/square_cutout_small/raw)
background-image: url(api/assets/BGR_000071/square_cutout_small/raw)
background-image: url(api/assets/BGR_000072/square_cutout_small/raw)
background-image: url(api/assets/BGR_000073/square_cutout_small/raw)
background-image: url(api/assets/BGR_000075/square_cutout_small/raw)
background-image: url(api/assets/BGR_000076/square_cutout_small/raw)
background-image: url(api/assets/BGR_000077/square_cutout_small/raw)
background-image: url(api/assets/BGR_000078/square_cutout_small/raw)
background-image: url(api/assets/BGR_000080/square_cutout_small/raw)
background-image: url(api/assets/BGR_000082/square_cutout_small/raw)
background-image: url(api/assets/BGR_000083/square_cutout_small/raw)
background-image: url(api/assets/BGR_000084/square_cutout_small/raw)
background-image: url(api/assets/BGR_000085/square_cutout_small/raw)
background-image: url(api/assets/BGR_000087/square_cutout_small/raw)
background-image: url(api/assets/BGR_000088/square_cutout_small/raw)
background-image: url(api/assets/BGR_000089/square_cutout_small/raw)
background-image: url(api/assets/BGR_000090/square_cutout_small/raw)
background-image: url(api/assets/BGR_000091/square_cutout_small/raw)
background-image: url(api/assets/[object Object]/square_cutout_small/raw)
background-image: url(api/assets/BGR_000094/square_cutout_small/raw)
background-image: url(api/assets/BGR_000095/square_cutout_small/raw)
background-image: url(api/assets/BGR_000096/square_cutout_small/raw)
Skorzystamy teraz z ChatGPT aby przetworzyć tę listę na listę identyfikatorów. Usuniemy z niej elementy, które nie są nam przydatne i być może wskazują na jakieś błędy w oprogramowaniu. W razie potrzeby możemy poprawić je ręcznie. Skorzystajmy z promptu
wyczyść tę listę, zostawiając na niej wyłącznie identyfikatory w schemacie BGR_NUMER.
W efekcie otrzymamy listę identyfikatorów:
BGR_000014
BGR_000015
BGR_000018
BGR_000019
BGR_000020
BGR_000021
BGR_000022
BGR_000023
BGR_000025
BGR_000026
BGR_000027
BGR_000028
BGR_000030
BGR_000033
BGR_000034
BGR_000035
BGR_000037
BGR_000038
BGR_000039
BGR_000040
BGR_000041
BGR_000042
BGR_000044
BGR_000045
BGR_000046
BGR_000047
BGR_000049
BGR_000051
BGR_000052
BGR_000053
BGR_000054
BGR_000056
BGR_000057
BGR_000058
BGR_000059
BGR_000060
BGR_000061
BGR_000063
BGR_000064
BGR_000065
BGR_000066
BGR_000068
BGR_000069
BGR_000070
BGR_000071
BGR_000072
BGR_000073
BGR_000075
BGR_000076
BGR_000077
BGR_000078
BGR_000080
BGR_000082
BGR_000083
BGR_000084
BGR_000085
BGR_000087
BGR_000088
BGR_000089
BGR_000090
BGR_000091
BGR_000094
BGR_000095
BGR_000096
Pozostaje nam tylko wygenerować na ich podstawie adresy plików skanów według schematu, który ustaliliśmy podczas analizy stron obiektów. Skorzystajmy z prompta
na podstawie tej listy identyfikatorów wygeneruj adresy URL w schemacie http://www.pauart.pl/api/assets/IDENTYFIKATOR/huge/download
Efekt jest taki jaki zakładaliśmy - ChatGPT jest bardzo pomocny przy prostych przekształceniach ciągów tekstowych. Oczywiście moglibyśmy zrobić to samo np. w Excelu, ale skorzystanie z ChatGPT jest szybsze i bardziej intuicyjne. Tę samą czynność powinniśmy zrobić dla kolejnych stron listy obiektów - pominę ją ze względu na obszerność tej lekcji.
http://www.pauart.pl/api/assets/BGR_000014/huge/download
http://www.pauart.pl/api/assets/BGR_000015/huge/download
http://www.pauart.pl/api/assets/BGR_000018/huge/download
http://www.pauart.pl/api/assets/BGR_000019/huge/download
http://www.pauart.pl/api/assets/BGR_000020/huge/download
http://www.pauart.pl/api/assets/BGR_000021/huge/download
http://www.pauart.pl/api/assets/BGR_000022/huge/download
http://www.pauart.pl/api/assets/BGR_000023/huge/download
http://www.pauart.pl/api/assets/BGR_000025/huge/download
http://www.pauart.pl/api/assets/BGR_000026/huge/download
http://www.pauart.pl/api/assets/BGR_000027/huge/download
http://www.pauart.pl/api/assets/BGR_000028/huge/download
http://www.pauart.pl/api/assets/BGR_000030/huge/download
http://www.pauart.pl/api/assets/BGR_000033/huge/download
http://www.pauart.pl/api/assets/BGR_000034/huge/download
http://www.pauart.pl/api/assets/BGR_000035/huge/download
http://www.pauart.pl/api/assets/BGR_000037/huge/download
http://www.pauart.pl/api/assets/BGR_000038/huge/download
http://www.pauart.pl/api/assets/BGR_000039/huge/download
http://www.pauart.pl/api/assets/BGR_000040/huge/download
http://www.pauart.pl/api/assets/BGR_000041/huge/download
http://www.pauart.pl/api/assets/BGR_000042/huge/download
http://www.pauart.pl/api/assets/BGR_000044/huge/download
http://www.pauart.pl/api/assets/BGR_000045/huge/download
http://www.pauart.pl/api/assets/BGR_000046/huge/download
http://www.pauart.pl/api/assets/BGR_000047/huge/download
http://www.pauart.pl/api/assets/BGR_000049/huge/download
http://www.pauart.pl/api/assets/BGR_000051/huge/download
http://www.pauart.pl/api/assets/BGR_000052/huge/download
http://www.pauart.pl/api/assets/BGR_000053/huge/download
http://www.pauart.pl/api/assets/BGR_000054/huge/download
http://www.pauart.pl/api/assets/BGR_000056/huge/download
http://www.pauart.pl/api/assets/BGR_000057/huge/download
http://www.pauart.pl/api/assets/BGR_000058/huge/download
http://www.pauart.pl/api/assets/BGR_000059/huge/download
http://www.pauart.pl/api/assets/BGR_000060/huge/download
http://www.pauart.pl/api/assets/BGR_000061/huge/download
http://www.pauart.pl/api/assets/BGR_000063/huge/download
http://www.pauart.pl/api/assets/BGR_000064/huge/download
http://www.pauart.pl/api/assets/BGR_000065/huge/download
http://www.pauart.pl/api/assets/BGR_000066/huge/download
http://www.pauart.pl/api/assets/BGR_000068/huge/download
http://www.pauart.pl/api/assets/BGR_000069/huge/download
http://www.pauart.pl/api/assets/BGR_000070/huge/download
http://www.pauart.pl/api/assets/BGR_000071/huge/download
http://www.pauart.pl/api/assets/BGR_000072/huge/download
http://www.pauart.pl/api/assets/BGR_000073/huge/download
http://www.pauart.pl/api/assets/BGR_000075/huge/download
http://www.pauart.pl/api/assets/BGR_000076/huge/download
http://www.pauart.pl/api/assets/BGR_000077/huge/download
http://www.pauart.pl/api/assets/BGR_000078/huge/download
http://www.pauart.pl/api/assets/BGR_000080/huge/download
http://www.pauart.pl/api/assets/BGR_000082/huge/download
http://www.pauart.pl/api/assets/BGR_000083/huge/download
http://www.pauart.pl/api/assets/BGR_000084/huge/download
http://www.pauart.pl/api/assets/BGR_000085/huge/download
http://www.pauart.pl/api/assets/BGR_000087/huge/download
http://www.pauart.pl/api/assets/BGR_000088/huge/download
http://www.pauart.pl/api/assets/BGR_000089/huge/download
http://www.pauart.pl/api/assets/BGR_000090/huge/download
http://www.pauart.pl/api/assets/BGR_000091/huge/download
http://www.pauart.pl/api/assets/BGR_000094/huge/download
http://www.pauart.pl/api/assets/BGR_000095/huge/download
http://www.pauart.pl/api/assets/BGR_000096/huge/download
Korzystanie z Wget w linii komend
Wget to program do pobierania zasobów WWW - od pojedynczych plików aż po całe witryny WWW.
Wget działa w konsoli (terminalu) - programy tego typu posiadają wyłącznie interfejs tekstowy (Command Line Interface, CLI). Od zwykłego programu desktopowego różnią się tym, że użytkownik korzysta z funkcji programu wyłącznie przez wprowadzanie poleceń tekstowych do terminala - tutaj też wyświetlane są wyniki działania programu. W programach działających w ten sposób nie ma graficznego interfejsu użytkownika (GUI), a który umożliwiałby korzystanie z przycisków, menu czy okien dialogowych.
Po poprawnej instalacji programu Wget powinniśmy móc uruchomić ten program w terminalu naszego systemu operacyjnego. Wpisujemy wget, klikamy ENTER i w efekcie otrzymujemy podstawową informację o składni wysyłania poleceń do programu:
$ wget
wget: brakujący URL
Składnia: wget [OPCJE]... [URL]...
Polecenie `wget --help' wyświetli więcej opcji.
Oczywiście program nie wykonał żadnej czynności, ponieważ nie podaliśmy żadnych opcji i adresów obiektów internetowych. Aby pobrać plik, podajemy jego ścieżkę i w efekcie po chwili na dysku pojawia się jego kopia:
$ wget http://www.pauart.pl/api/assets/BGR_000084/huge/download
--2024-02-21 16:48:26-- http://www.pauart.pl/api/assets/BGR_000084/huge/download
Translacja www.pauart.pl (www.pauart.pl)... 149.156.51.44
Łączenie się z www.pauart.pl (www.pauart.pl)|149.156.51.44|:80... połączono.
Żądanie HTTP wysłano, oczekiwanie na odpowiedź... 200 6470
Długość: nieznana [image/jpeg]
Zapis do: `download'
download [ <=> ] 451,89K 2,64MB/s w 0,2s
2024-02-21 16:48:27 (2,64 MB/s) - zapisano `download' [462732]
Moglibyśmy teraz masowo pobrać pliki z przygotowanych przez nas wyżej adresów - składnia polecenia dla wget jest bardzo prosta:
wget --wait=5 -i pliki.txt
Dodaliśmy dwie opcje. Pierwsza to –wait=5 wprowadza pięciosekundową przerwę między pobieraniem każdego pliku (staramy się nie blokować serwera). Druga opcja to -i - wskazanie nazwy pliku (dostępnego w katalogu, z którego uruchamiamy Wget) z listą adresów do pobrania (pliki.txt).
Niestety w związku z ustawieniami serwera PAUArt, pobierane pliki nazywane będa kolejno download (w niektórych systemach operacyjnych mogą być też nadpisywane) co nie jest dla nas optymalną sytuacją.
Pobieranie plików w pętli
Pewnym rozwiązaniem tego problemu może być skorzystanie z pętli w języku bash - użytkownicy innych systemów operacyjnych niż Linux / Ubuntu muszą zainstalować sobie tę powłokę systemu (jak prosto zrobić to w Windowsie - zobacz tutaj). Naszą listę pliki.txt zamieniamy na tabelę w formacie CSV, gdzie kolumny oddzielone są przecinkami. Przygotujemy ją w ChatGPT za pomocą promptu:
przygotuj tabelę w CSV, w której pierwszą kolumną będzie nazwa pliku z rozszerzeniem JPG bazująca na identyfikatorze zaczynającym się od BGR z każdego adresu w drugiej kolumnie: [podajemy linki]
W efekcie otrzymujemy tabelę CSV:
nazwa_pliku,adres_url
BGR_000014.jpg,http://www.pauart.pl/api/assets/BGR_000014/huge/download
BGR_000015.jpg,http://www.pauart.pl/api/assets/BGR_000015/huge/download
BGR_000018.jpg,http://www.pauart.pl/api/assets/BGR_000018/huge/download
BGR_000019.jpg,http://www.pauart.pl/api/assets/BGR_000019/huge/download
BGR_000020.jpg,http://www.pauart.pl/api/assets/BGR_000020/huge/download
BGR_000021.jpg,http://www.pauart.pl/api/assets/BGR_000021/huge/download
BGR_000022.jpg,http://www.pauart.pl/api/assets/BGR_000022/huge/download
BGR_000023.jpg,http://www.pauart.pl/api/assets/BGR_000023/huge/download
BGR_000025.jpg,http://www.pauart.pl/api/assets/BGR_000025/huge/download
BGR_000026.jpg,http://www.pauart.pl/api/assets/BGR_000026/huge/download
BGR_000027.jpg,http://www.pauart.pl/api/assets/BGR_000027/huge/download
BGR_000028.jpg,http://www.pauart.pl/api/assets/BGR_000028/huge/download
BGR_000030.jpg,http://www.pauart.pl/api/assets/BGR_000030/huge/download
BGR_000033.jpg,http://www.pauart.pl/api/assets/BGR_000033/huge/download
BGR_000034.jpg,http://www.pauart.pl/api/assets/BGR_000034/huge/download
BGR_000035.jpg,http://www.pauart.pl/api/assets/BGR_000035/huge/download
BGR_000037.jpg,http://www.pauart.pl/api/assets/BGR_000037/huge/download
BGR_000038.jpg,http://www.pauart.pl/api/assets/BGR_000038/huge/download
BGR_000039.jpg,http://www.pauart.pl/api/assets/BGR_000039/huge/download
BGR_000040.jpg,http://www.pauart.pl/api/assets/BGR_000040/huge/download
BGR_000041.jpg,http://www.pauart.pl/api/assets/BGR_000041/huge/download
BGR_000042.jpg,http://www.pauart.pl/api/assets/BGR_000042/huge/download
BGR_000044.jpg,http://www.pauart.pl/api/assets/BGR_000044/huge/download
BGR_000045.jpg,http://www.pauart.pl/api/assets/BGR_000045/huge/download
BGR_000046.jpg,http://www.pauart.pl/api/assets/BGR_000046/huge/download
BGR_000047.jpg,http://www.pauart.pl/api/assets/BGR_000047/huge/download
BGR_000049.jpg,http://www.pauart.pl/api/assets/BGR_000049/huge/download
BGR_000051.jpg,http://www.pauart.pl/api/assets/BGR_000051/huge/download
BGR_000052.jpg,http://www.pauart.pl/api/assets/BGR_000052/huge/download
BGR_000053.jpg,http://www.pauart.pl/api/assets/BGR_000053/huge/download
BGR_000054.jpg,http://www.pauart.pl/api/assets/BGR_000054/huge/download
BGR_000056.jpg,http://www.pauart.pl/api/assets/BGR_000056/huge/download
BGR_000057.jpg,http://www.pauart.pl/api/assets/BGR_000057/huge/download
BGR_000058.jpg,http://www.pauart.pl/api/assets/BGR_000058/huge/download
BGR_000059.jpg,http://www.pauart.pl/api/assets/BGR_000059/huge/download
BGR_000060.jpg,http://www.pauart.pl/api/assets/BGR_000060/huge/download
BGR_000061.jpg,http://www.pauart.pl/api/assets/BGR_000061/huge/download
BGR_000063.jpg,http://www.pauart.pl/api/assets/BGR_000063/huge/download
BGR_000064.jpg,http://www.pauart.pl/api/assets/BGR_000064/huge/download
BGR_000065.jpg,http://www.pauart.pl/api/assets/BGR_000065/huge/download
BGR_000066.jpg,http://www.pauart.pl/api/assets/BGR_000066/huge/download
BGR_000068.jpg,http://www.pauart.pl/api/assets/BGR_000068/huge/download
BGR_000069.jpg,http://www.pauart.pl/api/assets/BGR_000069/huge/download
BGR_000070.jpg,http://www.pauart.pl/api/assets/BGR_000070/huge/download
BGR_000071.jpg,http://www.pauart.pl/api/assets/BGR_000071/huge/download
BGR_000072.jpg,http://www.pauart.pl/api/assets/BGR_000072/huge/download
BGR_000073.jpg,http://www.pauart.pl/api/assets/BGR_000073/huge/download
BGR_000075.jpg,http://www.pauart.pl/api/assets/BGR_000075/huge/download
BGR_000076.jpg,http://www.pauart.pl/api/assets/BGR_000076/huge/download
BGR_000077.jpg,http://www.pauart.pl/api/assets/BGR_000077/huge/download
BGR_000078.jpg,http://www.pauart.pl/api/assets/BGR_000078/huge/download
BGR_000080.jpg,http://www.pauart.pl/api/assets/BGR_000080/huge/download
BGR_000082.jpg,http://www.pauart.pl/api/assets/BGR_000082/huge/download
BGR_000083.jpg,http://www.pauart.pl/api/assets/BGR_000083/huge/download
BGR_000084.jpg,http://www.pauart.pl/api/assets/BGR_000084/huge/download
BGR_000085.jpg,http://www.pauart.pl/api/assets/BGR_000085/huge/download
BGR_000087.jpg,http://www.pauart.pl/api/assets/BGR_000087/huge/download
BGR_000088.jpg,http://www.pauart.pl/api/assets/BGR_000088/huge/download
BGR_000089.jpg,http://www.pauart.pl/api/assets/BGR_000089/huge/download
BGR_000090.jpg,http://www.pauart.pl/api/assets/BGR_000090/huge/download
BGR_000091.jpg,http://www.pauart.pl/api/assets/BGR_000091/huge/download
BGR_000094.jpg,http://www.pauart.pl/api/assets/BGR_000094/huge/download
BGR_000095.jpg,http://www.pauart.pl/api/assets/BGR_000095/huge/download
BGR_000096.jpg,http://www.pauart.pl/api/assets/BGR_000096/huge/download
Pozostaje już tylko poprosić Chat GPT o wygenerowanie odpowiedniej pętli w języku bash. Skrypt będzie uruchamiał polecenie wget dla każdego wiersza naszej tabeli i korzystał z kolumny nazwa_pliku, aby nadać nazwę pliku pobranemu skanowi:
podaj jednolinijkowy skrypt w bashu ktory uruchomi polecenie wget dla kazdego wiersza z pierwszej kolumny adres_url pliku pliki.csv oraz nada mu nazwę z kolumny nazwa_pliku. niech polecenie wget uruchamia się co 5 sekund i nie uwzględnia pierwszej linijki (nagłówka kolumn)
W efekcie otrzymujemy kod:
tail -n +2 pliki.csv | while IFS=',' read -r nazwa_pliku adres_url; do wget -O "$nazwa_pliku" "$adres_url"; sleep 5; done
Ten skrypt wykonuje następujące czynności:
- tail -n +2 pliki.csv: pobiera zawartość pliku pliki.csv, pomijając pierwszą linijkę (nagłówek kolumn),
- while IFS=’,’ read -r nazwa_pliku adres_url; do … done: czyta każdą linię pliku pliki.csv, oddzielając nazwę pliku i adres URL po przecinku (,) i wykonuje pętlę dla każdej linii,
- wget -O “$nazwa_pliku” “$adres_url”: pobiera plik z adresu URL i zapisuje go pod nazwą wskazaną w kolumnie nazwa_pliku,
- sleep 5: czeka 5 sekund przed wykonaniem kolejnego polecenia wget, aby spełnić wymaganie pobierania kolejnego pliku po 5 sekundach od pobrania ostatniego.
Wklejamy go do terminala i zaczynamy pobieranie plików!
Podsumowanie
Domena publiczna to nie tylko status prawnoautorski rozmaitych obiektów - warto też ją praktykować, korzystając w różny sposób z zasobów udostępnianych przez instytucje dziedzictwa. Ponieważ te instytucje nie zawsze pozwalają w łatwy sposób pozyskać większą ilość własnych zbiorów cyfrowych, warto nauczyć się, jak robić to szybko i niezależnie. Masowo pobrane pliki można wykorzystać do dalszej analizy w ramach konkretnych badań albo do przygotowywania kolaży i wizualizacji.
Wykorzystanie metod
Kwerendy XPath i masowe pobieranie zasobów WWW z wykorzystaniem Wget lub innych programów stanowi często wstępną fazę projektów badawczych czy dziennikarskich w ramach działań OSINT (Open Source Intelligence). Badania OSINT polegają m.in. na zbieraniu, analizie i wykorzystywaniu informacji pochodzących z dostępnych publicznie źródeł takich jak witryny i fora internetowe, media społecznościowe czy repozytoria dokumentów.
Pomysł na warsztat
Uczestnicy i uczestniczki warsztatu mogą podjąć próbę analizy dostępności dobrej jakości reprodukcji cyfrowych w wybranym muzeum czy archiwum cyfrowym oraz zastanowić się, czy struktura witryny muzeum/archiwum pozwala na łatwe znalezienie bezpośrednich linków do dobrej jakości plików. Próba ich masowego pobrania z wykorzystaniem kwerend XPath i Wget może być dobrym ćwiczeniem umiejętności niezależnego pozyskiwania danych z internetu oraz zwracać uwagę na znaczenie struktury kodu źródłowego witryn w ich maszynowym wykorzystywaniu. Warsztat można połączyć z przedstawieniem podstaw języka HTML (elementy, atrybuty, drzewo DOM).