Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast

Höfundur greinarinnar, sem við birtum þýðinguna á í dag, segir að markmið hennar sé að tala um þróun vefsköfu í Python með Selenium, sem leitar að verði flugmiða. Þegar leitað er að miðum eru notaðar sveigjanlegar dagsetningar (+- 3 dagar miðað við tilgreindar dagsetningar). Skafan vistar leitarniðurstöðurnar í Excel skrá og sendir þeim sem rak leitina tölvupóst með samantekt á því sem hann fann. Markmið þessa verkefnis er að hjálpa ferðamönnum að finna bestu tilboðin.

Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast

Ef þér finnst þú glataður meðan þú skilur efnið, skoðaðu þá þetta grein.

Að hverju ætlum við að leita?

Þér er frjálst að nota kerfið sem lýst er hér eins og þú vilt. Til dæmis notaði ég það til að leita að helgarferðum og miðum til heimabæjar míns. Ef þér er alvara með að finna arðbæra miða geturðu keyrt handritið á þjóninum (einfalt netþjóni, fyrir 130 rúblur á mánuði, er alveg hentugur fyrir þetta) og vertu viss um að það gangi einu sinni eða tvisvar á dag. Leitarniðurstöður verða sendar til þín með tölvupósti. Auk þess mæli ég með því að setja allt upp þannig að handritið visti Excel skrá með leitarniðurstöðum í Dropbox möppu sem gerir þér kleift að skoða slíkar skrár hvar sem er og hvenær sem er.

Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast
Ég hef ekki fundið gjaldskrá með villum ennþá, en ég held að það sé mögulegt

Þegar leitað er, eins og áður hefur komið fram, er „sveigjanleg dagsetning“ notuð; handritið finnur tilboð sem eru innan þriggja daga frá tilteknum dagsetningum. Þó að þegar handritið er keyrt leitar það aðeins að tilboðum í eina átt er auðvelt að breyta því þannig að það geti safnað gögnum um nokkrar flugstefnur. Með hjálp þess geturðu jafnvel leitað að röngum gjaldskrá; slíkar uppgötvun getur verið mjög áhugaverð.

Af hverju þarftu aðra vefsköfu?

Þegar ég byrjaði fyrst að vefskrapa hafði ég satt að segja ekki sérstakan áhuga á því. Mig langaði að gera fleiri verkefni á sviði forspárlíkana, fjármálagreiningar og hugsanlega á sviði greiningar á tilfinningalitun texta. En það kom í ljós að það var mjög áhugavert að finna út hvernig á að búa til forrit sem safnar gögnum af vefsíðum. Þegar ég kafaði ofan í þetta efni áttaði ég mig á því að vefskrap er „vél“ internetsins.

Þú gætir haldið að þetta sé of djörf fullyrðing. En íhugaðu að Google byrjaði með vefsköfu sem Larry Page bjó til með Java og Python. Google vélmenni hafa verið að kanna internetið og reyna að veita notendum sínum bestu svörin við spurningum sínum. Vefskrap hefur endalausa notkun, og jafnvel þótt þú hafir áhuga á einhverju öðru í gagnavísindum, þá þarftu einhverja skafakunnáttu til að fá gögnin sem þú þarft að greina.

Ég fann nokkrar af þeim aðferðum sem notaðar eru hér í yndislegu bókinni um vefskrap, sem ég eignaðist nýlega. Það inniheldur mörg einföld dæmi og hugmyndir til hagnýtingar á því sem þú hefur lært. Að auki er mjög áhugaverður kafli um að komast framhjá reCaptcha ávísunum. Þetta kom sem fréttir fyrir mig, þar sem ég vissi ekki einu sinni að það væru sérstök tæki og jafnvel heil þjónusta til að leysa slík vandamál.

Finnst þér gaman að ferðast?!

Við hinni einföldu og frekar meinlausu spurningu sem sett er fram í titli þessa kafla má oft heyra jákvætt svar ásamt nokkrum sögum frá ferðum þess sem spurt var um. Flest okkar eru sammála um að ferðalög séu frábær leið til að sökkva sér niður í nýtt menningarumhverfi og víkka sjóndeildarhringinn. Hins vegar, ef þú spyrð einhvern hvort honum líkar að leita að flugmiðum, er ég viss um að svarið verður ekki svo jákvætt. Reyndar kemur Python okkur til hjálpar hér.

