Voglio creare un raschietto HTML in Ruby on Rails e voglio implementare una barra di avanzamento e un'abilità che riprenda da dove era stata interrotta se è stata interrotta durante lo scraping.
Penso che il modo migliore per farlo sia quello di creare una tabella di database con un record per ogni singola pagina, con una colonna booleana chiamata 'raschiato?'
Penso che il mio raschietto avrebbe due parti principali. La prima parte passerebbe attraverso l'intero sito, seguendo tutti i link e salvando i loro URL nella tabella, insieme a false
per il loro attributo scraped?
. Inoltre ripristinerebbe la sequenza pk del database, il che significa che la colonna id implicherebbe accuratamente quale numero il record è (più ne parlerò dopo!)
ActiveRecord::Base.connection.reset_pk_sequence!('pages')
La seconda parte passerebbe quindi attraverso questa tabella, visitando ciascun link e, una volta eseguita la scansione di quella pagina, cambierebbe il suo attributo scraped?
a true.
Questa seconda parte inizierà con la prima pagina che non è stata ancora raschiata:
first_page = Page.where(:scraped? = false).first
La barra di avanzamento funzionerebbe secondo il seguente principio:
total_page = Page.count
done_pages = first_page.id # (the first result would always be 1 because the first part resets the sequence)
percentage = done_pages / total_pages * 100
In realtà non vedo perché questo non avrebbe funzionato, ma sono ancora molto vago su come il raschietto si aggiri e visita ogni singolo link su un sito web.
Quali sarebbero le tue idee su questo? Voglio solo alcuni suggerimenti prima di immergermi:
Come farebbe a sapere di non allontanarsi dal sito attuale? (Sto pensando a regex sull'URL per assicurarmi che contenga il dominio specificato prima di visitarlo)
Come non visiterebbe loop infiniti? Come un collegamento alla home page sulla home page? (Immagino che un condizionale farebbe il trucco qui):
if new_uri != current_uri
visit new_uri
end
In che modo la prima parte andrebbe effettivamente a spidering, salvando un indice di ogni singolo link? Creando un array di ogni singolo link sulla pagina e poi iterandolo fino a trovare un uri che non esiste nel database? (questa è in realtà la mia più grande preoccupazione.)
Se quanto sopra è vero, come saprebbe quando fermarsi? Immagino che controllerebbe ogni new_link con i collegamenti esistenti nel database? Questo è solo un programma locale che verrà eseguito una volta, quindi non sono troppo preoccupato per le prestazioni qui, ma hai un'idea migliore di seguito:
if new_uri != current_uri # technically not necessary but it would save a few database interactions
if Page.exists?( uri: new_uri) == false
visit new_uri
end
end