Proszę o wsparcie dla Krzysia Bulczaka, największego bohatera jakiego znam.

Masowa archiwizacja stron w Wayback Machine z wykorzystaniem R

Spędziłem ostatnio trochę czasu na sprawdzaniu metod i narzędzi pozwalających na masową archiwizację adresów URL w Wayback Machine. Problemem nie jest samodzielne dodanie jednego czy kilku linków do tego archiwum: można to zrobić za pomocą formularza dostępnego na stronie web.archive.org/save. Od niedawna pozwala on nawet na archiwizowanie wszystkich linków wychodzących z zabezpieczanego adresu i generowanie screenshota dokumentującego aktualny wygląd strony. Kiedy jednak adresów do zarchiwizowania jest już więcej, nie da się tego robić ręcznie.

Jednym z dostępnych rozwiązań jest masowe wysyłanie żądań (requestów) bezpośrednio do adresu https://web.archive.org/save/ z pominięciem formularza (i w ogóle przeglądarki). W R da się to zrobić w miarę prosto i sprawnie dzięki pakietowi httr.

Poniżej kod z podstawowymi komentarzami, a pod nim dodatkowe uwagi i link do strony, na której można uruchomić sobie ten program bez konieczności posiadania środowiska.



# użycie: raport <- save2wm(c('http://wp.pl/','http://prezydent.pl/'))
# funkcja przyjmuje też listy lub kolumny z ramki danych

save2wm <- function(urls) {
  
  s <- NULL
  w <- 'https://web.archive.org/save/'
  l <- length(urls)
  i <- 1
  
  for(u in urls){
    
    cat(paste0('Przetwarzam adres ',i,'/',l,' (',round(i/l * 100),'%)\n'))
    cat(paste0(u,'\n'))
    
    tryCatch(
      expr = {
        r <- httr::GET(paste0(w,u))    
          if(r$status_code == 200) {
            # status odpowiedzi 200 oznacza, że strona została poprawnie zapisana w Wayback Machine
            # wpisywanie do ramki danych odpowiedzi serwera z adresem archiwalnej kopii strony
            s <- rbind(as.data.frame(list(original_url = u, saved_url = paste0('https://web.archive.org',r$headers$`content-location`)),stringsAsFactors = FALSE),s)
          } else {
           # wpisywanie do ramki danych statusu odpowiedzi serwera 
           s <- rbind(as.data.frame(list(original_url = u, saved_url = as.character(r$status_code)),stringsAsFactors = FALSE),s)
          }
        
        cat(paste0('Status odpowiedzi: ', r$status_code,'\n'))
        
      },
      error = function(e){
        message('Wystąpił błąd!')
        print(e)
        cat('-----------------------------------------\n')    
        
      },
      warning = function(w){
        message('Ostrzeżenie!')
        print(w)
        cat('-----------------------------------------\n')    
        
      },
      finally = {
        message('Odpowiedź serwera zapisana')
      }
    )    
    # zawieszenie działania skryptu, dzięki czemu można zmieścić się w limicie zapytań

    cat('Czekam 12 sekund ')

    for(e in 0:11) {
      cat('#')
      Sys.sleep(1)
    }

    cat('\n-----------------------------------------\n')    
      
    i <- i + 1
    
    
  }
  
  return(s)
}

Przy czym taka składnia:

r <- httr::GET(paste0(w,u))

to po prostu odwołanie się do metody GET z pakietu httr bez ładowania do środowiska całego pakietu. Pozwala to odrobinę skrócić kod, pominąć problemy z identycznymi nazwami funkcji pochodzących z różnych pakietów i raczej w bardzo niewielkim stopniu ograniczyć zużycie RAMu. Alternatywnie można napisać to tak:

library(httr)
r <- GET(paste0(w,u))

I jeszcze niezbędne uzupełnienie i informacja o ograniczeniach:

  • Kod wykorzystuje tryCatch – użyteczne rozwiązanie pozwalające przynajmniej częściowo udopornić program na sytuacje, w których serwer, do którego wysyłamy żądanie, nie odpowiada. tryCatch pozwala w łatwy sposób zarządzać błędami – więcej o tym np. w tej notce;
  • w razie błędu przy archiwizacji skrypt pobierze informację o kodzie odpowiedzi serwera. Pozwala to na późniejsze wyfiltrowanie list linków, które nie zostały poprawnie zarchiwizowane i ponowienie próby;
  • głównym problemem takiej archiwizacji jest jej szybkość. Ograniczenia narzucone przez Wayback Machine pozwalają na wysyłanie do 5 requestów na minutę – dlatego po każdym żądaniu skrypt robi sobie przerwę na 12 sekund. Przy tego typu (nieautoryzowanym przecież w żaden sposób) dostępie do mechanizmów Wayback Machine trzeba się liczyć z dalszymi ograniczeniami – nie wiadomo, jakie limity mogą się jeszcze pojawić. Trudno byłoby na takiej metodzie bazować przy jakimś rozbudowanym projekcie archiwizacyjnym planowanym na dłuższy czas (np. w ramach projektu badawczego).

Źródła: https://github.com/mw0000/R/blob/master/save2wm.R
Przetestuj ten skrypt online: https://hub.gke.mybinder.org/user/mw0000-r-i390okex/notebooks/save2wm.ipynb#

Grafika: komunikacja klient-serwer (a właściwie bitwa pod Agincourt, kronika Enguerranda de Monstrelet, wczesny XV w.)

Przeczytaj także:

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Akceptowane są wyłącznie komentarze merytoryczne. Każdy komentarz podlega moderacji.

Udostępnij na Twitterze | Udostępnij na Facebooku