Python - en assistent for å finne rimelige flybilletter for de som elsker å reise

Forfatteren av artikkelen, som vi publiserer oversettelsen av i dag, sier at målet er å snakke om utviklingen av en nettskraper i Python ved hjelp av Selenium, som søker etter flybillettpriser. Ved søk etter billetter benyttes fleksible datoer (+- 3 dager i forhold til angitte datoer). Skraperen lagrer søkeresultatene i en Excel-fil og sender personen som kjørte søket en e-post med et sammendrag av hva de fant. Målet med dette prosjektet er å hjelpe reisende med å finne de beste tilbudene.

Python - en assistent for å finne rimelige flybilletter for de som elsker å reise

Hvis du, mens du forstår materialet, føler deg fortapt, ta en titt på dette artikkel.

Hva skal vi se etter?

Du står fritt til å bruke systemet som er beskrevet her som du ønsker. For eksempel brukte jeg den til å søke etter helgeturer og billetter til hjembyen min. Hvis du er seriøs med å finne lønnsomme billetter, kan du kjøre skriptet på serveren (enkel serveren, for 130 rubler i måneden, er ganske egnet for dette) og sørg for at den går en eller to ganger om dagen. Søkeresultater vil bli sendt til deg på e-post. I tillegg anbefaler jeg å sette opp alt slik at skriptet lagrer en Excel-fil med søkeresultater i en Dropbox-mappe, som lar deg se slike filer fra hvor som helst og når som helst.

Python - en assistent for å finne rimelige flybilletter for de som elsker å reise
Jeg har ikke funnet takster med feil ennå, men jeg tror det er mulig

Ved søk, som allerede nevnt, brukes en "fleksibel dato"; skriptet finner tilbud som er innen tre dager etter de gitte datoene. Selv om det når skriptet kjøres, søker etter tilbud i bare én retning, er det enkelt å endre det slik at det kan samle inn data om flere flyretninger. Med dens hjelp kan du til og med se etter feilaktige tariffer; slike funn kan være veldig interessante.

Hvorfor trenger du en annen nettskraper?

Da jeg først begynte med nettskraping, var jeg ærlig talt ikke spesielt interessert i det. Jeg ønsket å gjøre flere prosjekter innen prediktiv modellering, finansiell analyse, og muligens innen analyse av emosjonell fargelegging av tekster. Men det viste seg at det var veldig interessant å finne ut hvordan man lager et program som samler inn data fra nettsider. Da jeg fordypet meg i dette emnet, innså jeg at nettskraping er "motoren" til Internett.

Du synes kanskje at dette er en for dristig uttalelse. Men tenk på at Google startet med en nettskraper som Larry Page laget med Java og Python. Google-roboter har utforsket Internett og forsøkt å gi brukerne de beste svarene på spørsmålene deres. Nettskraping har uendelige bruksområder, og selv om du er interessert i noe annet innen Data Science, trenger du noen skrapingferdigheter for å få dataene du trenger å analysere.

Jeg fant noen av teknikkene som brukes her i en fantastisk boka om nettskraping, som jeg nylig anskaffet. Den inneholder mange enkle eksempler og ideer for praktisk anvendelse av det du har lært. I tillegg er det et veldig interessant kapittel om å omgå reCaptcha-sjekker. Dette kom som en nyhet for meg, siden jeg ikke engang visste at det fantes spesialverktøy og til og med hele tjenester for å løse slike problemer.

Liker du å reise?!

På det enkle og ganske ufarlige spørsmålet som stilles i tittelen på denne delen, kan du ofte høre et positivt svar, ledsaget av et par historier fra reisene til personen som det ble spurt til. De fleste av oss er enige om at å reise er en fin måte å fordype seg i nye kulturmiljøer og utvide horisonten. Men spør du noen om de liker å søke etter flybilletter, er jeg sikker på at svaret ikke vil være så positivt. Faktisk kommer Python til hjelp her.

