L'autore dell'articolo che pubblichiamo oggi afferma che il suo obiettivo è spiegare lo sviluppo di un web scraper in Python utilizzando Selenium, che cerca i prezzi dei voli. Durante la ricerca dei biglietti vengono utilizzate date flessibili (+- 3 giorni rispetto alle date indicate). Lo scraper salva i risultati della ricerca in un file Excel e invia un'email a chi lo ha eseguito con un riepilogo di ciò che è riuscito a trovare. L'obiettivo di questo progetto è aiutare i viaggiatori a trovare le offerte più vantaggiose.
Se, mentre studi il materiale, ti senti disorientato, dai un'occhiata a articolo.
Cosa andremo a cercare?
Sei libero di utilizzare il sistema descritto qui come desideri. Io, ad esempio, l'ho usato per cercare offerte per weekend e biglietti per la mia città natale. Se sei seriamente intenzionato a trovare biglietti vantaggiosi, puoi eseguire lo script su un server (semplice , per 130 rubli al mese, è completamente adatto) e fare in modo che venga eseguito una o due volte al giorno. I risultati della ricerca verranno inviati tramite e-mail. Inoltre, consiglio di configurare tutto in modo che lo script salvi un file Excel con i risultati della ricerca in una cartella Dropbox, il che ti permetterà di visualizzare tali file da qualsiasi luogo e in qualsiasi momento.