Fyrsta verkefnið sem við þurfum að leysa á leiðinni að því að búa til kerfi til að leita upplýsinga um flugmiða verður að velja viðeigandi vettvang sem við tökum upplýsingar frá. Að leysa þetta vandamál var ekki auðvelt fyrir mig, en á endanum valdi ég Kayak þjónustuna. Ég reyndi þjónustu Momondo, Skyscanner, Expedia og nokkurra annarra, en vélmennavörnin á þessum auðlindum var órjúfanleg. Eftir nokkrar tilraunir, þar sem ég þurfti að takast á við umferðarljós, gangbrautir og reiðhjól, að reyna að sannfæra kerfin um að ég væri mannlegur, ákvað ég að kajak hentaði mér best, þrátt fyrir að jafnvel þótt of margar síður séu hlaðnar á skömmum tíma og athuganir hefjast einnig. Mér tókst að láta botninn senda beiðnir á síðuna með 4 til 6 klukkustunda millibili og allt virkaði vel. Af og til koma upp erfiðleikar þegar unnið er með Kayak, en ef þeir byrja að plaga þig með ávísunum, þá þarftu annað hvort að takast á við þá handvirkt og ræsa síðan vélmanninn, eða bíða í nokkrar klukkustundir og eftirlitið ætti að hætta. Ef nauðsyn krefur geturðu auðveldlega lagað kóðann fyrir annan vettvang og ef þú gerir það geturðu tilkynnt það í athugasemdum.

Ef þú ert nýbyrjaður með vefskrapun og veist ekki hvers vegna sumar vefsíður eiga í erfiðleikum með það, þá áður en þú byrjar á fyrsta verkefninu þínu á þessu sviði, gerðu sjálfum þér greiða og gerðu Google leit að orðunum "vefskrapunarsiðir" . Tilraunirnar þínar gætu endað fyrr en þú heldur ef þú gerir vefskrap á óskynsamlegan hátt.

getting Started

Hér er almennt yfirlit yfir hvað mun gerast í vefsköfunarkóðanum okkar:

  • Flyttu inn nauðsynleg bókasöfn.
  • Að opna Google Chrome flipa.
  • Hringdu í aðgerð sem ræsir vélmanninn og sendir honum borgirnar og dagsetningarnar sem verða notaðar þegar leitað er að miðum.
  • Þessi aðgerð tekur fyrstu leitarniðurstöðurnar, flokkaðar eftir bestu, og smellir á hnapp til að hlaða fleiri niðurstöðum.
  • Önnur aðgerð safnar gögnum af allri síðunni og skilar gagnaramma.
  • Tvö fyrri skrefin eru framkvæmd með því að flokka gerðir eftir miðaverði (ódýrt) og eftir flughraða (hraðasta).
  • Notanda smáforritsins er sendur tölvupóstur með yfirliti yfir miðaverð (ódýrustu miðana og meðalverð) og gagnarammi með upplýsingum raðað eftir þremur ofangreindum vísum er vistaður sem Excel skjal.
  • Allar ofangreindar aðgerðir eru framkvæmdar í lotu eftir ákveðinn tíma.

Það skal tekið fram að hvert Selenium verkefni byrjar með vefrekla. ég nota Chromedriver, Ég vinn með Google Chrome, en það eru aðrir valkostir. PhantomJS og Firefox eru líka vinsælar. Eftir að þú hefur hlaðið niður bílstjóranum þarftu að setja hann í viðeigandi möppu og það klárar undirbúninginn fyrir notkun hans. Fyrstu línurnar í handritinu okkar opna nýjan Chrome flipa.

Hafðu í huga að í sögu minni er ég ekki að reyna að opna nýjan sjóndeildarhring til að finna frábær tilboð á flugmiðum. Það eru til miklu fullkomnari aðferðir við að leita að slíkum tilboðum. Ég vil bara bjóða lesendum þessa efnis upp á einfalda en hagnýta leið til að leysa þetta vandamál.

Hér er kóðinn sem við ræddum um hér að ofan.

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)