Den første oppgaven vi må løse på veien til å lage et system for å søke informasjon om flybilletter vil være å velge en passende plattform som vi skal hente informasjon fra. Å løse dette problemet var ikke lett for meg, men til slutt valgte jeg Kayak-tjenesten. Jeg prøvde tjenestene til Momondo, Skyscanner, Expedia og noen få andre, men robotbeskyttelsesmekanismene på disse ressursene var ugjennomtrengelige. Etter flere forsøk, der jeg måtte forholde meg til trafikklys, fotgjengeroverganger og sykler, for å prøve å overbevise systemene om at jeg var menneskelig, bestemte jeg meg for at kajakk var best egnet for meg, til tross for at selv om for mange sider er lastet inn. i løpet av kort tid, og kontrollene starter også. Jeg klarte å få boten til å sende forespørsler til nettstedet med intervaller på 4 til 6 timer, og alt fungerte bra. Fra tid til annen oppstår det vanskeligheter når du jobber med Kayak, men hvis de begynner å plage deg med sjekker, må du enten håndtere dem manuelt og deretter starte boten, eller vente noen timer og sjekkene skal stoppe. Om nødvendig kan du enkelt tilpasse koden for en annen plattform, og hvis du gjør det kan du rapportere det i kommentarfeltet.

Hvis du nettopp har begynt med nettskraping og ikke vet hvorfor noen nettsteder sliter med det, så før du starter ditt første prosjekt på dette området, gjør deg selv en tjeneste og gjør et Google-søk på ordene "nettskrapingetikette" . Eksperimentene dine kan avsluttes raskere enn du tror hvis du gjør nettskraping uklokt.

Komme i gang

Her er en generell oversikt over hva som vil skje i nettskraperkoden vår:

  • Importer de nødvendige bibliotekene.
  • Åpne en Google Chrome-fane.
  • Ring en funksjon som starter boten, og gir den byene og datoene som skal brukes når du søker etter billetter.
  • Denne funksjonen tar de første søkeresultatene, sortert etter beste, og klikker på en knapp for å laste inn flere resultater.
  • En annen funksjon samler inn data fra hele siden og returnerer en dataramme.
  • De to foregående trinnene utføres ved hjelp av sorteringstyper etter billettpris (billig) og etter flyhastighet (raskeste).
  • Brukeren av scriptet får tilsendt en e-post som inneholder en oversikt over billettpriser (billigste billetter og gjennomsnittspris), og en dataramme med informasjon sortert etter de tre ovennevnte indikatorene lagres som en Excel-fil.
  • Alle handlingene ovenfor utføres i en syklus etter en spesifisert tidsperiode.

Det skal bemerkes at hvert Selenium-prosjekt starter med en nettdriver. jeg bruker Chromedriver, Jeg jobber med Google Chrome, men det finnes andre alternativer. PhantomJS og Firefox er også populære. Etter å ha lastet ned driveren, må du plassere den i den aktuelle mappen, og dette fullfører forberedelsen til bruken. De første linjene i skriptet åpner en ny Chrome-fane.

Husk at i historien min prøver jeg ikke å åpne nye horisonter for å finne gode tilbud på flybilletter. Det finnes mye mer avanserte metoder for å søke etter slike tilbud. Jeg vil bare tilby lesere av dette materialet en enkel, men praktisk måte å løse dette problemet på.

Her er koden vi snakket om ovenfor.

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

# Используйте тут ваш путь к chromedriver!
chromedriver_path = 'C:/{YOUR PATH HERE}/chromedriver_win32/chromedriver.exe'

driver = webdriver.Chrome(executable_path=chromedriver_path) # Этой командой открывается окно Chrome
sleep(2)

I begynnelsen av koden kan du se pakkeimportkommandoene som brukes gjennom hele prosjektet vårt. Så, randint brukes til å få boten til å "sovne" i et tilfeldig antall sekunder før du starter en ny søkeoperasjon. Vanligvis kan ikke en eneste bot klare seg uten dette. Hvis du kjører koden ovenfor, åpnes et Chrome-vindu som roboten vil bruke til å jobbe med nettsteder.

La oss gjøre et lite eksperiment og åpne nettstedet kayak.com i et eget vindu. Vi velger byen vi skal fly fra, og byen vi ønsker å komme til, samt flydatoene. Når du velger datoer, sørg for at området +-3 dager brukes. Jeg skrev koden under hensyntagen til hva nettstedet produserer som svar på slike forespørsler. Hvis du for eksempel trenger å søke etter billetter kun for spesifiserte datoer, er det stor sannsynlighet for at du må endre bot-koden. Når jeg snakker om koden, gir jeg passende forklaringer, men hvis du føler deg forvirret, gi meg beskjed.

