De auteur van het artikel dat we vandaag vertalen, zegt dat zijn doel is om te vertellen over de ontwikkeling van een web scraper in Python met behulp van Selenium, die prijszoekopdrachten voor vliegtickets uitvoert. Bij het zoeken naar tickets worden flexibele data gebruikt (+- 3 dagen ten opzichte van de opgegeven data). De scraper slaat de zoekresultaten op in een Excel-bestand en stuurt een e-mail naar degene die het heeft uitgevoerd met algemene informatie over wat hij heeft kunnen vinden. Het doel van dit project is om reizigers te helpen de beste aanbiedingen te vinden.
Als je tijdens het bestuderen van het materiaal het gevoel hebt dat je verloren bent — kijk dan naar artikel.
Wat gaan we zoeken?
Je bent vrij om het hier beschreven systeem te gebruiken zoals je wilt. Ik heb het bijvoorbeeld gebruikt om weekenduitjes en tickets naar mijn geboortestad te zoeken. Als je serieus bent over het vinden van voordelige tickets, kun je het script op een server draaien (een eenvoudige, , voor 130 roebel per maand, is hiervoor prima geschikt) en het zo instellen dat het één of twee keer per dag wordt uitgevoerd. De zoekresultaten worden naar je e-mail gestuurd. Bovendien raad ik aan alles zo in te stellen dat het script een Excel-bestand met de zoekresultaten opslaat in een Dropbox-map, zodat je zulke bestanden overal en op elk moment kunt bekijken.

