Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea

Artikuluaren egileak, gaur argitaratzen dugun itzulpena, dio bere helburua Selenium erabiliz Python-en web scraper baten garapenari buruz hitz egitea dela, hegazkin-txartelen prezioak bilatzen dituena. Sarrerak bilatzerakoan, data malguak erabiltzen dira (+- 3 egun zehaztutako datei dagokienez). Scraper-ek bilaketa-emaitzak Excel fitxategi batean gordetzen ditu eta bilaketa egin duen pertsonari mezu elektroniko bat bidaltzen dio aurkitutakoaren laburpen batekin. Proiektu honen helburua bidaiariei eskaintzarik onenak aurkitzen laguntzea da.

Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea

Materiala ulertzen duzun bitartean galduta sentitzen bazara, begiratu hau Artikulu.

Zer bilatuko dugu?

Hemen azaltzen den sistema nahi duzun moduan erabiltzeko librea zara. Adibidez, nire jaioterrirako asteburuko birak eta sarrerak bilatzeko erabili nuen. Txartel errentagarriak bilatzeko serio bazara, script-a exekutatu dezakezu zerbitzarian (erraza zerbitzaria, 130 errublo hilean, nahiko egokia da horretarako) eta ziurtatu egunean behin edo bitan exekutatzen dela. Bilaketaren emaitzak posta elektronikoz bidaliko zaizkizu. Horrez gain, dena konfiguratzea gomendatzen dut, horrela scriptak Excel fitxategi bat gorde dezan bilaketa-emaitzekin Dropbox karpeta batean, fitxategi horiek edozein lekutatik eta edonoiz ikusteko aukera emango dizuna.

Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea
Oraindik ez ditut akatsak dituzten tarifak aurkitu, baina posible dela uste dut

Bilatzerakoan, esan bezala, "data malgua" erabiltzen da; gidoiak emandako datatik hiru eguneko epean dauden eskaintzak aurkitzen ditu. Scripta exekutatzen denean, eskaintzak norabide bakarrean bilatzen baditu ere, erraza da aldatzea, hainbat hegaldi norabidetako datuak bil ditzan. Bere laguntzarekin, tarifa okerrak ere bilatu ditzakezu; horrelako aurkikuntzak oso interesgarriak izan daitezke.

Zergatik behar duzu beste web scraper bat?

Web scraping hasi nintzenean, egia esan, ez nintzen bereziki interesatzen. Proiektu gehiago egin nahi nituen eredu prediktiboaren, finantza-analisiaren alorrean eta, beharbada, testuen kolore emozionala aztertzearen alorrean. Baina konturatu zen oso interesgarria zela webguneetatik datuak biltzen dituen programa bat nola sortu asmatzea. Gai honetan sakondu ahala, web scraping Interneten "motorra" dela konturatu nintzen.

Adierazpen ausartegia dela pentsa dezakezu. Baina kontuan hartu Google Larry Pagek Java eta Python erabiliz sortu zuen web scraper batekin hasi zela. Google-ko robotak Internet arakatzen aritu dira, erabiltzaileei beren galderei erantzun onenak eman nahian. Web scraping erabilera amaigabeak ditu, eta Data Science-n beste zerbait interesatzen bazaizu ere, scraping trebetasun batzuk beharko dituzu aztertu behar dituzun datuak lortzeko.

Hemen erabiltzen diren teknika batzuk zoragarrian aurkitu ditut liburua web scraping-ari buruz, duela gutxi eskuratu dudana. Ikasitakoa praktikoki aplikatzeko adibide eta ideia erraz asko ditu. Horrez gain, oso kapitulu interesgarri bat dago reCaptcha egiaztapenak saihesteko. Hau albiste gisa etorri zitzaidan, ez bainekien horrelako arazoak konpontzeko tresna bereziak eta zerbitzu osoak zeudenik ere.

Bidaiatzea gustatzen zaizu?!

Atal honen izenburuan planteatzen den galdera soil eta kaltegabeari, sarritan erantzun positibo bat entzun daiteke, galdetu zaion pertsonaren bidaietako istorio pare batez lagunduta. Gehienok onartuko genuke bidaiatzea ingurune kultural berrietan murgiltzeko eta zure horizonteak zabaltzeko modu bikaina dela. Hala ere, norbaiti hegazkin-txartelak bilatzea gustatzen zaion galdetzen badiozu, ziur nago erantzuna ez dela hain positiboa izango. Izan ere, Python gure laguntzara dator hemen.