Non ho ancora trovato tariffe errate, ma suppongo che sia possibile.
Nella ricerca, come già detto, si utilizza una "data flessibile", lo script trova le offerte che sono entro tre giorni dalle date impostate. Anche se quando lo script viene eseguito cerca solo offerte in una direzione, non è difficile modificarlo in modo che possa raccogliere dati su più direzioni di volo. Con esso, è possibile anche cercare tariffe errate, tali scoperte potrebbero rivelarsi piuttosto interessanti.
A cosa serve un ulteriore web scraper?
Quando ho iniziato a occuparmi di web scraping, onestamente, non mi sembrava molto interessante. Volevo realizzare più progetti nel campo della modellazione predittiva, dell'analisi finanziaria e, forse, nell'analisi del sentiment dei testi. Ma si è rivelato essere davvero affascinante capire come creare un programma che raccolga dati dai siti web. Man mano che approfondivo l'argomento, ho capito che proprio il web scraping è il "motore" di Internet.
Potrebbe sembrare un'affermazione audace. Ma pensate che Google è nato da un web scraper che Larry Page ha creato usando Java e Python. I robot di Google esplorano e continuano a esplorare Internet per fornire ai propri utenti le migliori risposte alle loro domande. Il web scraping ha un numero infinito di applicazioni e, anche se in Data Science siete interessati a qualcos'altro, per raccogliere dati per l'analisi avrete bisogno di alcune competenze di scraping.
Alcuni dei metodi utilizzati qui li ho trovati in un meraviglioso sulla web scraping che ho recentemente acquisito. In essa è possibile trovare numerosi esempi semplici e idee per l'applicazione pratica di quanto appreso. Inoltre, c'è un capitolo molto interessante sull'aggiramento dei controlli reCaptcha. È stata una novità per me, poiché non sapevo che esistessero strumenti speciali e persino interi servizi per affrontare simili compiti.
Ami viaggiare?!
A una semplice e piuttosto innocua domanda, evidenziata nel titolo di questa sezione, si può spesso sentire una risposta positiva, accompagnata da un paio di storie sui viaggi di chi l'ha ascoltata. La maggior parte di noi concorderebbe sul fatto che i viaggi sono un modo meraviglioso per immergersi in nuove culture e ampliare i propri orizzonti. Tuttavia, se si chiede a qualcuno se gli piace cercare voli, sono certo che la risposta non sarà così positiva. In effetti, qui ci viene in aiuto Python.
Il primo compito da risolvere nella creazione di un sistema di ricerca di informazioni sui biglietti aerei è scegliere la piattaforma giusta da cui raccogliere i dati. Questa decisione non è stata facile per me, ma alla fine ho scelto il servizio Kayak. Ho provato Momondo, Skyscanner, Expedia e altri, ma i meccanismi di protezione da bot su quei siti erano insormontabili. Dopo diversi tentativi, durante i quali ho dovuto affrontare semafori, attraversamenti pedonali e biciclette nel tentativo di convincere i sistemi che ero un essere umano, ho deciso che Kayak era la scelta migliore, nonostante anche qui, se si tentano di caricare troppe pagine in poco tempo, iniziano i controlli. Sono riuscito a fare in modo che il bot inviasse richieste al sito con intervalli fra 4 e 6 ore, e tutto funzionava correttamente. Periodicamente possono sorgere difficoltà anche con Kayak, ma se sei continuamente disturbato dai controlli, puoi o risolverli manualmente prima di far partire il bot, oppure aspettare alcune ore finché i controlli non si fermano. Se necessario, puoi adattare il codice per un'altra piattaforma e se lo fai, sentiti libero di comunicarlo nei commenti.
Se stai appena iniziando a esplorare il web scraping e non sai perché alcuni siti web combattono con tutte le loro forze contro di esso, prima di intraprendere il tuo primo progetto in questo campo, fai a te stesso un favore e cerca su Google materiali con le parole "etichetta del web scraping". I tuoi esperimenti potrebbero concludersi più rapidamente di quanto pensi se non ti approcci al web scraping in modo sensato.
Inizio
Ecco una panoramica di ciò che accadrà nel codice del nostro web scraper:
- Importazione delle librerie necessarie.
- Apertura della scheda di Google Chrome.
- Chiamata della funzione che avvia il bot, passando le città e le date che saranno utilizzate nella ricerca dei voli.
- Questa funzione ottiene i primi risultati di ricerca, ordinati per il criterio di maggiore attrattiva (best), e fa clic sul pulsante per caricare ulteriori risultati.
- Un'altra funzione raccoglie i dati dall'intera pagina e restituisce un frame di dati.
- I due passaggi precedenti vengono eseguiti utilizzando i tipi di ordinamento per prezzo dei biglietti (cheap) e per durata del volo (fastest).
- All'utente dello script viene inviata un'email con un riepilogo dei prezzi dei biglietti (i biglietti più economici e il prezzo medio), e il frame di dati con le informazioni, ordinato secondo i tre indicatori sopra menzionati, viene salvato come file Excel.
- Tutte le azioni sopra descritte vengono eseguite in un ciclo a intervalli di tempo specificati.
Va notato che ogni progetto Selenium inizia con un WebDriver. Personalmente utilizzo , lavorando con Google Chrome, ma ci sono anche altre opzioni. Tra i più popolari ci sono PhantomJS e Firefox. Dopo aver scaricato il driver, è necessario posizionarlo nella cartella appropriata; così termina la preparazione al suo utilizzo. Nelle prime righe del nostro script si apre una nuova scheda di Chrome.
Si tenga conto che, nel mio racconto, non sto cercando di aprire nuovi orizzonti nella ricerca di offerte vantaggiose per i voli. Esistono anche tecniche molto più avanzate per trovare tali offerte. Vorrei solo proporre ai lettori di questo materiale un metodo semplice, ma attuabile nella pratica per risolvere questo problema.
Ecco il codice di cui abbiamo parlato in precedenza.
from time import sleep, strftime
from random import randint
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import smtplib
from email.mime.multipart import MIMEMultipart
# Usa qui il tuo percorso per chromedriver!
chromedriver_path = 'C:/{YOUR PATH HERE}/chromedriver_win32/chromedriver.exe'
driver = webdriver.Chrome(executable_path=chromedriver_path) # Questo comando apre una finestra di Chrome
sleep(2) All'inizio del codice puoi vedere i comandi per importare i pacchetti che vengono utilizzati in tutto il nostro progetto. Così, randint viene utilizzato per fare in modo che il bot «dormi» per un numero casuale di secondi prima di iniziare una nuova operazione di ricerca. Di solito, nessun bot può farne a meno. Se esegui il codice sopra, si aprirà una finestra di Chrome che il bot utilizzerà per lavorare con i siti web.
Faremo un piccolo esperimento e apriremo in una nuova finestra il sito kayak.com. Selezioneremo la città da cui intendiamo partire e la città in cui vogliamo arrivare, insieme alle date dei voli. Quando scegliamo le date, verificheremo di utilizzare un intervallo di ±3 giorni. Ho scritto il codice tenendo conto di ciò che il sito restituisce in risposta a tali richieste. Se, ad esempio, hai bisogno di cercare biglietti solo per le date specificate, è molto probabile che dovrai modificare il codice del bot. Mentre parlo del codice, fornisco le spiegazioni appropriate, ma se senti che ti sei confuso, fammi sapere.
Ora facciamo clic sul pulsante per avviare la ricerca e osserviamo il link nella barra degli indirizzi. Dovrebbe essere simile al link che uso nell'esempio sottostante, dove viene dichiarata la variabile kayak, che memorizza l'URL, e viene utilizzato il metodo get del driver web. Dopo aver fatto clic sul pulsante di ricerca, dovrebbero apparire i risultati sulla pagina.
![]()
Quando ho utilizzato il comando get più di due o tre volte in pochi minuti, mi è stato chiesto di eseguire un controllo utilizzando reCaptcha. Questo controllo può essere completato manualmente e si può continuare a sperimentare fino a quando il sistema decide di impostare un nuovo controllo. Quando ho testato lo script, ho avuto l'impressione che la prima sessione di ricerca procedesse sempre senza problemi, quindi, se desideri sperimentare con il codice, dovrai solo completare il controllo manualmente di tanto in tanto e lasciare che il codice venga eseguito, utilizzando intervalli lunghi tra le sessioni di ricerca. E, a ben pensarci, a una persona non servirebbero informazioni sui prezzi dei biglietti ottenute con intervalli di 10 minuti tra le operazioni di ricerca.
Lavorare con la pagina utilizzando XPath
Quindi, abbiamo aperto la finestra e caricato il sito. Per ottenere informazioni sui prezzi e altre informazioni, dobbiamo utilizzare la tecnologia XPath o i selettori CSS. Ho deciso di concentrarmi su XPath e non ho sentito la necessità di usare i selettori CSS, ma è possibile lavorare anche in questo modo. Navigare nella pagina utilizzando XPath può essere complicato e anche se utilizzi i metodi che ho descritto in articolo, dove applicavo la copia degli identificatori corrispondenti dal codice della pagina, ho capito che, in realtà, non è il modo ottimale per accedere agli elementi necessari. A proposito, nel libro si trova una descrizione eccellente delle basi del lavoro con le pagine utilizzando XPath e i selettori CSS. Ecco come appare il metodo corrispondente del web driver.
![]()
Quindi, continuiamo a lavorare sul bot. Utilizzeremo le funzioni del programma per scegliere i biglietti più economici. Nell'immagine seguente, il codice del selettore XPath è evidenziato in rosso. Per visualizzare il codice, fai clic con il tasto destro del mouse sull'elemento della pagina di tuo interesse e seleziona l'opzione Ispeziona (Inspect) dal menu che appare. Questa opzione può essere invocata per diversi elementi della pagina, il cui codice verrà visualizzato e evidenziato nella finestra di ispezione del codice.