Ik heb nog geen tarieven met fouten gevonden, maar ik denk dat dit mogelijk is.
Bij het zoeken, zoals al eerder vermeld, wordt 'flexibele datum' gebruikt; het script vindt aanbiedingen binnen drie dagen van de opgegeven datums. Hoewel het script bij het uitvoeren van de zoekopdracht alleen aanbiedingen voor één bestemming zoekt, is het niet moeilijk om het te verbeteren zodat het gegevens voor meerdere vluchtbestemmingen kan verzamelen. Het kan zelfs verkeerd geprijsde tarieven zoeken; zulke vondsten kunnen erg interessant zijn.
Waarom is er weer een web scraper nodig?
Toen ik voor het eerst begon met webscraping, vond ik het eerlijk gezegd niet zo interessant. Ik wilde liever meer projecten doen op het gebied van voorspellende modellering, financiële analyse en misschien in de analyse van emotionele toon van teksten. Maar al snel ontdekte ik dat het heel interessant is om een programma te maken dat gegevens van websites verzamelt. Naarmate ik dieper in dit onderwerp dook, realiseerde ik me dat webscraping de "motor" van het internet is.
Misschien vind je dit een gewaagde uitspraak. Maar denk eens aan het feit dat Google begon met een webscraper die Larry Page bouwde met Java en Python. De Google-robots verkennen en verkennen het internet om hun gebruikers de beste antwoorden op hun vragen te bieden. Webscraping heeft een eindeloos aantal toepassingsmogelijkheden, en zelfs als je, in de Data Science, geïnteresseerd bent in iets anders, heb je wat scrapingvaardigheden nodig om gegevens voor analyse te verkrijgen.
Sommige van de technieken die hier zijn gebruikt, vond ik in een geweldige over webscraping die ik recent heb aangeschaft. Het bevat veel eenvoudige voorbeelden en ideeën voor de praktische toepassing van het geleerde. Bovendien is er een zeer interessant hoofdstuk over het omzeilen van reCaptcha-controles. Voor mij was dit een onthulling, omdat ik niet wist dat er speciale tools en zelfs volledige diensten bestaan voor dergelijke taken.
Hou je van reizen?!
Op de eenvoudige en vrij onschuldige vraag die in de titel van dit gedeelte is gesteld, krijg je vaak een positief antwoord, vergezeld van een paar reisverhalen van degene aan wie je de vraag stelt. De meeste van ons zijn het erover eens dat reizen een geweldige manier is om in nieuwe culturele omgevingen ondergedompeld te worden en je blik te verruimen. Maar als je iemand vraagt of hij het leuk vindt om vliegtickets te zoeken, ben ik ervan overtuigd dat het antwoord al een stuk minder positief zal zijn. Eigenlijk komt Python hier goed van pas.
De eerste taak die we moeten oplossen op de weg naar het creëren van een systeem voor het zoeken naar informatie over vliegtickets is het selecteren van een geschikt platform waarvan we de gegevens gaan ophalen. Deze taak was niet gemakkelijk voor me, maar uiteindelijk koos ik voor de service Kayak. Ik heb Momondo, Skyscanner, Expedia en nog een paar andere diensten geprobeerd, maar de robotbescherming op deze sites was eenvoudigweg niet te omzeilen. Na verschillende pogingen, waarbij ik systemen moest overtuigen dat ik een mens was — en ik moest omgaan met verkeerslichten, voetgangersoversteekplaatsen en fietsen — besloot ik dat Kayak het beste bij mij paste, ondanks het feit dat ook hier controles beginnen wanneer je te veel pagina's in korte tijd laadt. Ik slaagde erin om de bot verzoeken naar de site te laten sturen met tussenpozen van 4 tot 6 uur, wat goed werkte. Af en toe ontstaan er problemen bij het werken met Kayak, maar als je lastiggevallen wordt door controles, moet je ofwel handmatig met ze omgaan voordat je de bot laat draaien, of enkele uren wachten zodat de controles stoppen. Als dat nodig is, kun je de code gemakkelijk aanpassen voor een ander platform, en als je dat doet — laat het ons weten in de reacties.
Als je net begint met web scraping en niet weet waarom sommige websites haar best doen om dit tegen te gaan, doe jezelf dan een dienst en zoek op Google naar materialen onder de zoekwoorden "web scraping etiquette" voordat je aan je eerste project in dit gebied begint. Je experimenten kunnen sneller eindigen dan je denkt als je niet verstandig met web scraping omgaat.
Aan de slag
Hier is een algemeen overzicht van wat er in de code van onze webscraper zal gebeuren:
- Importeren van de benodigde bibliotheken.
- Een tabblad Google Chrome openen.
- Het aanroepen van de functie die de bot start, waarbij steden en data worden doorgegeven die gebruikt zullen worden voor het zoeken naar tickets.
- Deze functie verkrijgt de eerste zoekresultaten, gesorteerd op het criterium van de meeste aantrekkelijkheid (best), en klikt op de knop om extra resultaten te laden.
- Een andere functie verzamelt gegevens van de gehele pagina en retourneert een dataframe.
- De twee vorige stappen worden uitgevoerd met behulp van sorteercriteria op de ticketprijzen (cheap) en op de vliegtijd (fastest).
- De gebruiker van het script ontvangt een e-mail met een samenvatting van de ticketprijzen (de goedkoopste tickets en de gemiddelde prijs), terwijl de datastructuur met informatie, gesorteerd op de bovengenoemde drie indicatoren, wordt opgeslagen als een Excel-bestand.
- Alle bovengenoemde acties worden uitgevoerd in een lus met een bepaalde tijdsinterval.
Het is belangrijk op te merken dat elk Selenium-project begint met een web-driver. Ik gebruik , werk met Google Chrome, maar er zijn ook andere opties. PhantomJS en Firefox zijn ook populair. Na het downloaden van de driver moet deze in de juiste map worden geplaatst, wat de voorbereiding voor het gebruik ervan afrondt. In de eerste regels van ons script wordt een nieuw tabblad in Chrome geopend.
Houd er rekening mee dat ik in mijn verhaal geen nieuwe horizonten wil openen voor het vinden van voordelige aanbiedingen voor vliegtickets. Er zijn veel geavanceerdere technieken om dergelijke aanbiedingen te vinden. Ik wil alleen de lezers van dit materiaal een eenvoudige, maar praktische manier bieden om dit probleem op te lossen.
Hier is de code waarover we het eerder hadden.
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
# Gebruik hier jouw pad naar chromedriver!
chromedriver_path = 'C:/{YOUR PATH HERE}/chromedriver_win32/chromedriver.exe'
driver = webdriver.Chrome(executable_path=chromedriver_path) # Dit commando opent een Chrome-venster
sleep(2) Aan het begin van de code kunnen we de importopdrachten van de pakketten zien die in ons hele project worden gebruikt. Zo wordt randint gebruikt om de bot een willekeurig aantal seconden te laten 'slapen' voordat hij een nieuwe zoekoperatie begint. Gewoonlijk komt dit in geen enkele bot voor. Als je de bovenstaande code uitvoert, wordt er een Chrome-venster geopend dat de bot zal gebruiken om met de websites te werken.
Laten we een kleine experimentele test doen en de site kayak.com in een nieuw venster openen. We kiezen de stad waaruit we willen vliegen, de stad waar we naartoe willen en de datums van de vlucht. Bij het kiezen van de datums zorgen we ervoor dat we een bereik van +-3 dagen gebruiken. Ik heb een code geschreven die rekening houdt met de antwoorden die de site geeft op dergelijke verzoeken. Als je bijvoorbeeld alleen tickets voor specifieke datums wilt zoeken, is de kans groot dat je de bot-code moet aanpassen. Tijdens het bespreken van de code geef ik de nodige uitleg, maar als je het gevoel hebt dat je in de war raakt, laat het me dan weten.
Klik nu op de knop om de zoekopdracht te starten en kijk naar de link in de adresbalk. Deze zou vergelijkbaar moeten zijn met de link die ik in het voorbeeld hieronder gebruik, waar de variabele kayak, die de URL bevat, wordt aangemaakt en de methode krijgen van de webdriver wordt gebruikt. Na het drukken op de zoekknop zouden de resultaten op de pagina moeten verschijnen.
![]()
Toen ik het commando krijgen meer dan twee of drie keer binnen enkele minuten gebruikte, werd mij gevraagd om reCaptcha te verifiëren. Deze verificatie kan handmatig worden doorlopen en je kunt blijven experimenteren totdat het systeem beslist dat er een nieuwe verificatie moet plaatsvinden. Toen ik het script testte, had ik het gevoel dat de eerste zoeksessie altijd probleemloos verloopt, dus als je met de code wilt experimenteren, moet je alleen periodiek handmatig de verificatie doorlopen en de code laten draaien met lange intervallen tussen de zoeksessies. En als je erover nadenkt, heeft een persoon waarschijnlijk geen informatie over ticketprijzen nodig die met 10 minuten tussentijd tussen zoekopdrachten worden verkregen.
Werken met de pagina met behulp van XPath
Dus, we hebben een venster geopend en de site geladen. Om informatie over prijzen en andere gegevens te verkrijgen, moeten we gebruikmaken van de technologie van XPath of CSS-selectors. Ik heb ervoor gekozen om bij XPath te blijven en voelde de behoefte niet om CSS-selectors te gebruiken, maar het is heel goed mogelijk om dat ook te doen. Navigeren op de pagina met XPath kan een uitdagende taak zijn, en zelfs als je de methoden gebruikt die ik beschreven heb in In het artikel, waar ik de betreffende identificaties uit de pagina code kopieerde, realiseerde ik me dat dit in feite geen optimale manier is om de benodigde elementen aan te spreken. Trouwens, in het boek vind je een uitstekende beschrijving van de basisprincipes van het werken met pagina's met behulp van XPath en CSS-selectors. Dit is hoe de betreffende methode van de webdriver eruit ziet.
![]()
Laten we dus doorgaan met het werken aan de bot. We maken gebruik van de mogelijkheden van het programma om de goedkoopste tickets te selecteren. In de volgende afbeelding is de XPath-selectorcode in het rood gemarkeerd. Om de code te bekijken, moet je met de rechtermuisknop op het element van de pagina klikken dat je interesseert en in het menu de optie Inspecteren (View code) selecteren. Deze optie kan voor verschillende elementen van de pagina worden aangeroepen, waarbij de code zal worden weergegeven en gemarkeerd in het codeweergavevenster.