Klikk nå på søkeknappen og se på lenken i adressefeltet. Den skal ligne på lenken jeg bruker i eksemplet nedenfor der variabelen er deklarert kayak, som lagrer URL-en, og metoden brukes get web-driver. Etter å ha klikket på søkeknappen, skal resultatene vises på siden.

Python - en assistent for å finne rimelige flybilletter for de som elsker å reise
Da jeg brukte kommandoen get mer enn to eller tre ganger i løpet av noen få minutter ble jeg bedt om å fullføre verifiseringen ved å bruke reCaptcha. Du kan bestå denne kontrollen manuelt og fortsette å eksperimentere til systemet bestemmer seg for å kjøre en ny sjekk. Da jeg testet skriptet virket det som om den første søkeøkten alltid gikk knirkefritt, så hvis du ville eksperimentere med koden, måtte du bare periodisk sjekke manuelt og la koden kjøre, med lange intervaller mellom søkeøktene. Og hvis du tenker på det, er det usannsynlig at en person trenger informasjon om billettpriser mottatt med 10-minutters intervaller mellom søkeoperasjoner.

Arbeide med en side ved hjelp av XPath

Så vi åpnet et vindu og lastet inn siden. For å få priser og annen informasjon, må vi bruke XPath-teknologi eller CSS-velgere. Jeg bestemte meg for å holde meg til XPath og følte ikke behov for å bruke CSS-velgere, men det er fullt mulig å jobbe på den måten. Det kan være vanskelig å navigere rundt på en side ved hjelp av XPath, og selv om du bruker teknikkene jeg beskrev i dette artikkel, som innebar å kopiere de tilsvarende identifikatorene fra sidekoden, innså jeg at dette faktisk ikke er den optimale måten å få tilgang til de nødvendige elementene. Forresten, i dette Boken gir en utmerket beskrivelse av det grunnleggende om arbeid med sider ved hjelp av XPath- og CSS-velgere. Slik ser den tilsvarende webdrivermetoden ut.

Python - en assistent for å finne rimelige flybilletter for de som elsker å reise
Så la oss fortsette å jobbe med boten. La oss bruke programmets muligheter til å velge de billigste billettene. I det følgende bildet er XPath-velgerkoden uthevet i rødt. For å se koden må du høyreklikke på sideelementet du er interessert i og velge Inspiser-kommandoen fra menyen som vises. Denne kommandoen kan kalles for forskjellige sideelementer, hvis kode vil bli vist og uthevet i kodeviseren.

Python - en assistent for å finne rimelige flybilletter for de som elsker å reise
Se sidekode

For å finne bekreftelse på resonnementet mitt om ulempene ved å kopiere velgere fra kode, vær oppmerksom på følgende funksjoner.

Dette er hva du får når du kopierer koden:

//*[@id="wtKI-price_aTab"]/div[1]/div/div/div[1]/div/span/span

For å kopiere noe slikt, må du høyreklikke på kodedelen du er interessert i og velge kommandoen Kopier > Kopier XPath fra menyen som vises.

Her er det jeg brukte for å definere Billigste-knappen:

cheap_results = ‘//a[@data-code = "price"]’

Python - en assistent for å finne rimelige flybilletter for de som elsker å reise
Kopier kommando > Kopier XPath

Det er ganske åpenbart at det andre alternativet ser mye enklere ut. Når den brukes, søker den etter et element a som har attributtet data-code, lik price. Når du bruker det første alternativet, søkes elementet id som er lik wtKI-price_aTab, og XPath-banen til elementet ser slik ut /div[1]/div/div/div[1]/div/span/span. Et XPath-søk som dette til en side vil gjøre susen, men bare én gang. Det kan jeg si akkurat nå id endres neste gang siden lastes inn. Karaktersekvens wtKI endres dynamisk hver gang siden lastes inn, så koden som bruker den vil være ubrukelig etter neste sideinnlasting. Så ta deg tid til å forstå XPath. Denne kunnskapen vil tjene deg godt.

Det skal imidlertid bemerkes at kopiering av XPath-velgere kan være nyttig når du arbeider med ganske enkle nettsteder, og hvis du er komfortabel med dette, er det ingenting galt med det.