Visualizza il codice della pagina
Per trovare conferma delle mie considerazioni sui difetti della copia dei selettori dal codice, presta attenzione alle seguenti caratteristiche.
Ecco cosa succede quando copiamo il codice:
//*[@id="wtKI-price_aTab"]/div[1]/div/div/div[1]/div/span/spanPer copiare qualcosa di simile, fai clic con il tasto destro del mouse sulla parte di codice che ti interessa e scegli nel menu apparso l'opzione Copia > Copia XPath.
Ecco cosa ho usato per definire il pulsante Cheapest:
cheap_results = ‘//a[@data-code = "price"]’ 
Comando Copia > Copia XPath
È chiaramente evidente che la seconda opzione appare molto più semplice. Utilizzando questa, viene cercato l'elemento a, che ha l'attributo data-code, uguale a prezzo. Utilizzando la prima opzione, si ricerca un elemento id il cui valore è wtKI-price_aTab, dove il percorso XPath per l'elemento appare come /div[1]/div/div/div[1]/div/span/span. Una richiesta XPath di questo tipo alla pagina funzionerà, ma solo una volta. Posso dirti subito che id cambierà al successivo caricamento della pagina. La sequenza di caratteri wtKI cambia dinamicamente ad ogni caricamento della pagina, rendendo il codice in cui viene utilizzato inutile dopo ogni successivo riavvio della pagina. Quindi prenditi un momento per capire XPath. Queste conoscenze ti saranno molto utili.
Tuttavia, è importante notare che copiare i selettori XPath può essere utile quando si lavora con siti abbastanza semplici, e se questo ti sta bene, non c'è nulla di male.
Adesso pensiamo a come procedere se dobbiamo ottenere tutti i risultati della ricerca in più righe all'interno di un elenco. È molto semplice. Ogni risultato si trova all'interno di un oggetto con classe resultWrapper. Il caricamento di tutti i risultati può essere effettuato in un ciclo, simile a quello che verrà mostrato di seguito.
È importante notare che se quanto sopra è chiaro, dovresti essere in grado di comprendere senza problemi la maggior parte del codice che analizzeremo. Durante l'esecuzione di questo codice, per accedere a ciò di cui abbiamo bisogno (in effetti, questo è l'elemento che contiene il risultato), utilizziamo un meccanismo per specificare il percorso (XPath). Questo viene fatto per ottenere il testo dell'elemento e inserirlo in un oggetto da cui possiamo leggere i dati (inizialmente si usa flight_containers, poi flights_list).

