Autor článku, jehož překlad dnes publikujeme, říká, že jeho cílem je popsat vývoj webového scrapperu v Pythonu pomocí Selenium, který vyhledává ceny letenek. Při hledání letenek se používají flexibilní data (+- 3 dny od zadaných dat). Scrapper ukládá výsledky vyhledávání do Excel souboru a posílá email osobě, která jej spustila, se souhrnnými informacemi o tom, co se mu podařilo najít. Cílem tohoto projektu je pomoci cestovatelům najít nejvýhodnější nabídky.
Pokud se při studiu materiálu cítíte ztraceni, podívejte se na článok.
Co budeme hledat?
Můžete systém popsaný zde použít, jak chcete. Já například jej využíval k hledání víkendových zájezdů a letenek do svého rodného města. Pokud se vážně zaměřujete na hledání výhodných letenek, můžete spustit skript na serveru (jednoduchý , za 130 korun měsíčně, je k tomu zcela vhodný) a nastavit ho tak, aby se spouštěl jednou až dvakrát denně. Výsledky vyhledávání k vám budou chodit emailem. Dále doporučuji nastavit vše tak, aby skript ukládal Excel soubor s výsledky vyhledávání do složky Dropbox, což vám umožní prohlížet tyto soubory odkudkoliv a kdykoliv.

