Forfatteren af artiklen, hvis oversættelse vi offentliggør i dag, siger, at hendes mål er at fortælle om udviklingen af en web-scraper i Python med brug af Selenium, der søger priser på flybilletter. Ved søgning af billetter anvendes fleksible datoer (+- 3 dage i forhold til de angivne datoer). Scraperen gemmer søgeresultaterne i en Excel-fil og sender en e-mail til den, der startede den, med generelle oplysninger om, hvad den har været i stand til at finde. Målet med dette projekt er at hjælpe rejsende med at finde de mest fordelagtige tilbud.
Hvis du under arbejdet med materialet føler, at du er gået tabt - kig på artiklen.
Hvad skal vi søge efter?
Du er fri til at bruge det beskrevne system, som du vil. Jeg for eksempel har anvendt det til at finde weekendture og billetter til min hjemby. Hvis du er seriøs omkring at finde fordelagtige billetter - kan du køre scriptet på en server (en simpel , til 130 kroner om måneden, vil være helt fint til dette) og få det til at køre en eller to gange om dagen. Søgningens resultater vil komme til din e-mail. Derudover anbefaler jeg at opsætte det sådan, at scriptet gemmer en Excel-fil med søgeresultaterne i en Dropbox-mappe, hvilket giver dig mulighed for at se sådanne filer fra hvor som helst og når som helst.