Í upphafi kóðans geturðu séð pakkainnflutningsskipanirnar sem eru notaðar í gegnum verkefnið okkar. Svo, randint notað til að láta vélmanninn „sofna“ í tilviljunarkenndan fjölda sekúndna áður en ný leitaraðgerð er hafin. Venjulega getur ekki einn botni verið án þessa. Ef þú keyrir ofangreindan kóða opnast Chrome gluggi sem vélmenni mun nota til að vinna með vefsvæðum.

Gerum smá tilraun og opnum vefsíðuna kayak.com í sérstökum glugga. Við munum velja borgina sem við ætlum að fljúga frá og borgina sem við viljum komast til, auk flugdaga. Þegar þú velur dagsetningar skaltu ganga úr skugga um að bilið +-3 dagar sé notað. Ég skrifaði kóðann með hliðsjón af því sem síðan framleiðir sem svar við slíkum beiðnum. Ef þú þarft til dæmis að leita að miðum eingöngu fyrir tilteknar dagsetningar, þá eru miklar líkur á að þú þurfir að breyta botnkóðanum. Þegar ég tala um kóðann gef ég viðeigandi skýringar, en ef þú finnur fyrir ruglingi, láttu mig vita.

Smelltu nú á leitarhnappinn og skoðaðu hlekkinn í veffangastikunni. Það ætti að vera svipað og tengilinn sem ég nota í dæminu hér að neðan þar sem breytan er lýst yfir kayak, sem geymir slóðina, og aðferðin er notuð get bílstjóri fyrir vefinn. Eftir að hafa smellt á leitarhnappinn ættu niðurstöður að birtast á síðunni.

Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast
Þegar ég notaði skipunina get oftar en tvisvar eða þrisvar á nokkrum mínútum var ég beðinn um að ljúka sannprófun með reCaptcha. Þú getur staðist þessa athugun handvirkt og haldið áfram að gera tilraunir þar til kerfið ákveður að keyra nýja athugun. Þegar ég prófaði handritið virtist sem fyrsta leitarlotan hafi alltaf gengið snurðulaust fyrir sig, þannig að ef þú vildir gera tilraunir með kóðann, þá þyrftirðu aðeins að athuga reglulega handvirkt og láta kóðann keyra, með löngum bili á milli leitarlota. Og ef þú hugsar um það er ólíklegt að einstaklingur þurfi upplýsingar um miðaverð sem berast með 10 mínútna millibili á milli leitaraðgerða.

Vinna með síðu með XPath

Svo, við opnuðum glugga og hlóðum síðuna. Til að fá verð og aðrar upplýsingar þurfum við að nota XPath tækni eða CSS veljara. Ég ákvað að halda mig við XPath og fannst ég ekki þurfa að nota CSS veljara, en það er alveg hægt að vinna þannig. Það getur verið flókið að fletta um síðu með XPath og jafnvel þó þú notir tæknina sem ég lýsti í þetta grein, sem fól í sér að afrita samsvarandi auðkenni úr síðukóðanum, áttaði ég mig á því að þetta er í raun ekki ákjósanlegasta leiðin til að fá aðgang að nauðsynlegum þáttum. Við the vegur, í þetta Bókin gefur frábæra lýsingu á grunnatriðum þess að vinna með síður með XPath og CSS veljara. Svona lítur samsvarandi vefbílstjóri út.

Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast
Svo skulum við halda áfram að vinna að botni. Notum möguleika forritsins til að velja ódýrustu miðana. Á eftirfarandi mynd er XPath veljakóðinn auðkenndur með rauðu. Til að skoða kóðann þarftu að hægrismella á síðuþáttinn sem þú hefur áhuga á og velja Skoða skipunina í valmyndinni sem birtist. Hægt er að kalla á þessa skipun fyrir mismunandi síðuþætti, kóðinn sem birtist og auðkenndur í kóðaskoðaranum.

Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast
Skoða síðukóða

Til að finna staðfestingu á rökstuðningi mínum um ókosti þess að afrita veljara úr kóða, gefðu gaum að eftirfarandi eiginleikum.

Þetta er það sem þú færð þegar þú afritar kóðann:

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