La oss nå tenke på hva du skal gjøre hvis du trenger å få alle søkeresultatene på flere linjer, inne i en liste. Veldig enkelt. Hvert resultat er inne i et objekt med en klasse resultWrapper. Lasting av alle resultatene kan gjøres i en løkke som ligner på den som er vist nedenfor.

Det skal bemerkes at hvis du forstår det ovenfor, bør du enkelt forstå det meste av koden som vi vil analysere. Når denne koden kjøres, får vi tilgang til det vi trenger (faktisk elementet som resultatet er pakket inn i) ved å bruke en slags banespesifiserende mekanisme (XPath). Dette gjøres for å få teksten til elementet og plassere den i et objekt som data kan leses fra (først brukt flight_containers, deretter - flights_list).

Python - en assistent for å finne rimelige flybilletter for de som elsker å reise
De tre første linjene vises og vi kan tydelig se alt vi trenger. Vi har imidlertid mer interessante måter å innhente informasjon på. Vi må ta data fra hvert element separat.

Kom på jobb!

Den enkleste måten å skrive en funksjon på er å laste inn flere resultater, så det er der vi starter. Jeg ønsker å maksimere antall flyreiser som programmet mottar informasjon om, uten å vekke mistanker i tjenesten som fører til en inspeksjon, så jeg klikker på Last flere resultater-knappen én gang hver gang siden vises. I denne koden bør du ta hensyn til blokken try, som jeg la til fordi knappen noen ganger ikke laster ordentlig. Hvis du også støter på dette, kommenter ut anrop til denne funksjonen i funksjonskoden start_kayak, som vi skal se på 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:
        pass

Nå, etter en lang analyse av denne funksjonen (noen ganger kan jeg la meg rive med), er vi klare til å erklære en funksjon som vil skrape siden.

Jeg har allerede samlet det meste av det som trengs i følgende funksjon kalt page_scrape. Noen ganger kombineres de returnerte banedataene, så jeg bruker en enkel metode for å skille dem. For eksempel når jeg bruker variabler for første gang section_a_list и section_b_list. Vår funksjon returnerer en dataramme flights_df, gjør dette at vi kan skille resultatene som er oppnådd fra ulike datasorteringsmetoder og senere 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 prøvde å navngi variablene slik at koden skulle være forståelig. Husk at variabler som starter med a tilhører den første etappen av stien, og b - til den andre. La oss gå videre til neste funksjon.

Støttemekanismer

Vi har nå en funksjon som lar oss laste inn flere søkeresultater og en funksjon for å behandle disse resultatene. Denne artikkelen kunne ha sluttet her, siden disse to funksjonene gir alt du trenger for å skrape sider som du kan åpne selv. Men vi har ennå ikke vurdert noen av hjelpemekanismene som er diskutert ovenfor. Dette er for eksempel koden for å sende e-post og en del andre ting. Alt dette finner du i funksjonen start_kayak, som vi nå skal vurdere.

For at denne funksjonen skal fungere, trenger du informasjon om byer og datoer. Ved å bruke denne informasjonen danner den en lenke i en variabel kayak, som brukes til å ta deg til en side som vil inneholde søkeresultater sortert etter deres beste samsvar med søket. Etter første skrapingsøkt vil vi jobbe med prisene i tabellen øverst på siden. Vi vil nemlig finne minste billettpris og gjennomsnittspris. Alt dette, sammen med spådommen utstedt av nettstedet, vil bli sendt på e-post. På siden skal den tilsvarende tabellen være i øvre venstre hjørne. Arbeid med denne tabellen kan forresten forårsake en feil ved søk med eksakte datoer, siden tabellen i dette tilfellet ikke vises på siden.