Bekijk de paginacode
Om bevestiging te vinden voor mijn argumenten over de tekortkomingen van het kopiëren van selectors uit de code, let op de volgende aspecten.
Dit is wat er gebeurt bij het kopiëren van de code:
//*[@id="wtKI-price_aTab"]/div[1]/div/div/div[1]/div/span/spanOm iets dergelijks te kopiëren, moet je met de rechtermuisknop op het desbetreffende deel van de code klikken en in het menu de optie Copy > Copy XPath selecteren.
Dit is wat ik gebruikte om de Cheapest-knop te identificeren:
cheap_results = '//*[a[@data-code = "price"]]' 
De optie Copy > Copy XPath
Het is volkomen duidelijk dat de tweede optie er veel eenvoudiger uitziet. Bij het gebruik ervan wordt gezocht naar het element a, dat de attribuut heeft data-code, gelijk aan price. Bij het gebruik van de eerste optie wordt gezocht naar het element id wiens identifier gelijk is aan wtKI-price_aTab, waarbij de XPath-route naar het element eruitziet als /div[1]/div/div/div[1]/div/span/span. Zo'n XPath-query naar de pagina zal zijn werk doen, maar - slechts één keer. Ik kan nu al zeggen dat id zal veranderen bij de volgende keer dat de pagina wordt geladen. De reeks symbolen wtKI verandert dynamisch bij elke paginalading, waardoor de code waarin het wordt gebruikt na de volgende herlaadbeurt van de pagina waardeloos zal zijn. Dus neem wat tijd om je in XPath te verdiepen. Deze kennis zal je goed van pas komen.
Het moet echter worden opgemerkt dat het kopiëren van XPath-selectors nuttig kan zijn bij het werken met relatief eenvoudige websites, en als je je daarbij goed voelt, is er niets mis mee.
Laten we nu kijken naar hoe we alle zoekresultaten in meerdere regels binnen een lijst kunnen krijgen. Dat is heel eenvoudig. Elk resultaat bevindt zich in een object met de klasse resultWrapper. Het laden van alle resultaten kan in een lus worden uitgevoerd, vergelijkbaar met de onderstaande code.
Het is belangrijk op te merken dat als je het bovenstaande begrijpt, je zonder problemen de meeste code zou moeten kunnen begrijpen die we gaan analyseren. Tijdens de uitvoering van deze code richten we ons op wat we nodig hebben (terwijl dit eigenlijk het element is dat de resultaten omhult), met behulp van een mechanisme om het pad aan te geven (XPath). Dit wordt gedaan om de tekst van het element te verkrijgen en deze in een object te plaatsen waaruit we gegevens kunnen lezen (eerder wordt flight_containers, en vervolgens — flights_list).