Dosud jsem nenalezl chytré tarify, ale domnívám se, že to je možné.
Při hledání, jak již bylo řečeno, se používají "flexibilní data", skript nachází nabídky, které se nacházejí v rámci tří dnů od zadaných dat. I když při spuštění skriptu probíhá vyhledávání pouze do jednoho směru, není složité jej upravit, aby mohl shromažďovat data pro více směru letů. Pomocí něj lze dokonce vyhledávat chyby v tarifech, podobné nálezy mohou být velmi zajímavé.
Proč potřebujeme další webový scrapper?
Keď som sa prvýkrát zaoberal web scrapingom, úprimne povedané, nebolo to pre mňa veľmi zaujímavé. Chcel som robiť viac projektov v oblasti prediktívneho modelovania, finančnej analýzy a možno v oblasti analýzy emocionálneho zafarbenia textov. Ale ukázalo sa, že je to veľmi zaujímavé — prichádzať na to, ako vytvoriť program, ktorý zhromažďuje údaje z webových stránok. Keď som sa do tejto témy viac zažral, uvedomil som si, že práve web scraping je „motorom“ internetu.
Možno sa rozhodnete, že je to príliš odvážne vyhlásenie. Ale zamyslite sa nad tým, že spoločnosť Google začala s web scraprom, ktorý Larry Page vytvoril pomocou Javy a Pythonu. Robots Google skúmajú a skúmajú internet s cieľom poskytnúť svojim používateľom tie najlepšie odpovede na ich otázky. Web scraping má nekonečné množstvo aplikácií, a aj keď vás v oblasti Data Science zaujíma niečo iné, na získanie dát na analýzu budete potrebovať niektoré zručnosti v scraping.
Niektoré z techník, ktoré sú tu použité, som našiel vo výnimočnej o web scrapingu, ktorú som si nedávno zaobstaral. Môžete v nej nájsť množstvo jednoduchých príkladov a nápadov na praktické využitie toho, čo ste sa naučili. Okrem toho tam je veľmi zaujímavá kapitola o obchádzaní kontrol reCaptcha. Pre mňa to bolo prekvapením, pretože som nevedel, že existujú špeciálne nástroje a dokonca celé služby na riešenie podobných úloh.
Milujete cestovanie?!
Na jednoduchú a celkom neškodnú otázku, ktorá je uvedená v názve tejto sekcie, často môžete počuť pozitívnu odpoveď, doplnenú o niekoľko príbehov z ciest toho, komu bola položená. Väčšina z nás súhlasí s tým, že cestovanie je skvelý spôsob, ako sa ponoriť do nových kultúrnych prostredí a rozšíriť si obzory. Avšak, ak by ste sa niekoho opýtali, či sa mu páči hľadanie leteniek, som si istý, že odpoveď na túto otázku už nebude taká pozitívna. Vlastne, tu prichádza na pomoc Python.
Prvou úlohou, ktorú musíme vyriešiť na ceste k vytvoreniu systému vyhľadávania informácií o letenkách, bude výber vhodnej platformy, z ktorej získame informácie. Riešenie tejto úlohy mi dalo dosť zabrať, ale nakoniec som si vybral službu Kayak. Skúšal som služby Momondo, Skyscanner, Expedia a niektoré ďalšie, ale mechanizmy ochrany pred robotmi na týchto stránkach boli nepreniknuteľné. Po niekoľkých pokusoch, kedy som sa snažil presvedčiť systémy, že som človek, som musel čeliť semaforom, prechodom pre chodcov a bicyklom. Rozhodol som sa, že mi najviac vyhovuje Kayak, aj keď aj tu, ak sa za krátky čas načítajú príliš veľa stránok, začnú kontroly. Podarilo sa mi nastaviť bota tak, aby posielal požiadavky na stránku v intervaloch od 4 do 6 hodín, a všetko fungovalo normálne. Občas sa počas práce s Kayak objavia komplikácie, ale ak vás začnú obťažovať kontrolami, musíte buď problém vyriešiť ručne a následne spustiť bota, alebo počkať niekoľko hodín, keď by kontroly mali prestať. Ak chcete, môžete kód prispôsobiť aj pre iné platformy a ak to urobíte, môžete sa o to podeliť v komentároch.
Ak sa len zoznamujete s web scrapingom a neviete, prečo niektoré webové stránky s ním bojujú všetkými silami, predtým než sa pustíte do svojho prvého projektu v tejto oblasti — urobte si službu a vyhľadajte v Google materiály na téma „etiketa web scrapingu“. Vaše experimenty môžu skončiť skôr, ako si myslíte, ak sa budete venovať web scrapingu nerozvážne.
Začiatok práce
Tu je všeobecný prehľad toho, čo sa bude diať v kóde nášho web skraperu:
- Import potrebných knižníc.
- Otváranie karty Google Chrome.
- Volanie funkcie, ktorá spúšťa bota, pričom mu odovzdáva mestá a dátumy, ktoré sa budú používať pri vyhľadávaní leteniek.
- Táto funkcia získava prvé výsledky vyhľadávania, zoradené podľa kritéria najvyššej atraktívnosti (best) a klikne na tlačidlo pre načítanie ďalších výsledkov.
- Ďalšia funkcia zbiera dáta z celej stránky a vracia rámec údajov.
- Dva predchádzajúce kroky sa vykonávajú pomocou typov triedenia podľa ceny leteniek (cheap) a podľa rýchlosti letu (fastest).
- Používateľ skriptu dostane e-mail, ktorý obsahuje krátke zhrnutie cien lístkov (najlacnejšie lístky a priemerná cena), a dáta so záznamami zoradenými podľa týchto troch vyžadovaných ukazovateľov sa uložia ako Excel súbor.
- Všetky vyššie opísané akcie prebiehajú v cykle cez stanovený časový interval.
Je potrebné poznamenať, že každý projekt Selenium začína s webovým ovládačom. Používam , pracujem s Google Chrome, ale existujú aj iné možnosti. Obľubu si získali aj PhantomJS a Firefox. Po stiahnutí ovládača ho treba umiestniť do príslušného priečinka, na tom sa príprava na jeho použitie končí. V prvých riadkoch nášho skriptu sa otvorí nová karta v Chrome.
Vezmite do úvahy, že vo svojom rozprávaní sa nepokúšam otvoriť nové horizonty pri hľadaní výhodných ponúk na letenky. Existujú aj oveľa pokročilejšie techniky vyhľadávania takýchto ponúk. Chcem len ponúknuť čitateľom tohto materiálu jednoduchý, ale prakticky použiteľný spôsob, ako tento problém riešiť.
Tu je kód, o ktorom sme hovorili vyššie.
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
# Použite tu vašu cestu k chromedriver!
chromedriver_path = 'C:/{YOUR PATH HERE}/chromedriver_win32/chromedriver.exe'
driver = webdriver.Chrome(executable_path=chromedriver_path) # Tento príkaz otvorí okno Chrome
sleep(2) Na začiatku kódu sú viditeľné príkazy na import balíkov, ktoré sú použité v celom našom projekte. Tak, randint sa používa na to, aby bot "zaspal" na náhodný počet sekúnd predtým, než začne novú operáciu vyhľadávania. Bez toho sa zvyčajne nezaobíde žiadny bot. Ak spustíte uvedený kód, otvorí sa okno Chrome, ktoré bot bude používať na prácu so stránkami.
Urobíme malý experiment a otvoríme v samostatnom okne stránku kayak.com. Vyberieme mesto, z ktorého plánujeme letieť, a mesto, do ktorého chceme prísť, ako aj dátumy letov. Pri výbere dátumov skontrolujeme, či sa používa rozsah +-3 dni. Napísal som kód s ohľadom na to, čo stránka vracia na podobné dopyty. Ak by ste napríklad potrebovali hľadať letenky len na stanovené dátumy, je vysoká pravdepodobnosť, že budete musieť prispôsobiť kód bota. Pri rozprávaní o kóde robím príslušné objasnenia, ale ak máte pocit, že ste sa stratili, dajte mi vedieť.
Teraz klikneme na tlačidlo spustenia vyhľadávania a pozrieme sa na odkaz v riadku adresy. Mal by byť podobný odkazu, ktorý používam v príklade nižšie, kde sa deklaruje premenná kayak, ktorá uchováva URL a používa sa metóda get webového ovládača. Po kliknutí na tlačidlo vyhľadávania by sa na stránke mali zobraziť výsledky.
![]()
Keď som použil príkaz get viac ako dvakrát-trikrát za niekoľko minút, požiadali ma o prechod overením pomocou reCaptcha. Toto overenie môžete prejsť manuálne a pokračovať v experimentoch dovtedy, kým systém nerozhodne, že je potrebné nové overenie. Keď som testoval skript, mal som pocit, že prvé hľadanie vždy prebieha hladko, a preto, ak chcete experimentovať s kódom, budete musieť iba občas manuálne prejsť overením a nechať kód bežať s dlhšími intervalmi medzi hľadaniami. A navyše, ak sa nad tým zamyslíte, človeku sotva budú potrebné informácie o cenách leteniek, ktoré sa získali s 10-minútovými intervalmi medzi operáciami hľadania.
Práca so stránkou pomocou XPath
Takže sme otvorili okno a načítali stránku. Aby sme získali informácie o cenách a ďalšie údaje, musíme využiť technológiu XPath alebo CSS selektory. Rozhodol som sa zamerať na XPath a necítil som potrebu používať CSS selektory, ale je určite možné pracovať aj tak. Pohyb po stránke pomocou XPath môže byť zložitým úkon, a aj keď použijete metódy, ktoré som popísal v V článku, kde som kopíroval príslušné identifikátory z kódu stránky, som pochopil, že to nie je vlastne optimálny spôsob, ako sa obrátiť na potrebné prvky. Mimochodom, v knihe nájdete skvelý popis základov práce so stránkami pomocou XPath a CSS selektorov. Takto vyzerá príslušná metóda webového ovládača.
![]()
Pokračujeme v práci na botovi. Využijeme možnosti programu na výber najlacnejších leteniek. Na nasledujúcom obrázku je červenou farbou zvýraznený kód XPath selektora. Aby ste si mohli zobraziť kód, musíte kliknúť pravým tlačidlom myši na zaujímavý prvok na stránke a v zobrazenom menu zvoliť príkaz Zobraziť kód (Inspect). Tento príkaz môžete aktivovať pre rôzne prvky stránok, ktorých kód sa zobrazí a zvýrazní v okne prezerania kódu.