Hegazkin-txartelei buruzko informazioa bilatzeko sistema sortzeko bidean ebatzi behar dugun lehenengo zeregina plataforma egoki bat hautatzea izango da, bertatik informazioa hartuko dugun. Arazo hau konpontzea ez zen erraza izan niretzat, baina azkenean Kayak zerbitzua aukeratu nuen. Momondo, Skyscanner, Expedia eta beste batzuen zerbitzuak probatu nituen, baina baliabide horien roboten babes-mekanismoak zeharkaezinak ziren. Hainbat saiakera egin ondoren, eta horietan semaforoei, oinezkoen pasabideei eta bizikletei aurre egin behar izan nien, sistemak gizakia nintzela konbentzitu nahian, Kayak niretzat egokiena zela erabaki nuen, nahiz eta orrialde gehiegi kargatu. denbora gutxian, eta kontrolak ere hasten dira. Botak gunera eskaerak bidaltzea lortu nuen 4 eta 6 ordu arteko tarteetan, eta dena ondo funtzionatu zuen. Noizean behin, zailtasunak sortzen dira Kayak-ekin lan egitean, baina egiaztapenekin traba egiten hasten bazaituzte, eskuz landu eta bot-a abiarazi behar duzu, edo ordu batzuk itxaron eta egiaztapenak gelditu beharko dira. Beharrezkoa izanez gero, erraz molda dezakezu kodea beste plataforma baterako, eta hala eginez gero, iruzkinetan jakinarazi dezakezu.

Web scraping-ekin hasi berria bazara eta webgune batzuek zergatik borrokatzen duten ez badakizu, orduan zure lehenengo proiektua hasi aurretik, egin mesede bat eta egin Google bilaketa "web scraping etiquette" hitzetan. . Baliteke zure esperimentuak uste baino lehenago amaitzea web-arazketak gaizki egiten badituzu.

Pizten

Hona hemen gure web scraper kodean gertatuko denaren ikuspegi orokorra:

  • Inportatu beharrezko liburutegiak.
  • Google Chrome fitxa bat irekitzea.
  • Deitu bot-a abiarazten duen funtzio bati, sarrerak bilatzeko orduan erabiliko diren hiriak eta datak pasatuz.
  • Funtzio honek lehen bilaketa-emaitzak hartzen ditu, hoberen arabera ordenatuta, eta botoi batean klik egiten du emaitza gehiago kargatzeko.
  • Beste funtzio batek orrialde osoko datuak biltzen ditu eta datu-markoa itzultzen du.
  • Aurreko bi urratsak txartelaren prezioaren arabera (merkeak) eta hegaldien abiaduraren arabera (azkarrenak) sailkatzeko motak erabiltzen dira.
  • Gidoiaren erabiltzaileari mezu elektroniko bat bidaltzen zaio, sarreren prezioen laburpena (sarrera merkeenak eta batez besteko prezioa), eta goian aipatutako hiru adierazleen arabera ordenatutako informazioa duen datu-markoa Excel fitxategi gisa gordetzen da.
  • Aurreko ekintza guztiak ziklo batean egiten dira denbora-tarte jakin baten ondoren.

Kontuan izan behar da Selenium proiektu bakoitza web kontrolatzaile batekin hasten dela. erabiltzen dut Chromedriver, Google Chromerekin lan egiten dut, baina badaude beste aukera batzuk. PhantomJS eta Firefox ere ezagunak dira. Gidaria deskargatu ondoren, dagokion karpetan jarri behar duzu, eta honek erabilerarako prestaketa amaituko du. Gure gidoiaren lehen lerroek Chrome fitxa berri bat irekitzen dute.

Gogoan izan nire istorioan ez naizela horizonte berriak irekitzen saiatzen aire-txarteletan eskaintza bikainak aurkitzeko. Halako eskaintzak bilatzeko metodo askoz aurreratuagoak daude. Material honen irakurleei arazo hau konpontzeko modu sinple baina praktiko bat eskaini nahi diet.

Hona hemen goian aipatu dugun kodea.

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)