Jeg har endnu ikke fundet priser med fejl, men jeg formoder, at det kan være muligt.
Ved søgningen, som allerede nævnt, anvendes 'fleksibel dato', og scriptet finder tilbud, der ligger inden for tre dage fra de angivne datoer. Selvom scriptet kun søger tilbud på én rute ad gangen, er det ikke svært at tilpasse det, så det kan indsamle data for flere flyruter. Med det kan du endda søge efter fejlagtige takster; sådanne fund kan vise sig at være ganske interessante.
Hvorfor har vi brug for en ny web-scraper?
Da jeg først begyndte at skrabe web, var jeg ærligt talt ikke så interesseret i det. Jeg ønskede at gøre flere projekter inden for prognosemodellering, finansiel analyse og måske inden for følelsesmæssig tekstanalyse. Men det viste sig at være meget interessant at finde ud af, hvordan man skaber et program, der indsamler data fra hjemmesider. Efterhånden som jeg blev mere involveret i emnet, indså jeg, at det faktisk er web-scraping, der er internettets 'motor'.
Måske vil du mene, at dette er en for dristig påstand. Men tænk på, at Google startede med en web-scraper, som Larry Page skabte ved hjælp af Java og Python. Googles robotter udforsker og udforskede internettet for at give deres brugere de bedste svar på deres spørgsmål. Web-scraping har uendelige anvendelsesmuligheder, og selv hvis du i Data Science er interesseret i noget andet, vil du have brug for nogle scraping-færdigheder for at samle data til analyse.
Nogle af de teknikker, jeg har brugt her, fandt jeg i en fantastisk om web-scraping, som jeg for nylig erhvervede. Den indeholder mange enkle eksempler og idéer til praktisk anvendelse af det, du har lært. Derudover er der et meget interessant kapitel om at omgå reCaptcha-tjek. For mig var dette en nyhed, da jeg ikke vidste, at der findes specielle værktøjer og endda hele tjenester til at løse sådanne problemer.
Elsker du at rejse?!
På det enkle og temmelig uskyldige spørgsmål, der er stillet i overskriften til dette afsnit, kan man ofte høre et positivt svar, ofte ledsaget af et par rejsehistorier fra den, der blev spurgt. De fleste af os vil være enige om, at rejser er en fantastisk måde at dykke ind i nye kulturelle miljøer og udvide sin horisont. Men hvis man spørger nogen, om de kan lide at søge efter flybilletter, er jeg sikker på, at svaret vil være langt mindre positivt. Faktisk kommer Python os til hjælp her.
Den første opgave, vi skal løse på vej til at skabe et system til at finde oplysninger om flybilletter, er at vælge den rigtige platform, som vi vil hente information fra. Det var en udfordring at finde en løsning, men jeg endte med at vælge tjenesten Kayak. Jeg prøvede tjenesterne Momondo, Skyscanner, Expedia og flere andre, men de havde uigennemsigtige beskyttelsesmekanismer mod bots. Efter adskillige forsøg, hvor jeg forsøgte at overbevise systemerne om, at jeg var et menneske—med trafiklys, fodgængeroverføringer og cykler—kom jeg frem til, at Kayak var det bedste valg for mig, selvom selv her, hvis man indlæser for mange sider på kort tid, også vil møde verificeringer. Jeg fik det så, at botten sendte forespørgsler til hjemmesiden med intervaller på 4 til 6 timer, og alt fungerede normalt. Der opstår periodisk udfordringer med Kayak, men hvis de begynder at bombardere dig med verificeringer, skal du enten finde en løsning manuelt for derefter at starte botten, eller vente nogle timer, så bør verificeringerne ophøre. Du kan, hvis nødvendigt, tilpasse koden til en anden platform, og hvis du gør det, må du gerne nævne det i kommentarerne.
Hvis du lige er begyndt at udforske web scraping, og ikke ved, hvorfor nogle websteder kæmper imod det, så gør dig selv en tjeneste og søg på Google efter materialer med ordene 'web scraping etiquette', før du går i gang med dit første projekt på området. Dine eksperimenter kan ende hurtigere, end du tror, hvis du udfører web scraping uforsigtigt.
Getting Started
Her er en generel oversigt over, hvad der vil ske i koden til vores web scraper:
- Importering af de nødvendige biblioteker.
- Åbning af en fane i Google Chrome.
- Kald af en funktion, der starter botten og sender de byer og datoer, der vil blive brugt til at søge efter billetter.
- Denne funktion får de første søgeresultater sorteret efter det mest attraktive kriterium (best) og klikker på knappen for at indlæse flere resultater.
- En anden funktion samler data fra hele siden og returnerer en data frame.
- De to tidligere trin udføres med typer af sortering efter billetpriser (cheap) og efter flyvetid (fastest).
- Brugeren af scriptet modtager en e-mail, der indeholder et kort resumé af billetpriserne (de billigste billetter og gennemsnitsprisen), og datasættet med oplysninger, sorteret efter de tre nævnte parametre, gemmes i en Excel-fil.
- Alle de ovenfor beskrevne handlinger udføres i en sløjfe med et angivet tidsinterval.
Det skal bemærkes, at hvert Selenium-projekt starter med en web-driver. Jeg bruger , som arbejder med Google Chrome, men der er også andre muligheder. PhantomJS og Firefox er også populære. Efter download af driveren skal den placeres i den relevante mappe, hvorefter forberedelsen til brugen slutter. I de første linjer af vores script åbnes der en ny fane i Chrome.
Bemærk, at jeg i min beretning ikke forsøger at åbne nye horisonter for at finde fordelagtige tilbud på flybilletter. Der findes langt mere avancerede metoder til at finde sådanne tilbud. Jeg vil blot tilbyde læserne af dette materiale en enkel, men praktisk anvendelig metode til at løse denne opgave.
Her er koden, som vi talte om tidligere.
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
# Brug din sti til chromedriver her!
chromedriver_path = 'C:/{DIN STI HER}/chromedriver_win32/chromedriver.exe'
driver = webdriver.Chrome(executable_path=chromedriver_path) # Denne kommando åbner Chrome-vinduet
sleep(2) I begyndelsen af koden kan man se import-kommandoer for de biblioteker, der bruges i hele vores projekt. Således randint bruges til, at botten "sover" i et tilfældigt antal sekunder, før den påbegynder en ny søge-operation. Normalt kan ingen bot klare sig uden dette. Hvis du kører den ovenfor nævnte kode, åbnes et Chrome-vindue, som botten vil bruge til at arbejde med hjemmesider.
Lad os gennemføre et lille eksperiment og åbne kayak.com i et separat vindue. Vi vælger byen, vi skal flyve fra, og byen, vi ønsker at komme til, samt rejsedatoerne. Når vi vælger datoer, skal vi sikre os, at der bruges et interval på +-3 dage. Jeg har skrevet koden med henblik på det, som hjemmesiden giver som svar på sådanne forespørgsler. Hvis du for eksempel kun har brug for at søge efter billetter på bestemte datoer, er der stor sandsynlighed for, at du bliver nødt til at justere botkoden. Når jeg taler om koden, giver jeg de relevante forklaringer, men hvis du føler, at du er blevet forvirret, så giv mig besked.
Nu klikker vi på knappen for at starte søgningen og ser på adresselinjen. Den skal ligne det link, jeg bruger i eksemplet nedenfor, hvor variablen kayak, der gemmer URL'en, deklareres, og metoden get af webdriveren anvendes. Efter at have klikket på søgeknappen, skal resultaterne vises på siden.
![]()
Da jeg brugte kommandoen get mere end to-tre gange inden for få minutter, blev jeg bedt om at gennemgå en bekræftelse med reCaptcha. Denne bekræftelse kan gennemføres manuelt, og man kan fortsætte eksperimenterne, indtil systemet beslutter at pålægge en ny kontrol. Da jeg testede scriptet, fik jeg indtryk af, at den første søgesession altid forløb uden problemer, så hvis du ønsker at eksperimentere med koden, bliver du kun nødt til at gennemføre kontrol manuelt fra tid til anden og lade koden køre med lange intervaller mellem søgningerne. Og hvis man tænker over det, vil en person sjældent have brug for oplysninger om billetpriser indhentet med 10-minutters intervaller mellem søgninger.
Arbejdet med siden ved hjælp af XPath
Så vi har åbnet vinduet og indlæst hjemmesiden. For at få oplysninger om priser og andre informationer, skal vi bruge teknologien XPath eller CSS-selektorer. Jeg valgte at fokusere på XPath og følte ikke behov for at bruge CSS-selektorer, men det er helt muligt at arbejde på den måde. Navigation på siden ved hjælp af XPath kan være en udfordring, og selv hvis du bruger de metoder, som jeg har beskrevet i I artiklen, hvor jeg anvendte kopiering af de relevante identifikatorer fra sidekoden, indså jeg, at det faktisk ikke er en optimal måde at få adgang til de nødvendige elementer på. Forresten, i bogen kan du finde en fremragende beskrivelse af grundlæggende arbejdet med sider ved hjælp af XPath og CSS-selektorer. Sådan ser den relevante metode til web-driveren ud.
![]()
Så lad os fortsætte arbejdet på botten. Vi vil bruge programmets funktioner til at vælge de billigste billetter. På næste billede er XPath-selektorens kode fremhævet med rødt. For at se koden skal du højreklikke på det ønskede element på siden og vælge Vis kode (Inspect) i den menu, der vises. Denne kommando kan bruges til forskellige elementer på siden, hvis kode vises og fremhæves i kodevisningsvinduet.