Vengono visualizzate le prime tre righe e possiamo vedere chiaramente tutto ciò di cui abbiamo bisogno. Tuttavia, abbiamo anche modi più interessanti per ottenere informazioni. Dobbiamo prendere i dati da ciascun elemento singolarmente.
Iniziamo!
È più semplice scrivere una funzione per caricare risultati aggiuntivi, quindi iniziamo da lì. Vorrei massimizzare il numero di voli di cui il programma raccoglie informazioni, senza destare sospetti al servizio che potrebbero portare a controlli, quindi clicco una volta sul pulsante Carica altri risultati ogni volta che la pagina viene visualizzata. In questo codice, dovremmo prestare attenzione al blocco try, che ho aggiunto perché a volte il bottone non si carica correttamente. Se anche tu ti imbatti in questo problema, commenta le chiamate a questa funzione nel codice della funzione. start_kayak, che esamineremo di seguito.
# Загрузка большего количества результатов для того, чтобы максимизировать объём собираемых данных
def load_more():
try:
more_results = '//a[@class = "moreButton"]'
driver.find_element_by_xpath(more_results).click()
# Вывод этих заметок в ходе работы программы помогает мне быстро выяснить то, чем она занята
print('sleeping.....')
sleep(randint(45,60))
except:
passOra, dopo una lunga analisi di questa funzione (a volte mi lascio prendere), siamo pronti a dichiarare una funzione che si occuperà dello scraping della pagina.
Ho già raccolto gran parte di ciò che serve nella seguente funzione, chiamata page_scrape. A volte i dati restituiti sui percorsi risultano essere combinati, per separarli utilizzo un metodo semplice. Ad esempio, quando utilizzo per la prima volta le variabili section_a_list e section_b_list. La nostra funzione restituisce un dataframe flights_df, questo ci permette di separare i risultati ottenuti utilizzando diversi metodi di ordinamento dei dati e in seguito di combinarli.
def page_scrape():
"""This function takes care of the scraping part"""
xp_sections = '//*[@class="section duration"]'
sections = driver.find_elements_by_xpath(xp_sections)
sections_list = [value.text for value in sections]
section_a_list = sections_list[::2] # так мы разделяем информацию о двух полётах
section_b_list = sections_list[1::2]
# Если вы наткнулись на reCaptcha, вам может понадобиться что-то предпринять.
# О том, что что-то пошло не так, вы узнаете исходя из того, что вышеприведённые списки пусты
# это выражение if позволяет завершить работу программы или сделать ещё что-нибудь
# тут можно приостановить работу, что позволит вам пройти проверку и продолжить скрапинг
# я использую тут SystemExit так как хочу протестировать всё с самого начала
if section_a_list == []:
raise SystemExit
# Я буду использовать букву A для уходящих рейсов и B для прибывающих
a_duration = []
a_section_names = []
for n in section_a_list:
# Получаем время
a_section_names.append(''.join(n.split()[2:5]))
a_duration.append(''.join(n.split()[0:2]))
b_duration = []
b_section_names = []
for n in section_b_list:
# Получаем время
b_section_names.append(''.join(n.split()[2:5]))
b_duration.append(''.join(n.split()[0:2]))
xp_dates = '//div[@class="section date"]'
dates = driver.find_elements_by_xpath(xp_dates)
dates_list = [value.text for value in dates]
a_date_list = dates_list[::2]
b_date_list = dates_list[1::2]
# Получаем день недели
a_day = [value.split()[0] for value in a_date_list]
a_weekday = [value.split()[1] for value in a_date_list]
b_day = [value.split()[0] for value in b_date_list]
b_weekday = [value.split()[1] for value in b_date_list]
# Получаем цены
xp_prices = '//a[@class="booking-link"]/span[@class="price option-text"]'
prices = driver.find_elements_by_xpath(xp_prices)
prices_list = [price.text.replace('$','') for price in prices if price.text != '']
prices_list = list(map(int, prices_list))
# stops - это большой список, в котором первый фрагмент пути находится по чётному индексу, а второй - по нечётному
xp_stops = '//div[@class="section stops"]/div[1]'
stops = driver.find_elements_by_xpath(xp_stops)
stops_list = [stop.text[0].replace('n','0') for stop in stops]
a_stop_list = stops_list[::2]
b_stop_list = stops_list[1::2]
xp_stops_cities = '//div[@class="section stops"]/div[2]'
stops_cities = driver.find_elements_by_xpath(xp_stops_cities)
stops_cities_list = [stop.text for stop in stops_cities]
a_stop_name_list = stops_cities_list[::2]
b_stop_name_list = stops_cities_list[1::2]
# сведения о компании-перевозчике, время отправления и прибытия для обоих рейсов
xp_schedule = '//div[@class="section times"]'
schedules = driver.find_elements_by_xpath(xp_schedule)
hours_list = []
carrier_list = []
for schedule in schedules:
hours_list.append(schedule.text.split('n')[0])
carrier_list.append(schedule.text.split('n')[1])
# разделяем сведения о времени и о перевозчиках между рейсами a и b
a_hours = hours_list[::2]
a_carrier = carrier_list[1::2]
b_hours = hours_list[::2]
b_carrier = carrier_list[1::2]
cols = (['Out Day', 'Out Time', 'Out Weekday', 'Out Airline', 'Out Cities', 'Out Duration', 'Out Stops', 'Out Stop Cities',
'Return Day', 'Return Time', 'Return Weekday', 'Return Airline', 'Return Cities', 'Return Duration', 'Return Stops', 'Return Stop Cities',
'Price'])
flights_df = pd.DataFrame({'Out Day': a_day,
'Out Weekday': a_weekday,
'Out Duration': a_duration,
'Out Cities': a_section_names,
'Return Day': b_day,
'Return Weekday': b_weekday,
'Return Duration': b_duration,
'Return Cities': b_section_names,
'Out Stops': a_stop_list,
'Out Stop Cities': a_stop_name_list,
'Return Stops': b_stop_list,
'Return Stop Cities': b_stop_name_list,
'Out Time': a_hours,
'Out Airline': a_carrier,
'Return Time': b_hours,
'Return Airline': b_carrier,
'Price': prices_list})[cols]
flights_df['timestamp'] = strftime("%Y%m%d-%H%M") # время сбора данных
return flights_df Ho cercato di nominare le variabili in modo che il codice fosse comprensibile. Ricorda che le variabili che iniziano con a si riferiscono alla prima fase del percorso, mentre b si riferiscono alla seconda. Passiamo alla funzione successiva.
Meccanismi ausiliari
Ora abbiamo una funzione che consente di caricare risultati di ricerca aggiuntivi e una funzione per elaborare questi risultati. Potremmo anche concludere questo articolo qui, poiché queste due funzioni forniscono tutto il necessario per il scraping delle pagine che possono essere aperte autonomamente. Tuttavia, non abbiamo ancora considerato alcuni meccanismi ausiliari di cui abbiamo parlato in precedenza. Ad esempio, questo è il codice per inviare email e altre cose. Tutto ciò si può trovare nella funzione start_kayak, che stiamo per esaminare.
Per far funzionare questa funzione sono necessarie informazioni sulle città e sulle date. Essa, utilizzando queste informazioni, forma un link nella variabile kayak, utilizzata per passare alla pagina contenente i risultati della ricerca, ordinati in base alla loro migliore corrispondenza con la richiesta. Dopo il primo scraping, esamineremo i prezzi presenti nella tabella in cima alla pagina. In particolare, troveremo il prezzo minimo del biglietto e il prezzo medio. Tutto questo, insieme alla previsione fornita dal sito, sarà inviato via email. Nella pagina, la tabella corrispondente dovrebbe trovarsi nell'angolo in alto a sinistra. Lavorare con questa tabella, tra l'altro, potrebbe causare errori durante la ricerca utilizzando date precise, poiché in quel caso la tabella non viene visualizzata nella pagina.
def start_kayak(city_from, city_to, date_start, date_end):
"""Codici delle città - sono i codici IATA!
Formato della data - YYYY-MM-DD"""
kayak = ('https://www.kayak.com/flights/' + city_from + '-' + city_to +
'/' + date_start + '-flexible/' + date_end + '-flexible?sort=bestflight_a')
driver.get(kayak)
sleep(randint(8,10))
# a volte appare un popup, per controllarlo e chiuderlo si può usare il blocco try
try:
xp_popup_close = '//button[contains(@id,"dialog-close") and contains(@class,"Button-No-Standard-Style close ")]'
driver.find_elements_by_xpath(xp_popup_close)[5].click()
except Exception as e:
pass
sleep(randint(60,95))
print('caricamento in corso.....')
# load_more()
print('inizio del primo scraping.....')
df_flights_best = page_scrape()
df_flights_best['sort'] = 'best'
sleep(randint(60,80))
# Prendiamo il prezzo più basso dalla tabella situata nella parte superiore della pagina
matrix = driver.find_elements_by_xpath('//*[contains(@id,"FlexMatrixCell")]')
matrix_prices = [price.text.replace('$','') for price in matrix]
matrix_prices = list(map(int, matrix_prices))
matrix_min = min(matrix_prices)
matrix_avg = sum(matrix_prices)/len(matrix_prices)
print('passaggio ai risultati più economici.....')
cheap_results = '//a[@data-code = "price"]'
driver.find_element_by_xpath(cheap_results).click()
sleep(randint(60,90))
print('caricamento in corso.....')
# load_more()
print('inizio del secondo scraping.....')
df_flights_cheap = page_scrape()
df_flights_cheap['sort'] = 'cheap'
sleep(randint(60,80))
print('passaggio ai risultati più veloci.....')
quick_results = '//a[@data-code = "duration"]'
driver.find_element_by_xpath(quick_results).click()
sleep(randint(60,90))
print('caricamento in corso.....')
# load_more()
print('inizio del terzo scraping.....')
df_flights_fast = page_scrape()
df_flights_fast['sort'] = 'fast'
sleep(randint(60,80))
# Salvataggio del nuovo frame in un file Excel, il nome riflette le città e le date
final_df = df_flights_cheap.append(df_flights_best).append(df_flights_fast)
final_df.to_excel('search_backups//{}_flights_{}-{}_from_{}_to_{}.xlsx'.format(strftime("%Y%m%d-%H%M"),
city_from, city_to,
date_start, date_end), index=False)
print('df salvato.....')
# Si può monitorare come il pronostico fornito dal sito si confronta con la realtà
xp_loading = '//div[contains(@id,"advice")]'
loading = driver.find_element_by_xpath(xp_loading).text
xp_prediction = '//span[@class="info-text"]'
prediction = driver.find_element_by_xpath(xp_prediction).text
print(loading+'n'+prediction)
# a volte nella variabile loading si trova questa stringa, che in seguito causa problemi nell'invio dell'email
# se è così, cambiamo in "Not Sure"
weird = '¯_(ツ)_/¯'
if loading == weird:
loading = 'Non sicuro'
username = 'YOUREMAIL@hotmail.com'
password = 'YOUR PASSWORD'
server = smtplib.SMTP('smtp.outlook.com', 587)
server.ehlo()
server.starttls()
server.login(username, password)
msg = ('Subject: Flight Scrapernn
Volo più economico: {}nPrezzo medio: {}nnRaccomandazione: {}nnFine del messaggio'.format(matrix_min, matrix_avg, (loading+'n'+prediction)))
message = MIMEMultipart()
message['From'] = 'YOUREMAIL@hotmail.com'
message['to'] = 'YOUROTHEREMAIL@domain.com'
server.sendmail('YOUREMAIL@hotmail.com', 'YOUROTHEREMAIL@domain.com', msg)
print('email inviata.....')Ho testato questo script utilizzando un account Outlook (hotmail.com). Non l'ho verificato per il funzionamento con un account Gmail, che è un servizio di posta elettronica molto popolare, ma ci sono molte altre opzioni disponibili. Se stai utilizzando un account Hotmail, per farlo funzionare è sufficiente inserire i tuoi dati nel codice.
Se desideri comprendere cosa viene eseguito in sezioni specifiche di questo codice, puoi copiare quelle sezioni e fare delle prove. Sperimentare con il codice è l'unico modo per comprenderlo veramente.
Sistema pronto
Ora, dopo aver completato tutto ciò di cui abbiamo parlato, possiamo creare un semplice ciclo in cui chiamiamo le nostre funzioni. Lo script chiede all'utente di inserire dati su città e date. Durante il test con il riavvio continuo dello script, difficilmente vorrai inserire questi dati manualmente ogni volta, quindi puoi commentare temporaneamente le righe pertinenti, decommentando quelle che vanno sotto di esse, in cui sono fissati i dati necessari per lo script.
city_from = input('Da quale città? ')
city_to = input('Dove andare? ')
date_start = input('Cerca intorno a quale data di partenza? Si prega di utilizzare solo il formato YYYY-MM-DD ')
date_end = input('Quando tornare? Si prega di utilizzare solo il formato YYYY-MM-DD ')
# city_from = 'LIS'
# city_to = 'SIN'
# date_start = '2019-08-21'
# date_end = '2019-09-07'
for n in range(0,5):
start_kayak(city_from, city_to, date_start, date_end)
print('iterazione {} completata @ {}'.format(n, strftime("%Y%m%d-%H%M")))
# Aspettiamo 4 ore
sleep(60*60*4)
print('sonno finito.....') Ecco come appare l'esecuzione di prova dello script.

Esecuzione di prova dello script
Risultati
Se sei arrivato a questo punto, congratulazioni! Ora hai un web scraper funzionante, anche se vedo già molti modi in cui può essere migliorato. Ad esempio, può essere integrato con Twilio per inviare messaggi di testo invece di e-mail. Puoi utilizzare una VPN o altro per ricevere risultati da più server contemporaneamente. C'è anche un problema intermittente con la verifica dell'utente sul sito per determinare se è un umano, ma anche quel problema può essere risolto. In ogni caso, ora hai una base che puoi espandere, se lo desideri. Ad esempio, fare in modo che il file Excel venga inviato all'utente come allegato a un'e-mail.
Solo gli utenti registrati possono partecipare al sondaggio. , per favore.
Utilizzi tecnologie di web scraping?
Sì
No
Hanno votato 8 utenti. 1 utente si è astenuto.
Fonte: habr.com