De eerste drie regels worden weergegeven en we kunnen duidelijk zien wat we nodig hebben. Maar er zijn nog interessantere manieren om informatie te verkrijgen. We moeten gegevens uit elk element afzonderlijk ophalen.
Aan de slag!
Het is het gemakkelijkst om een functie te schrijven om extra resultaten te laden, dus daar beginnen we mee. Ik wil het aantal vluchten maximaliseren waarvan het programma informatie verkrijgt, zonder dat dat de dienst wantrouwig maakt, dus klik ik elke keer op de knop 'Laad meer resultaten' wanneer de pagina wordt weergegeven. In deze code moeten we letten op de blok try, die ik heb toegevoegd omdat de knop soms niet goed laadt. Als je ook met dit probleem te maken krijgt — commentarieer dan de aanroepen van deze functie in de code van de functie start_kayak, die we hieronder zullen behandelen.
# Загрузка большего количества результатов для того, чтобы максимизировать объём собираемых данных
def load_more():
try:
more_results = '//a[@class = "moreButton"]'
driver.find_element_by_xpath(more_results).click()
# Вывод этих заметок в ходе работы программы помогает мне быстро выяснить то, чем она занята
print('sleeping.....')
sleep(randint(45,60))
except:
passNu, na een grondige bespreking van deze functie (soms kan ik me daarin verliezen), zijn we klaar om de functie te verklaren die de pagina gaat scrapen.
Ik heb al het meeste van wat nodig is verzameld in de volgende functie, genaamd page_scrape. Soms worden de teruggegeven gegevens over de route samengevoegd, om ze te scheiden gebruik ik een eenvoudige methode. Bijvoorbeeld, wanneer ik voor de eerste keer de variabelen gebruik section_a_list en section_b_list. Onze functie geeft een gegevensframe terug flights_df, dit stelt ons in staat om de resultaten, verkregen met verschillende methoden voor gegevenssortering, te scheiden en later samen te voegen.
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 Ik heb geprobeerd om variabelen zodanig te benoemen dat de code begrijpelijk is. Vergeet niet dat variabelen die beginnen met a betrekking hebben op de eerste fase van de reis, en b behoren tot de tweede. Laten we doorgaan naar de volgende functie.
Hulpmiddelen
Nu hebben we een functie die het mogelijk maakt om aanvullende zoekresultaten te laden en een functie voor het verwerken van deze resultaten. Dit artikel zou hierop kunnen eindigen, aangezien deze twee functies alles bieden wat nodig is voor het scrapen van pagina's die zelfstandig kunnen worden geopend. Maar we hebben nog niet enkele van de eerder genoemde hulpmiddelen bekeken. Bijvoorbeeld de code voor het verzenden van e-mails en nog enkele andere dingen. Dit alles is te vinden in de functie start_kayak, die we nu gaan bekijken.
Voor het functioneren van deze functie zijn gegevens over steden en data nodig. Met deze gegevens vormt het een link in de variabele kayak, die wordt gebruikt om naar de pagina te gaan waar de zoekresultaten staan, gesorteerd op hun beste overeenstemming met de aanvraag. Na de eerste sessie van scrapen zullen we de prijzen behandelen die zich in de tabel bovenaan de pagina bevinden. Namelijk, we zullen de minimumprijs van het ticket en de gemiddelde prijs vinden. Dit alles, samen met de voorspelling die door de site wordt gegeven, zal per e-mail worden verzonden. Op de pagina moet de bijbehorende tabel zich in de linkerbovenhoek bevinden. Werken met deze tabel kan overigens een fout veroorzaken bij het zoeken met exacte data, aangezien in dat geval de tabel op de pagina niet wordt weergegeven.
def start_kayak(city_from, city_to, date_start, date_end):
"""Stadscodes - het zijn de IATA-codes!
Datumformaat - 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))
# Soms verschijnt er een popup, gebruik het try-blok voor controle en om deze te sluiten
try:
xp_popup_close = '//*[@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('meer laden.....')
# load_more()
print('start eerste scrape.....')
df_flights_best = page_scrape()
df_flights_best['sort'] = 'beste'
sleep(randint(60,80))
# Neem de laagste prijs uit de tabel bovenaan de 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('overschakelen naar de goedkopere resultaten.....')
cheap_results = '//*[@data-code = "price"]'
driver.find_element_by_xpath(cheap_results).click()
sleep(randint(60,90))
print('meer laden.....')
# load_more()
print('start tweede scrape.....')
df_flights_cheap = page_scrape()
df_flights_cheap['sort'] = 'goedkoop'
sleep(randint(60,80))
print('overschakelen naar de snelste resultaten.....')
quick_results = '//*[@data-code = "duration"]'
driver.find_element_by_xpath(quick_results).click()
sleep(randint(60,90))
print('meer laden.....')
# load_more()
print('start derde scrape.....')
df_flights_fast = page_scrape()
df_flights_fast['sort'] = 'snel'
sleep(randint(60,80))
# Opslaan van de nieuwe frame in Excel-bestand, met een naam die de steden en data weerspiegelt
final_df = df_flights_cheap.append(df_flights_best).append(df_flights_fast)
final_df.to_excel('search_backups/{}_flights_{}-{}_van_{}_naar_{}.xlsx'.format(strftime("%Y%m%d-%H%M"),
city_from, city_to,
date_start, date_end), index=False)
print('gegeven df opgeslagen.....')
# Je kunt volgen hoe de prognose van de website zich verhoudt tot de werkelijkheid
xp_loading = '//*[@id="advice"]'
loading = driver.find_element_by_xpath(xp_loading).text
xp_prediction = '//*[@class="info-text"]'
prediction = driver.find_element_by_xpath(xp_prediction).text
print(loading+'n'+prediction)
# Soms kan de variabele loading deze regel bevatten, die later problemen kan veroorzaken bij het verzenden van een e-mail
# Als dit gebeurt, wijzig deze dan in "Not Sure"
weird = '¯_(ツ)_/¯'
if loading == weird:
loading = 'Niet zeker'
username = 'JOUWMAIL@hotmail.com'
password = 'JOUW WACHTWOORD'
server = smtplib.SMTP('smtp.outlook.com', 587)
server.ehlo()
server.starttls()
server.login(username, password)
msg = ('Onderwerp: Vliegtuig Scraper nnGoedkoopste Vlucht: {}nGemiddelde Prijs: {}nnAanbeveling: {}nnEinde van bericht'.format(matrix_min, matrix_avg, (loading+'n'+prediction)))
message = MIMEMultipart()
message['From'] = 'JOUWMAIL@hotmail.com'
message['to'] = 'JOUWANDEREEMAIL@domain.com'
server.sendmail('JOUWMAIL@hotmail.com', 'JOUWANDEREEMAIL@domain.com', msg)
print('e-mail verzonden.....')Ik heb dit script getest met een Outlook-account (hotmail.com). Ik heb het niet gecontroleerd op de werking met een Gmail-account; dit e-mailsysteem is behoorlijk populair, maar er zijn tal van mogelijke varianten. Als je echter een Hotmail-account gebruikt, hoef je alleen maar je gegevens in de code in te voeren om alles aan de praat te krijgen.
Als je wilt begrijpen wat er precies gebeurt in bepaalde delen van de code van deze functie, kun je ze kopiëren en ermee experimenteren. Experimenteren met code is de enige manier om het goed te begrijpen.
Klaar systeem
Nu we alles hebben gedaan wat we hebben besproken, kunnen we een eenvoudige lus maken waarin onze functies worden aangeroepen. Het script vraagt de gebruiker om gegevens over steden en data. Bij het testen met constante herstart van het script, wil je waarschijnlijk niet elke keer deze gegevens handmatig invoeren, dus de relevante regels kunnen voor de testperiode worden uitgecommentarieerd, terwijl de regels eronder, waarin de vereiste gegevens voor het script hard zijn ingesteld, worden ingeschakeld.
city_from = input('Van welke stad? ')
city_to = input('Waarheen? ')
date_start = input('Zoek rond welke vertrekdatum? Gebruik alleen het formaat YYYY-MM-DD ')
date_end = input('Wanneer terug? Gebruik alleen het formaat 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('iteratie {} was compleet @ {}'.format(n, strftime("%Y%m%d-%H%M")))
# Wacht 4 uur
sleep(60*60*4)
print('slaap is afgelopen.....') Dit is hoe een testuitvoering van het script eruit ziet.

Testuitvoering van het script
Conclusies
Als je dit punt hebt bereikt, gefeliciteerd! Nu heb je een werkende web-scraper, hoewel ik al veel manieren zie om het te verbeteren. Je kunt het bijvoorbeeld integreren met Twilio, zodat het in plaats van e-mails tekstberichten kan versturen. Je kunt een VPN of iets anders gebruiken om gelijktijdig resultaten van meerdere servers te krijgen. Er is ook de sporadische uitdaging van het controleren of de gebruiker een robot is, maar ook dit probleem kan worden opgelost. Hoe dan ook, nu heb je een basis die je, als je dat wilt, kunt uitbreiden. Bijvoorbeeld, om een Excel-bestand als bijlage in een e-mail naar de gebruiker te sturen.
Alleen geregistreerde gebruikers kunnen deelnemen aan de enquête. , alstublieft.
Maak je gebruik van web-scrapingtechnologieën?
Yes
No
8 gebruikers hebben gestemd. 1 gebruiker onthield zich.
Bron: habr.com