Vis kode for siden
For at finde bekræftelse af mine overvejelser om manglerne ved at kopiere selektorer fra koden, vær opmærksom på følgende træk.
Sådan ser det ud ved kopiering af koden:
//*[@id="wtKI-price_aTab"]/div[1]/div/div/div[1]/div/span/spanFor at kopiere noget lignende, skal du højreklikke på det ønskede kodeområde og vælge Copy > Copy XPath i den menu, der vises.
Dette er, hvad jeg brugte til at bestemme knappen Cheapest:
cheap_results = ‘//a[@data-code = "price"]’ 
Kommandoen Copy > Copy XPath
Det er helt klart, at den anden mulighed ser meget simpler ud. Ved at bruge den udføres der en søgning efter et a-element, der har attributten data-code, der er lig med price. Ved anvendelse af den første mulighed udføres søgning efter et element, id hvis værdi er wtKI-price_aTab, hvor XPath-stien til elementet ser således ud /div[1]/div/div/div[1]/div/span/span. En sådan XPath-forespørgsel til siden vil gøre sit arbejde, men — kun én gang. Jeg kan allerede nu sige, at id vil ændre sig ved næste indlæsning af siden. Tegnsekvensen wtKI ændres dynamisk ved hver indlæsning af siden, hvilket gør koden, hvor den bruges, ubrugelig efter den næste sideopdatering. Så tag dig lidt tid til at forstå XPath. Denne viden vil tjene dig godt.
Det skal dog bemærkes, at kopiering af XPath-selektorer kan være nyttigt ved arbejde med ret simple hjemmesider, og hvis det fungerer for dig, er der intet galt i det.
Nu skal vi overveje, hvordan man får alle søgeresultaterne i flere rækker, indeni en liste. Det er meget enkelt. Hvert resultat findes inde i et objekt med klassen resultWrapper. Indlæsningen af alle resultater kan udføres i en løkke, som minder om den, der vises nedenfor.
Det er vigtigt at nævne, at hvis du forstår det ovenstående, så burde du uden problemer kunne forstå størstedelen af den kode, vi vil gennemgå. Under arbejdet med denne kode har vi brug for (faktisk er det et element, der indeholder resultatet) at henvende os til det ved hjælp af en mekanisme til at angive stien (XPath). Dette gøres for at få tekst fra elementet og placere det i et objekt, som vi kan læse data fra (først bruges flight_containers, derefter — flights_list).