Kodearen hasieran gure proiektuan zehar erabiltzen diren paketeak inportatzeko komandoak ikus ditzakezu. Beraz, randint bilaketa-eragiketa berri bat hasi aurretik ausazko segundo kopuru batean bot-a "loak hartzeko" erabiltzen da. Normalean, bot bakar batek ezin du hori gabe egin. Goiko kodea exekutatzen baduzu, Chrome leiho bat irekiko da, bot-ak guneekin lan egiteko erabiliko duena.

Egin dezagun esperimentu txiki bat eta ireki kayak.com webgunea beste leiho batean. Hegan egingo dugun hiria hautatuko dugu, eta iritsi nahi dugun hiria, baita hegaldien datak ere. Datak aukeratzerakoan, ziurtatu +-3 eguneko tartea erabiltzen dela. Halako eskaerei erantzunez guneak ekoizten duena kontuan hartuta idatzi nuen kodea. Adibidez, data zehatzetarako soilik txartelak bilatu behar badituzu, orduan bot kodea aldatu behar izateko probabilitate handia dago. Kodeari buruz hitz egiten dudanean, azalpen egokiak ematen ditut, baina nahastuta sentitzen bazara, jakinarazi iezadazu.

Orain egin klik bilaketa botoian eta begiratu helbide-barrako esteka. Aldagaia deklaratzen den beheko adibidean erabiltzen dudan estekaren antzekoa izan beharko luke kayak, URLa gordetzen duena, eta metodoa erabiltzen da get web gidaria. Bilaketa botoian klik egin ondoren, emaitzak orrialdean agertu beharko lirateke.

Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea
Komandoa erabili nuenean get Bi edo hiru aldiz baino gehiago minutu gutxiren buruan, reCaptcha erabiliz egiaztapena osatzeko eskatu zidaten. Egiaztapen hau eskuz pasa dezakezu eta esperimentatzen jarraitu sistemak egiaztapen berri bat egitea erabaki arte. Script-a probatu nuenean, lehenengo bilaketa saioa beti ondo joan zela zirudien, beraz, kodearekin esperimentatu nahi bazenu, aldian-aldian eskuz egiaztatu eta kodea exekutatzen utzi beharko zenuke, bilaketa-saioen arteko tarte luzeak erabiliz. Eta, pentsatuz gero, pertsona batek nekez beharko du bilaketa-eragiketen artean 10 minutuko tartean jasotako sarreren prezioei buruzko informazioa.

XPath erabiliz orrialde batekin lan egitea

Beraz, leiho bat ireki eta gunea kargatu genuen. Prezioak eta bestelako informazioa lortzeko, XPath teknologia edo CSS hautatzaileak erabili behar ditugu. XPath-ekin jarraitzea erabaki nuen eta ez nuen CSS hautatzaileak erabiltzeko beharrik sentitu, baina nahiko posible da horrela lan egitea. XPath erabiliz orrialde batean nabigatzea zaila izan daiteke, eta deskribatu ditudan teknikak erabiltzen badituzu ere hau artikuluan, orrialdearen kodetik dagozkien identifikatzaileak kopiatzea suposatzen zuena, konturatu nintzen hori ez dela beharrezko elementuetara sartzeko modurik egokiena. Bide batez, barruan hau Liburuak XPath eta CSS hautatzaileak erabiliz orrialdeekin lan egiteko oinarrien deskribapen bikaina eskaintzen du. Hau da dagokion web kontrolatzailearen metodoaren itxura.

Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea
Beraz, jarrai dezagun botarekin lanean. Erabili ditzagun programaren gaitasunak sarrera merkeenak hautatzeko. Hurrengo irudian, XPath hautatzailearen kodea gorriz nabarmenduta dago. Kodea ikusteko, eskuineko botoiarekin klik egin behar duzu interesatzen zaizun orriaren elementuan eta hautatu Ikuskatu komandoa agertzen den menuan. Komando hau orri-elementu desberdinetarako dei daiteke, eta horien kodea kode-ikustailean bistaratuko eta nabarmenduko da.

Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea
Ikusi orriaren kodea

Hautatzaileak kodetik kopiatzearen desabantailei buruzko nire arrazoibidearen berrespena aurkitzeko, arreta jarri ondorengo ezaugarriei.

Hau da kodea kopiatzen duzunean lortzen duzuna:

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