def start_kayak(city_from, city_to, date_start, date_end):
    """City codes - it's the IATA codes!
    Date format -  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))
    
    # иногда появляется всплывающее окно, для проверки на это и его закрытия можно воспользоваться блоком 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('loading more.....')
    
#     load_more()
    
    print('starting first scrape.....')
    df_flights_best = page_scrape()
    df_flights_best['sort'] = 'best'
    sleep(randint(60,80))
    
    # Возьмём самую низкую цену из таблицы, расположенной в верхней части страницы
    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('switching to cheapest results.....')
    cheap_results = '//a[@data-code = "price"]'
    driver.find_element_by_xpath(cheap_results).click()
    sleep(randint(60,90))
    print('loading more.....')
    
#     load_more()
    
    print('starting second scrape.....')
    df_flights_cheap = page_scrape()
    df_flights_cheap['sort'] = 'cheap'
    sleep(randint(60,80))
    
    print('switching to quickest results.....')
    quick_results = '//a[@data-code = "duration"]'
    driver.find_element_by_xpath(quick_results).click()  
    sleep(randint(60,90))
    print('loading more.....')
    
#     load_more()
    
    print('starting third scrape.....')
    df_flights_fast = page_scrape()
    df_flights_fast['sort'] = 'fast'
    sleep(randint(60,80))
    
    # Сохранение нового фрейма в Excel-файл, имя которого отражает города и даты
    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('saved df.....')
    
    # Можно следить за тем, как прогноз, выдаваемый сайтом, соотносится с реальностью
    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)
    
    # иногда в переменной loading оказывается эта строка, которая, позже, вызывает проблемы с отправкой письма
    # если это прозошло - меняем её на "Not Sure"
    weird = '¯_(ツ)_/¯'
    if loading == weird:
        loading = 'Not sure'
    
    username = '[email protected]'
    password = 'YOUR PASSWORD'

    server = smtplib.SMTP('smtp.outlook.com', 587)
    server.ehlo()
    server.starttls()
    server.login(username, password)
    msg = ('Subject: Flight Scrapernn
Cheapest Flight: {}nAverage Price: {}nnRecommendation: {}nnEnd of message'.format(matrix_min, matrix_avg, (loading+'n'+prediction)))
    message = MIMEMultipart()
    message['From'] = '[email protected]'
    message['to'] = '[email protected]'
    server.sendmail('[email protected]', '[email protected]', msg)
    print('sent email.....')

Jeg testet dette skriptet med en Outlook-konto (hotmail.com). Jeg har ikke testet det for å fungere riktig med en Gmail-konto, dette e-postsystemet er ganske populært, men det er mange mulige alternativer. Hvis du bruker en Hotmail-konto, trenger du bare å legge inn dataene dine i koden for at alt skal fungere.

Hvis du vil forstå nøyaktig hva som gjøres i bestemte deler av koden for denne funksjonen, kan du kopiere dem og eksperimentere med dem. Å eksperimentere med koden er den eneste måten å virkelig forstå den på.

Klart system

Nå som vi har gjort alt vi snakket om, kan vi lage en enkel sløyfe som kaller opp funksjonene våre. Skriptet ber om data fra brukeren om byer og datoer. Når du tester med konstant omstart av skriptet, er det lite sannsynlig at du vil legge inn disse dataene manuelt hver gang, så de tilsvarende linjene, for testtidspunktet, kan kommenteres ut ved å fjerne kommentarene under dem, der dataene som trengs av skriptet er hardkodet.

city_from = input('From which city? ')
city_to = input('Where to? ')
date_start = input('Search around which departure date? Please use YYYY-MM-DD format only ')
date_end = input('Return when? Please use YYYY-MM-DD format only ')

# 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 {} was complete @ {}'.format(n, strftime("%Y%m%d-%H%M")))
    
    # Ждём 4 часа
    sleep(60*60*4)
    print('sleep finished.....')

Slik ser en testkjøring av skriptet ut.
Python - en assistent for å finne rimelige flybilletter for de som elsker å reise
Testkjøring av skriptet

Resultater av

Hvis du har kommet så langt, gratulerer! Du har nå en fungerende nettskraper, selv om jeg allerede kan se mange måter å forbedre den på. Den kan for eksempel integreres med Twilio slik at den sender tekstmeldinger i stedet for e-post. Du kan bruke en VPN eller noe annet for å motta resultater fra flere servere samtidig. Det er også et periodisk problem med å sjekke brukeren av nettstedet for å se om han er en person, men dette problemet kan også løses. Uansett, nå har du en base som du kan utvide hvis du ønsker det. Pass for eksempel på at en Excel-fil sendes til brukeren som et vedlegg til en e-post.

Python - en assistent for å finne rimelige flybilletter for de som elsker å reise

Kun registrerte brukere kan delta i undersøkelsen. Logg inn, vær så snill.

Bruker du nettskrapingsteknologier?

  • Ja

  • Ikke

8 brukere stemte. 1 bruker avsto.

Kilde: www.habr.com

Legg til en kommentar