Zobraziť kód stránky
Aby som našiel potvrdenie svojich úvah o nedostatkoch kopírovania selektorov z kódu, venujte pozornosť nasledujúcim aspektom.
Tu je to, čo sa získava pri kopírovaní kódu:
//*[@id="wtKI-price_aTab"]/div[1]/div/div/div[1]/div/span/spanAby ste skopírovali niečo podobné, musíte kliknúť pravým tlačidlom myši na zaujímavú časť kódu a v zobrazenom menu zvoliť príkaz Copy > Copy XPath.
Tu je to, čo som použil na určenie tlačidla Cheapest:
cheap_results = '//'a[@data-code = "price"]' 
Príkaz Copy > Copy XPath
Je úplne zrejmé, že druhá možnosť vyzerá oveľa jednoduchšie. Pri jej použití sa vyhľadáva prvok a, ktorý má atribút data-code, rovný price. Pri použití prvej varianty sa vykonáva vyhľadávanie prvku, id ktorého hodnota je wtKI-price_aTab, pričom cesta XPath k prvku vyzerá ako /div[1]/div/div/div[1]/div/span/span. Takýto XPath dotaz na stránku urobí svoje, ale — iba raz. Môžem povedať, že id sa zmení pri nasledujúcom načítaní stránky. Sekvencia znakov wtKI sa dynamicky mení pri každom načítaní stránky, v dôsledku čoho sa kód, v ktorom je použitý, po ďalšom obnovení stránky stane nepoužiteľným. Preto si nájdite čas na to, aby ste sa oboznámili s XPath. Tieto vedomosti vám dobre poslúžia.
Je však potrebné poznamenať, že kopírovanie XPath selektorov môže byť užitočné pri práci s dostatočne jednoduchými webmi a ak vám to vyhovuje, nie je v tom nič zlé.
Teraz sa poďme zamyslieť nad tým, čo robiť, ak potrebujeme získať všetky výsledky vyhľadávania v niekoľkých riadkoch, v rámci zoznamu. Je to veľmi jednoduché. Každý výsledok sa nachádza v objekte s triedou resultWrapper. Načítanie všetkých výsledkov môže prebiehať v cykle, ktorý pripomína ten, ktorý bude zobrazený nižšie.
Treba poznamenať, že ak vám je jasné to, čo bolo povedané vyššie, mali by ste bez problémov pochopiť väčšinu kódu, ktorý budeme rozoberať. V priebehu práce tohto kódu sa k tomu, čo potrebujeme (v podstate - je to prvok, do ktorého je zabalený výsledok), obraciame pomocou akéhosi mechanizmu na určenie cesty (XPath). Robí sa to na to, aby sme získali text prvku a umiestnili ho do objektu, z ktorého môžeme čítať dáta (najprv sa používa flight_containers, potom - flights_list).