Til að afrita eitthvað eins og þetta þarftu að hægrismella á kóðann sem þú hefur áhuga á og velja Copy > Copy XPath skipunina í valmyndinni sem birtist.

Hér er það sem ég notaði til að skilgreina Ódýrasta hnappinn:

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

Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast
Afrita skipun > Afrita XPath

Það er alveg augljóst að seinni kosturinn lítur miklu einfaldari út. Þegar það er notað leitar það að þætti a sem hefur eiginleikann data-codejafnt og price. Þegar fyrsta valmöguleikinn er notaður er leitað í þættinum id sem er jafnt wtKI-price_aTab, og XPath slóðin að frumefninu lítur út eins og /div[1]/div/div/div[1]/div/span/span. XPath fyrirspurn eins og þessi á síðu mun gera bragðið, en aðeins einu sinni. Ég get sagt það núna id mun breytast næst þegar síðan er hlaðið. Persónuröð wtKI breytist á kraftmikinn hátt í hvert sinn sem síðan er hlaðin, þannig að kóðinn sem notar hana verður ónýtur eftir næstu endurhleðslu. Svo gefðu þér smá tíma til að skilja XPath. Þessi þekking mun þjóna þér vel.

Hins vegar skal tekið fram að afritun XPath veljara getur verið gagnlegt þegar unnið er með frekar einfaldar síður og ef þú ert sátt við þetta er ekkert að því.

Nú skulum við hugsa um hvað á að gera ef þú þarft að fá allar leitarniðurstöður í nokkrum línum, inni í lista. Mjög einfalt. Hver niðurstaða er inni í hlut með flokki resultWrapper. Hægt er að hlaða öllum niðurstöðunum í lykkju svipað þeirri sem sýnd er hér að neðan.

Það skal tekið fram að ef þú skilur ofangreint, þá ættir þú auðveldlega að skilja mestan hluta kóðans sem við munum greina. Þegar þessi kóði keyrir, fáum við aðgang að því sem við þurfum (reyndar þáttinn sem útkoman er vafuð í) með því að nota einhvers konar slóðatilgreina vélbúnað (XPath). Þetta er gert til að fá texta frumefnisins og setja hann í hlut sem hægt er að lesa gögn úr (fyrst notað flight_containers, Þá - flights_list).

Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast
Fyrstu þrjár línurnar birtast og við sjáum greinilega allt sem við þurfum. Hins vegar höfum við áhugaverðari leiðir til að afla upplýsinga. Við þurfum að taka gögn frá hverjum þætti fyrir sig.

Farðu að vinna!

Auðveldasta leiðin til að skrifa fall er að hlaða viðbótarniðurstöðum, svo það er þar sem við byrjum. Mig langar að hámarka fjölda flugferða sem forritið fær upplýsingar um, án þess að vekja grunsemdir í þjónustunni sem leiðir til skoðunar, svo ég smelli einu sinni á hnappinn Hlaða fleiri niðurstöðum í hvert sinn sem síðan birtist. Í þessum kóða ættir þú að borga eftirtekt til blokkarinnar try, sem ég bætti við vegna þess að stundum hleðst hnappurinn ekki rétt inn. Ef þú lendir líka í þessu skaltu skrifa athugasemd við símtöl í þessa aðgerð í aðgerðakóðanum start_kayak, sem við munum skoða hér að neðan.

# Загрузка большего количества результатов для того, чтобы максимизировать объём собираемых данных
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úna, eftir langa greiningu á þessari aðgerð (stundum læt ég fara í taugarnar á mér), erum við tilbúin að lýsa yfir aðgerð sem mun skafa síðuna.

Ég hef nú þegar safnað saman flestu sem þarf í eftirfarandi aðgerð sem kallast page_scrape. Stundum eru skiluðu slóðgögnin sameinuð, svo ég nota einfalda aðferð til að aðgreina þau. Til dæmis þegar ég nota breytur í fyrsta skipti section_a_list и section_b_list. Fallið okkar skilar gagnaramma flights_df, þetta gerir okkur kleift að aðgreina niðurstöður sem fengnar eru úr mismunandi gagnaflokkunaraðferðum og sameina þær síðar.

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