Horrelako zerbait kopiatzeko, interesatzen zaizun kodearen atalean eskuineko botoiarekin klik egin behar duzu eta agertzen den menuan Kopiatu > Kopiatu XPath komandoa hautatu.

Hona hemen Merkeena botoia definitzeko erabili dudana:

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

Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea
Kopiatu komandoa > Kopiatu XPath

Nahiko bistakoa da bigarren aukera askoz sinpleagoa dela. Erabiltzen denean, atributua duen a elementu bat bilatzen du data-codeberdina price. Lehenengo aukera erabiltzean, elementua bilatzen da id berdina dena wtKI-price_aTab, eta elementurako XPath bidea itxura du /div[1]/div/div/div[1]/div/span/span. Orrialde bati honelako XPath kontsulta batek trikimailua egingo du, baina behin bakarrik. Oraintxe esan dezaket hori id orrialdea kargatzen den hurrengoan aldatuko da. Pertsonaien sekuentzia wtKI orria kargatzen den bakoitzean modu dinamikoan aldatzen da, beraz, erabiltzen duen kodea alferrikakoa izango da hurrengo orrialdea birkargatu ondoren. Beraz, hartu denbora pixka bat XPath ulertzeko. Ezagutza honek ondo balioko dizu.

Hala ere, kontuan izan behar da XPath hautatzaileak kopiatzea erabilgarria izan daitekeela gune nahiko sinpleekin lan egiten denean, eta honekin eroso bazaude, ez dago ezer txarrik.

Orain pentsa dezagun zer egin bilaketaren emaitza guztiak hainbat lerrotan lortu behar badituzu, zerrenda baten barruan. Oso sinplea. Emaitza bakoitza klase bat duen objektu baten barruan dago resultWrapper. Emaitza guztiak kargatzea behean agertzen denaren antzeko begizta batean egin daiteke.

Kontuan izan behar da goikoa ulertzen baduzu, aztertuko dugun kode gehiena erraz ulertu behar duzula. Kode hau exekutatzen den heinean, behar duguna (hain zuzen ere, emaitza bilduta dagoen elementura) sartzen gara bide-zehaztapen mekanismoren bat erabiliz (XPath). Elementuaren testua lortzeko eta datuak irakur daitezkeen objektu batean kokatzeko egiten da (lehen erabilitakoa). flight_containers, orduan - flights_list).

Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea
Lehenengo hiru lerroak bistaratzen dira eta behar dugun guztia argi eta garbi ikus dezakegu. Hala ere, informazioa lortzeko modu interesgarriagoak ditugu. Elementu bakoitzeko datuak banan-banan hartu behar ditugu.

Hasi lanari!

Funtzio bat idazteko modurik errazena emaitza gehigarriak kargatzea da, hortik hasiko gara. Programak informazioa jasotzen duen hegaldi kopurua maximizatu nahiko nuke, ikuskapen bat dakarten zerbitzuan susmorik sortu gabe, beraz, orria bistaratzen den bakoitzean Kargatu emaitza gehiago botoian klik egiten dut. Kode honetan, blokeari arreta jarri behar diozu try, gehitu dudana batzuetan botoia ez delako behar bezala kargatzen. Hau ere aurkitzen baduzu, iruzkin ezazu funtzio honetarako deiak funtzioaren kodean start_kayak, jarraian aztertuko duguna.

# Загрузка большего количества результатов для того, чтобы максимизировать объём собираемых данных
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

Orain, funtzio honen analisi luzea egin ondoren (batzuetan eraman dezaket), orria scrape egingo duen funtzio bat deklaratzeko prest gaude.

Dagoeneko bildu dut deitzen den hurrengo funtzioan behar dena page_scrape. Batzuetan, itzulitako bide-datuak konbinatzen dira, beraz, metodo sinple bat erabiltzen dut bereizteko. Adibidez, aldagaiak lehen aldiz erabiltzen ditudanean section_a_list и section_b_list. Gure funtzioak datu-markoa itzultzen du flights_df, horri esker, datuak ordenatzeko metodo ezberdinetatik lortutako emaitzak bereiztu eta gero konbinatu.

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

Aldagaiei izena jartzen saiatu nintzen, kodea ulergarria izan zedin. Gogoratu aldagaiak hasten direla a bidearen lehen etapakoak dira, eta b - bigarrenari. Joan gaitezen hurrengo funtziora.