Zobrazujú sa prvé tri riadky a jasne vidíme všetko, čo potrebujeme. Máme však aj zaujímavejšie spôsoby získania informácií. Potrebujeme brať údaje z každého prvku osobitne.
Do práce!
Najjednoduchšie je napísať funkciu na načítanie dodatočných výsledkov, takže s ňou aj začneme. Chcel by som maximálne zvýšiť počet letov, o ktorých program získava informácie, a pritom nevzbudzovať podozrenie služby, čo by mohlo viesť k kontrole, preto každý raz kliknem na tlačidlo Načítať viac výsledkov, keď sa zobrazuje stránka. V tomto kóde je potrebné venovať pozornosť bloku try, ktorý som pridal, pretože niekedy sa tlačidlo správne nenahráva. Ak sa s tým tiež stretnete — zakomentujte volania tejto funkcie v kóde funkcie start_kayak, ktorú preskúmame nižšie.
# Загрузка большего количества результатов для того, чтобы максимизировать объём собираемых данных
def load_more():
try:
more_results = '//a[@class = "moreButton"]'
driver.find_element_by_xpath(more_results).click()
# Вывод этих заметок в ходе работы программы помогает мне быстро выяснить то, чем она занята
print('sleeping.....')
sleep(randint(45,60))
except:
passTeraz, po dlhom rozbore tejto funkcie (niekedy sa môžem aj nechať uniesť), sme pripravení na to, aby sme vyhlásili funkciu, ktorá bude zaoberať sa skrípaním stránky.
Už som zhromaždil väčšinu potrebného v nasledujúcej funkcii nazvanej page_scrape. Niekedy sa vrátené dáta o etapách cesty kombinujú; na ich oddelenie používam jednoduchú metódu. Napríklad, keď prvýkrát používam premenné section_a_list a section_b_list. Naša funkcia vracia rámec údajov flights_df, čo nám umožňuje oddeliť výsledky získané pri používaní rôznych metód triedenia údajov a neskôr ich zlúčiť.
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 Snažil som sa nazvať premenné tak, aby bol kód zrozumiteľný. Nezabúdajte, že premenné, ktoré začínajú s a patria k prvej fáze cesty, a b — k druhej. Prejdime k ďalšej funkcii.
Pomocné mechanizmy
Teraz máme funkciu, ktorá umožňuje načítať ďalšie výsledky vyhľadávania a funkciu na spracovanie týchto výsledkov. Tento článok by sme mohli skončiť tu, pretože tieto dve funkcie poskytujú všetko potrebné na scrapovanie stránok, ktoré je možné otvoriť samostatne. Avšak zatiaľ sme nepreskúmali niektoré pomocné mechanizmy, o ktorých sme hovorili vyššie. Napríklad — toto je kód na odoslanie e-mailov a ešte niektoré veci. To všetko nájdeme vo funkcii start_kayak, ktorú teraz preskúmame.
Na fungovanie tejto funkcie sú potrebné údaje o mestách a dátumoch. Táto funkcia, využívajúc tieto údaje, formuje odkaz v premennej kayak, ktorá sa používa na prechod na stránku, na ktorej budú výsledky vyhľadávania zoradené podľa najlepšieho zodpovedania dopytu. Po prvej relácii scrapovania sa pozrieme na ceny, ktoré sa nachádzajú v tabuľke v hornej časti stránky. A to konkrétne, nájdeme minimálnu cenu lístka a priemernú cenu. To všetko, spolu s predpoveďou poskytnutou stránkou, bude odoslané e-mailom. Na stránke by mala byť príslušná tabuľka v ľavnom hornom rohu. Práca s touto tabuľkou, mimochodom, môže spôsobiť chybu pri vyhľadávaní pomocou presných dátumov, pretože v takom prípade sa tabuľka na stránke nezobrazuje.
def start_kayak(city_from, city_to, date_start, date_end):
"""Kódy miest - ide o IATA kódy!
Formát dátumu - 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))
# Niekedy sa objaví vyskakovacie okno, na jeho kontrolu a zavretie môžeme použiť blok try
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('načítanie pokračuje.....')
# load_more()
print('začiatok prvej extrakcie.....')
df_flights_best = page_scrape()
df_flights_best['sort'] = 'najlepšie'
sleep(randint(60,80))
# Zoberieme najnižšiu cenu z tabuľky, nachádzajúcej sa na hornej časti stránky
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('prepínanie na najlacnejšie výsledky.....')
cheap_results = '//*[contains(@data-code, "price")]'
driver.find_element_by_xpath(cheap_results).click()
sleep(randint(60,90))
print('načítanie pokračuje.....')
# load_more()
print('začiatok druhej extrakcie.....')
df_flights_cheap = page_scrape()
df_flights_cheap['sort'] = 'lacné'
sleep(randint(60,80))
print('prepínanie na najrýchlejšie výsledky.....')
quick_results = '//*[contains(@data-code, "duration")]'
driver.find_element_by_xpath(quick_results).click()
sleep(randint(60,90))
print('načítanie pokračuje.....')
# load_more()
print('začiatok tretej extrakcie.....')
df_flights_fast = page_scrape()
df_flights_fast['sort'] = 'rýchlo'
sleep(randint(60,80))
# Uloženie nového rámca do Excel súboru, ktorého názov odráža mestá a dátumy
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('uložený df.....')
# Môžeme sledovať, ako sa predpoveď na stránke zhoduje s realitou
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)
# Niekedy sa v premennej loading objaví tento reťazec, ktorý neskôr spôsobuje problémy s odoslaním e-mailu
# ak sa to stane - zmeníme ho na "Not Sure"
weird = '¯_(ツ)_/¯'
if loading == weird:
loading = 'Nie som si istý'
username = 'YOUREMAIL@hotmail.com'
password = 'YOUR PASSWORD'
server = smtplib.SMTP('smtp.outlook.com', 587)
server.ehlo()
server.starttls()
server.login(username, password)
msg = ('Predmet: Flight Scrapernn
Najlacnejší let: {}nPriemerná cena: {}nnOdporúčanie: {}nnKoniec správy'.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('odoslaný e-mail.....')Otestoval som tento skript pomocou účtu Outlook (hotmail.com). Neprekontroloval som jeho funkčnosť s účtom Gmail, ktorý je veľmi populárny, ale existuje množstvo možných variantov. Ak používate účet Hotmail, stačí zadať svoje údaje do kódu, aby všetko fungovalo.
Ak chcete pochopiť, čo presne sa vykonáva v jednotlivých častiach kódu tejto funkcie, môžete si ich skopírovať a experimentovať s nimi. Experimentovanie s kódom je jediný spôsob, ako ho riadne pochopiť.
Hotový systém
Teraz, keď je hotové všetko, o čom sme hovorili, môžeme vytvoriť jednoduchý cyklus, v ktorom sa volajú naše funkcie. Skript sa pýta používateľa na údaje o mestách a dátumoch. Pri testovaní s neustálym reštartovaním skriptu sa vám zrejme nebude chcieť zakaždým zadávať tieto údaje ručne, preto je možné príslušné riadky na čas testovania zakomentovať, a odkomentovať tie, ktoré sú nižšie, v ktorých sú pevne zadané potrebné údaje pre skript.
city_from = input('Z ktorého mesta? ')
city_to = input('Kam? ')
date_start = input('Hľadať okolo ktorého dátumu odchodu? Použite iba formát YYYY-MM-DD ')
date_end = input('Kedy sa má vrátiť? Použite iba formát 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('iterácia {} bola dokončená @ {}'.format(n, strftime("%Y%m%d-%H%M")))
# Čakáme 4 hodiny
sleep(60*60*4)
print('čakací čas skončil.....') Takto vyzerá testovacie spustenie skriptu.

Testovacie spustenie skriptu
Zhrnutie
Ak ste sa dostali až sem — blahoželám! Teraz máte funkčný webový skríping, hoci už vidím množstvo spôsobov, ako ho vylepšiť. Napríklad ho môžete integrovať s Twilio, aby namiesto e-mailov posielal textové správy. Môžete použiť VPN alebo niečo podobné na to, aby ste zároveň získavali výsledky z niekoľkých serverov. Existuje aj občasne sa vyskytujúci problém s kontrolou používateľa webu, či je človekom, ale aj tento problém sa dá vyriešiť. V každom prípade, teraz máte základ, ktorý môžete rozširovať podľa svojich predstáv. Napríklad, aby sa Excel súbor posielal používateľovi ako príloha v e-maile.
Len registrovaní používatelia sa môžu zúčastniť prieskumu. , prosím.
Používate technológie webového skríningu?
Áno
Nie
Hlasovalo 8 používateľov. Zdržal sa 1 používateľ.
Zdroj: habr.com