Vi viser de første tre rækker, og vi kan tydeligt se alt, hvad vi har brug for. Men vi har også mere interessante måder at indhente information på. Vi skal samle data fra hvert element enkeltvis.
Lad os komme i gang!
Det er lettest at skrive en funktion til at indlæse flere resultater, så lad os starte med den. Jeg ønsker at maksimere antallet af flyvninger, som programmet indhenter oplysninger om, og samtidig ikke vække tjenestens mistanker, der kan føre til kontrol, så jeg klikker en gang på knappen 'Load more results', hver gang siden vises. I denne kode skal der lægges mærke til sektionen try, som jeg har tilføjet, fordi knappen nogle gange ikke indlæses ordentligt. Hvis du også støder på dette — kommentarer over funktionerne i funktionen start_kayak, som vi vil gennemgå nedenfor.
# Загрузка большего количества результатов для того, чтобы максимизировать объём собираемых данных
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, efter en lang gennemgang af denne funktion (nogle gange kan jeg virkelig blive opslugt), er vi klar til at erklære en funktion, der vil udføre side-scraping.
Jeg har allerede samlet det meste af det, der er nødvendigt, i den næste funktion, kaldet page_scrape. Nogle gange er de returnerede data om ruterne kombineret, og for at adskille dem bruger jeg en simpel metode. For eksempel, når jeg første gang bruger variablerne section_a_list og section_b_list. Vores funktion returnerer en dataramme flights_df, hvilket gør det muligt for os at adskille resultaterne opnået ved hjælp af forskellige databehandlingsmetoder, og senere — at kombinere dem.
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 Jeg har forsøgt at navngive variablerne, så koden bliver forståelig. Husk på, at variabler, der starter med en henviser til det første trin på vejen, mens b henviser til det andet. Vi går videre til den næste funktion.
Supplerende mekanismer
Nu har vi en funktion, der gør det muligt at indlæse ekstra søgeresultater, og en funktion til at behandle disse resultater. Denne artikel kunne egentlig være sluther, da disse to funktioner giver alt, hvad der er nødvendigt for at scrape sider, som man kan åbne selvstændigt. Men vi har endnu ikke dækket nogle af de supplerende mekanismer, som nævnt tidligere. For eksempel er der koden til at sende e-mails og nogle andre ting. Alt dette kan findes i funktionen start_kayak, som vi nu vil se nærmere på.
Denne funktion kræver oplysninger om byer og datoer. Den, ved at bruge disse oplysninger, danner et link i variablen kayak, som bruges til at navigere til den side, hvor resultaterne af søgningen vil befinde sig, sorteret efter deres bedste overensstemmelse med forespørgslen. Efter den første scraping-session vil vi arbejde med priserne, der findes i tabellen, øverst på siden. Nemlig, vi vil finde den laveste billetpris og den gennemsnitlige pris. Alt dette, sammen med det estimat, der gives af siden, vil blive sendt via e-mail. På siden skal den tilsvarende tabel være i øverste venstre hjørne. At arbejde med denne tabel kan i øvrigt forårsage en fejl, når man søger med præcise datoer, da tabelen ikke vises på siden i så fald.
def start_kayak(city_from, city_to, date_start, date_end):
"""Bykode - det er IATA-koderne!
Datoformat - 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))
# nogle gange vises et popup-vindue, for at kontrollere dette og lukke det kan man bruge try-blokken
try:
xp_popup_close = '//*[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('indlæser mere.....')
# load_more()
print('starter første scrap.....')
df_flights_best = page_scrape()
df_flights_best['sort'] = 'bedst'
sleep(randint(60,80))
# Lad os tage den laveste pris fra tabellen, der findes øverst på siden
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('skifter til de billigste resultater.....')
cheap_results = '//*[contains(@data-code = "price")]'
driver.find_element_by_xpath(cheap_results).click()
sleep(randint(60,90))
print('indlæser mere.....')
# load_more()
print('starter anden scrap.....')
df_flights_cheap = page_scrape()
df_flights_cheap['sort'] = 'billigst'
sleep(randint(60,80))
print('skifter til de hurtigste resultater.....')
quick_results = '//*[contains(@data-code = "duration")]'
driver.find_element_by_xpath(quick_results).click()
sleep(randint(60,90))
print('indlæser mere.....')
# load_more()
print('starter tredje scrap.....')
df_flights_fast = page_scrape()
df_flights_fast['sort'] = 'hurtigst'
sleep(randint(60,80))
# Gem den nye ramme i en Excel-fil, hvis navn afspejler byer og datoer
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('gemte df.....')
# Man kan følge med i, hvordan forudsigelsen fra hjemmesiden står i forhold til virkeligheden
xp_loading = '//*[contains(@id,"advice")]'
loading = driver.find_element_by_xpath(xp_loading).text
xp_prediction = '//*[contains(@class="info-text")]'
prediction = driver.find_element_by_xpath(xp_prediction).text
print(loading+'n'+prediction)
# nogle gange i variablen loading findes der denne sætning, som senere kan forårsage problemer med at sende mail
# hvis dette er sket - skifter vi den til "Ikke sikker"
weird = '¯_(ツ)_/¯'
if loading == weird:
loading = 'Ikke sikker'
username = 'YOUREMAIL@hotmail.com'
password = 'DIT KODEORD'
server = smtplib.SMTP('smtp.outlook.com', 587)
server.ehlo()
server.starttls()
server.login(username, password)
msg = ('Subject: Flight Scrapernn
Billigste Fly: {}nGennemsnitlig Pris: {}nnAnbefaling: {}nnSlut på besked'.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('sendte mail.....')Jeg har testet dette script med en Outlook-konto (hotmail.com). Jeg har ikke kontrolleret dets funktionalitet med en Gmail-konto; dette mailsystem er meget populært, men der er mange muligheder. Hvis du bruger en Hotmail-konto, skal du blot indsætte dine oplysninger i koden for at få det til at fungere.
Hvis du gerne vil forstå, hvad der præcist sker i de enkelte dele af koden i denne funktion, kan du kopiere dem og eksperimentere med dem. Eksperimentering med koden er den eneste måde at forstå den ordentligt på.
Det færdige system
Nu hvor alt, hvad vi har talt om, er gjort, kan vi skabe en simpel løkke, hvor vores funktioner kaldes. Scriptet beder brugeren om oplysninger om byer og datoer. Når du tester med konstant genstart af scriptet, vil du næppe have lyst til at indtaste disse oplysninger manuelt hver gang, så de relevante linjer kan kommenteres for testens varighed, mens de nedenfor kan afkommenteres, hvor de nødvendige data er hårdkodede.
city_from = input('Fra hvilken by? ')
city_to = input('Hvor til? ')
date_start = input('Søg omkring hvilken afrejsedato? Brug venligst kun formatet ÅÅÅÅ-MM-DD ')
date_end = input('Hvornår skal der returneres? Brug venligst kun formatet ÅÅÅÅ-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('iteration {} blev gennemført @ {}'.format(n, strftime("%Y%m%d-%H%M")))
# Venter 4 timer
sleep(60*60*4)
print('søvn afsluttet.....') Her er, hvordan en testkørsel af scriptet ser ud.

Testkørsel af scriptet
Resumé
Hvis du er nået til dette punkt - tillykke! Nu har du en fungerende web-scraper, selvom jeg allerede kan se mange måder at forbedre den på. For eksempel kan den integreres med Twilio, så den i stedet for e-mails sender tekstbeskeder. Du kan bruge en VPN eller noget lignende for at få resultater fra flere servere samtidig. Der er også det periodisk opståede problem med at kontrollere, om webstedets bruger er en menneske, men dette problem kan også løses. Under alle omstændigheder har du nu et grundlag, som du kan udvide, hvis du ønsker det. For eksempel kunne Excel-filen sendes til brugeren som en vedhæftning i en e-mail.
Kun registrerede brugere kan deltage i undersøgelsen. , please.
Bruger du web-scraping-teknologier?
Ja
Nej
8 brugere har stemt. 1 bruger har undladt at stemme.
Kilde: habr.com