Ég reyndi að nefna breyturnar svo að kóðinn væri skiljanlegur. Mundu að breytur sem byrja á a tilheyra fyrsta áfanga leiðarinnar, og b - í annað. Við skulum halda áfram í næstu aðgerð.

Stuðningskerfi

Við höfum nú aðgerð sem gerir okkur kleift að hlaða fleiri leitarniðurstöðum og aðgerð til að vinna úr þeim niðurstöðum. Þessi grein hefði getað endað hér, þar sem þessar tvær aðgerðir veita allt sem þú þarft til að skafa síður sem þú getur opnað sjálfur. En við höfum ekki enn íhugað nokkrar af þeim hjálparaðferðum sem fjallað er um hér að ofan. Til dæmis er þetta kóðinn til að senda tölvupóst og ýmislegt fleira. Allt þetta er að finna í aðgerðinni start_kayak, sem við munum nú athuga.

Til að þessi aðgerð virki þarftu upplýsingar um borgir og dagsetningar. Með því að nota þessar upplýsingar myndar þær tengil í breytu kayak, sem er notað til að fara með þig á síðu sem mun innihalda leitarniðurstöður flokkaðar eftir bestu samsvörun við fyrirspurnina. Eftir fyrstu skraptímann munum við vinna með verðin í töflunni efst á síðunni. Við finnum nefnilega lágmarksmiðaverð og meðalverð. Allt þetta, ásamt spánni frá síðunni, verður sent með tölvupósti. Á síðunni ætti samsvarandi tafla að vera í efra vinstra horninu. Að vinna með þessa töflu, við the vegur, getur valdið villu þegar leitað er með nákvæmum dagsetningum, þar sem í þessu tilfelli er taflan ekki birt á síðunni.

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

Ég prófaði þetta handrit með Outlook reikningi (hotmail.com). Ég hef ekki prófað að það virki rétt með Gmail reikningi, þetta tölvupóstkerfi er nokkuð vinsælt, en það eru margir möguleikar. Ef þú notar Hotmail reikning, þá þarftu bara að slá inn gögnin þín í kóðann til að allt virki.

Ef þú vilt skilja hvað nákvæmlega er gert í tilteknum hlutum kóðans fyrir þessa aðgerð geturðu afritað þá og gert tilraunir með þá. Að gera tilraunir með kóðann er eina leiðin til að skilja hann í raun og veru.

Tilbúið kerfi

Nú þegar við höfum gert allt sem við töluðum um getum við búið til einfalda lykkju sem kallar á aðgerðir okkar. Handritið biður um gögn frá notandanum um borgir og dagsetningar. Þegar prófað er með stöðugri endurræsingu á handritinu er ólíklegt að þú viljir slá inn þessi gögn handvirkt í hvert skipti, þannig að samsvarandi línur, fyrir prófunartímann, er hægt að gera athugasemdir við með því að fjarlægja athugasemdir fyrir neðan þær, þar sem gögnin sem þarf af handritið er harðkóða.

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

Svona lítur prufukeyrsla á handritinu út.
Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast
Prufukeyrsla á handritinu

Niðurstöður

Ef þú hefur komist svona langt, til hamingju! Þú ert núna með virkan vefsköfu, þó ég sé nú þegar margar leiðir til að bæta hann. Til dæmis er hægt að samþætta það við Twilio þannig að það sendir textaskilaboð í stað tölvupósts. Þú getur notað VPN eða eitthvað annað til að fá niðurstöður frá nokkrum netþjónum samtímis. Það er líka vandamál sem kemur upp reglulega við að athuga notandann á síðunni til að sjá hvort hann sé manneskja, en þetta vandamál er líka hægt að leysa. Í öllum tilvikum, nú ertu með grunn sem þú getur stækkað ef þú vilt. Gakktu úr skugga um að Excel skrá sé send til notanda sem viðhengi við tölvupóst.

Python - aðstoðarmaður við að finna ódýra flugmiða fyrir þá sem elska að ferðast

Aðeins skráðir notendur geta tekið þátt í könnuninni. Skráðu þig inn, takk.

Notar þú vefskrapunartækni?

  • No

8 notendur kusu. 1 notandi sat hjá.

Heimild: www.habr.com

Bæta við athugasemd