Laguntza-mekanismoak

Orain bilaketa-emaitza osagarriak kargatzeko aukera ematen digun funtzio bat dugu eta emaitza horiek prozesatzeko funtzio bat. Artikulu hau hemen amaitu zitekeen, bi funtzio hauek zuk zeuk ireki ditzakezun orriak arakatzeko behar duzun guztia eskaintzen baitute. Baina oraindik ez ditugu kontuan hartu goian aipaturiko mekanismo laguntzaile batzuk. Adibidez, hau da mezu elektronikoak eta beste gauza batzuk bidaltzeko kodea. Hau guztia funtzioan aurki daiteke start_kayak, orain kontuan hartuko duguna.

Funtzio honek funtziona dezan, hiriei eta datei buruzko informazioa behar duzu. Informazio hori erabiliz, aldagai batean esteka bat osatzen du kayak, bilaketa-emaitzak kontsultarekin bat datorren onenaren arabera ordenatuta izango dituen orrialde batera eramateko erabiltzen dena. Lehenengo scraping saioaren ostean, orriaren goiko aldean dagoen taulako prezioekin lan egingo dugu. Hots, sarreraren gutxieneko prezioa eta batez besteko prezioa aurkituko ditugu. Hori guztia, webguneak emandako iragarpenarekin batera, posta elektronikoz bidaliko da. Orrialdean, dagokion taula goiko ezkerreko izkinan egon behar du. Taula honekin lan egiteak, bide batez, akats bat sor dezake data zehatzak erabiliz bilaketak egitean, kasu honetan taula ez baita orrialdean bistaratzen.

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.....')

Script hau Outlook kontu bat erabiliz probatu dut (hotmail.com). Ez dut Gmail kontu batekin behar bezala funtzionatzen duen probatu, posta elektronikoko sistema hau nahiko ezaguna da, baina aukera asko daude. Hotmail kontu bat erabiltzen baduzu, dena funtziona dezan, zure datuak kodean sartu besterik ez duzu behar.

Funtzio honen kodearen atal zehatzetan zer egiten ari den ulertu nahi baduzu, kopiatu eta haiekin esperimentatu dezakezu. Kodearekin esperimentatzea da benetan ulertzeko modu bakarra.

Prest sistema

Orain hitz egin dugun guztia egin dugunean, gure funtzioak deitzen dituen begizta sinple bat sor dezakegu. Scriptak erabiltzaileari hiriei eta datei buruzko datuak eskatzen dizkio. Scripta etengabe berrabiaraziz probatzen duzunean, nekez sartu nahi izango dituzu datu hauek aldi bakoitzean, beraz, dagozkien lerroak, probak irauten duen bitartean, iruzkinak egin daitezke azpian daudenak iruzkinak kenduz, zeinetan beharrezkoak diren datuak. gidoia gogor kodetuta dago.

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.....')

Hau da scriptaren proba-exekuzio baten itxura.
Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea
Gidoiaren proba-exekuzioa

Emaitzak

Honaino iritsi bazara, zorionak! Orain funtzionatzen duen web scraper bat duzu, nahiz eta dagoeneko hobetu ahal izateko modu asko ikusten ditudan. Esaterako, Twilio-rekin integra daiteke, mezu elektronikoen ordez testu-mezuak bidal ditzan. VPN bat edo beste zerbait erabil dezakezu hainbat zerbitzaritako emaitzak aldi berean jasotzeko. Aldian-aldian sortzen den arazo bat ere badago gunearen erabiltzailea pertsona bat den egiaztatzeko, baina arazo hau ere konpondu daiteke. Nolanahi ere, orain nahi izanez gero zabal dezakezun oinarri bat duzu. Adibidez, ziurtatu Excel fitxategi bat erabiltzaileari mezu elektroniko baten eranskin gisa bidaltzen zaiola.

Python - bidaiatzea maite dutenentzat hegazkin-txartel merkeak aurkitzeko laguntzailea

Erregistratutako erabiltzaileek soilik parte hartu dezakete inkestan. Hasi saioa, mesedez.

Web scraping teknologiak erabiltzen al dituzu?

  • Bai

  • No

8 erabiltzailek eman dute botoa. Erabiltzaile 1 abstenitu egin zen.

Iturria: www.habr.com

Gehitu iruzkin berria