Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм

Өнөөдрийн орчуулгыг нийтэлж буй нийтлэлийн зохиогч хэлэхдээ, нисэх онгоцны тийзний үнийг хайдаг Selenium ашиглан Python хэл дээр вэб хусагчийг хөгжүүлэх тухай ярих явдал юм. Тасалбар хайхдаа уян хатан огноог ашигладаг (заасан огноотой харьцуулахад +- 3 хоног). Скрепер нь хайлтын үр дүнг Excel файлд хадгалж, хайлт хийсэн хүнд олсон зүйлийнхээ хураангуйг имэйлээр илгээдэг. Энэхүү төслийн зорилго нь аялагчдад хамгийн сайн саналыг олоход нь туслах явдал юм.

Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм

Хэрэв та материалыг ойлгож байхдаа алдагдсан мэт санагдвал сайтар ажиглаарай энэ нь нийтлэл.

Бид юу хайх гэж байна вэ?

Та энд тайлбарласан системийг хүссэнээрээ чөлөөтэй ашиглах боломжтой. Жишээлбэл, би үүнийг амралтын өдрүүдээр хийх аялал, төрөлх хот руугаа тасалбар хайхад ашигладаг байсан. Хэрэв та ашигтай тасалбар хайж байгаа бол скриптийг сервер дээр ажиллуулж болно (энгийн сервер, сард 130 рублийн хувьд энэ нь маш тохиромжтой) бөгөөд өдөрт нэг эсвэл хоёр удаа ажилладаг эсэхийг шалгаарай. Хайлтын үр дүнг танд имэйлээр илгээх болно. Нэмж дурдахад би бүх зүйлийг тохируулахыг зөвлөж байна, ингэснээр скрипт нь хайлтын үр дүн бүхий Excel файлыг Dropbox хавтсанд хадгалах бөгөөд энэ нь танд ийм файлуудыг хаанаас ч, хэзээ ч үзэх боломжийг олгоно.

Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм
Би алдаатай тарифыг хараахан олоогүй байгаа ч боломжтой гэж бодож байна

Хайлт хийхдээ аль хэдийн дурьдсанчлан "уян хатан огноо" ашигладаг бөгөөд скрипт нь өгөгдсөн өдрөөс хойш гурав хоногийн дотор байгаа саналыг олдог. Хэдийгээр энэ скриптийг ажиллуулахдаа зөвхөн нэг чиглэлд санал хайдаг боловч хэд хэдэн нислэгийн чиглэлийн мэдээллийг цуглуулж чадахаар өөрчлөхөд хялбар байдаг. Үүний тусламжтайгаар та алдаатай тарифыг хайж олох боломжтой бөгөөд ийм олдвор нь маш сонирхолтой байж болно.

Яагаад танд өөр вэб хусах хэрэгтэй байна вэ?

Би анх вэб хусаж эхлэхэд би үүнийг тийм ч их сонирхдоггүй байсан. Би урьдчилан таамаглах загварчлал, санхүүгийн дүн шинжилгээ, магадгүй текстийн сэтгэл хөдлөлийн будгийг шинжлэх чиглэлээр илүү олон төсөл хийхийг хүссэн. Гэхдээ вэб сайтаас мэдээлэл цуглуулдаг программыг хэрхэн бүтээхийг олж мэдэх нь маш сонирхолтой байсан. Би энэ сэдвийг судлахдаа вэб хусах нь интернетийн "хөдөлгүүр" гэдгийг ойлгосон.

Та үүнийг хэтэрхий зоримог мэдэгдэл гэж бодож магадгүй юм. Гэхдээ Google нь Ларри Пэйжийн Java болон Python ашиглан бүтээсэн вэб хусагчаар эхэлсэн гэдгийг бодоорой. Google-ийн роботууд интернетийг судалж, хэрэглэгчдийнхээ асуултанд хамгийн сайн хариулт өгөхийг хичээж байна. Вэб хусах нь эцэс төгсгөлгүй хэрэглээтэй бөгөөд та Data Science-ийн өөр зүйлийг сонирхож байгаа ч танд дүн шинжилгээ хийх шаардлагатай өгөгдлийг олж авахын тулд хусах ур чадвар хэрэгтэй болно.

Энд ашигласан зарим техникийг би гайхалтайгаар олсон ном Миний саяхан олж авсан вэб хусах тухай. Энэ нь таны сурсан зүйлээ практикт хэрэгжүүлэх олон энгийн жишээ, санааг агуулдаг. Үүнээс гадна, reCaptcha шалгалтыг тойрч гарах тухай маш сонирхолтой бүлэг байдаг. Ийм асуудлыг шийдвэрлэх тусгай хэрэгсэл, тэр ч байтугай бүхэл бүтэн үйлчилгээ байдаг гэдгийг би мэдээгүй байсан тул энэ нь надад мэдээ байсан юм.

Чи аялах дуртай юу?!

Энэ хэсгийн гарчигт тавьсан энгийн бөгөөд хор хөнөөлгүй асуултанд та асуусан хүний ​​​​аялчлалын хэд хэдэн түүхийг дагалдуулсан эерэг хариултыг сонсох боломжтой. Аялал бол соёлын шинэ орчинд нэвтрэн орж, алсын хараагаа тэлэх сайхан арга гэдэгтэй бидний ихэнх нь санал нийлэх байх. Гэсэн хэдий ч, хэрэв та хэн нэгнээс онгоцны тийз хайх дуртай эсэхийг асуувал хариулт нь тийм ч эерэг байх болно гэдэгт би итгэлтэй байна. Үнэндээ Python энд бидэнд туслахаар ирдэг.

Онгоцны тийзний мэдээлэл хайх системийг бий болгоход бидний шийдэх ёстой хамгийн эхний ажил бол мэдээлэл авах тохиромжтой платформыг сонгох явдал юм. Энэ асуудлыг шийдэх нь надад амаргүй байсан ч эцэст нь Каяк үйлчилгээг сонгосон. Би Momondo, Skyscanner, Expedia болон бусад хэд хэдэн үйлчилгээг туршиж үзсэн боловч эдгээр нөөц дээрх роботыг хамгаалах механизм нь нэвтэршгүй байв. Би гэрлэн дохио, явган хүний ​​гарц, унадаг дугуйтай тулалдаж, системийг хүн гэж итгүүлэхийн тулд хэд хэдэн оролдлого хийснийхээ дараа Хэт олон хуудас ачаалагдсан байсан ч Каяк надад хамгийн тохиромжтой гэж шийдсэн. богино хугацаанд, мөн шалгалт эхэлнэ. Би роботыг 4-6 цагийн зайтай сайт руу хүсэлт илгээж чадсан бөгөөд бүх зүйл хэвийн болсон. Каяктай ажиллахад үе үе бэрхшээлтэй тулгардаг, гэхдээ тэд таныг чекээр зовоож эхэлбэл та тэдгээрийг гараар шийдэж, дараа нь ботыг ажиллуулах эсвэл хэдэн цаг хүлээх хэрэгтэй бөгөөд шалгалт зогсох ёстой. Шаардлагатай бол та кодыг өөр платформд хялбархан тохируулах боломжтой бөгөөд хэрэв та үүнийг хийвэл сэтгэгдэл дээр мэдээлж болно.

Хэрэв та вэб хусах ажлыг дөнгөж эхэлж байгаа бөгөөд зарим вэбсайт яагаад ийм асуудалтай тулгардагийг мэдэхгүй байгаа бол энэ чиглэлээр анхны төслөө эхлүүлэхээсээ өмнө өөртөө сайн сайхныг үзүүлж, Google-ээс "вэб хусах ёс зүй" гэсэн үгээр хайгаарай. . Хэрэв та ухаалгаар вэб хусах юм бол таны туршилтууд таны бодож байснаас хурдан дуусч магадгүй юм.

Эхлэл

Манай вэб хусагч кодонд юу тохиолдох талаар ерөнхий тойм энд байна.

  • Шаардлагатай номын санг импортлох.
  • Google Chrome табыг нээж байна.
  • Тасалбар хайхад хэрэглэгдэх хот, огноог дамжуулж, роботыг ажиллуулдаг функцийг дуудна уу.
  • Энэ функц нь хайлтын эхний илэрцийг хамгийн сайнаар нь эрэмбэлсэн бөгөөд товчлуур дээр дарж илүү олон илэрцийг ачаална.
  • Өөр нэг функц нь бүх хуудаснаас өгөгдлийг цуглуулж, өгөгдлийн хүрээг буцаана.
  • Өмнөх хоёр алхмыг тасалбарын үнэ (хямд) болон нислэгийн хурдаар (хамгийн хурдан) ангилах төрлүүдийг ашиглан гүйцэтгэдэг.
  • Тасалбарын үнийн хураангуй (хамгийн хямд тасалбар ба дундаж үнэ) агуулсан имэйлийг скрипт хэрэглэгч рүү илгээж, дээр дурдсан гурван хэмжигдэхүүнээр эрэмбэлсэн мэдээлэл бүхий өгөгдлийн хүрээг Excel файл болгон хадгална.
  • Дээрх бүх үйлдлүүд нь тодорхой хугацааны дараа мөчлөгт хийгддэг.

Selenium төсөл бүр вэб драйвераас эхэлдэг гэдгийг тэмдэглэх нь зүйтэй. би хэрэглэдэг Chromedriver, Би Google Chrome-тэй ажилладаг, гэхдээ өөр сонголтууд байдаг. PhantomJS болон Firefox нь бас алдартай. Драйверыг татаж авсны дараа та тохирох хавтсанд байрлуулах хэрэгтэй бөгөөд энэ нь түүнийг ашиглах бэлтгэлийг дуусгана. Манай скриптийн эхний мөрүүд нь шинэ Chrome табыг нээнэ.

Миний түүхэнд би онгоцны тийзний хямдрал олох шинэ боломжуудыг нээхийг оролдоогүй гэдгийг санаарай. Ийм саналыг хайх илүү дэвшилтэт аргууд байдаг. Би энэ материалыг уншигчдад энэ асуудлыг шийдэх энгийн боловч практик аргыг санал болгохыг хүсч байна.

Энд бидний дээр ярьсан код байна.

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)

Кодын эхэнд та манай төслийн хүрээнд хэрэглэгдэж буй багц импортын командуудыг харж болно. Тэгэхээр, randint Хайлтын шинэ ажиллагааг эхлүүлэхийн өмнө ботыг санамсаргүй хэдэн секундын турш "унтуулах" зорилгоор ашигладаг. Ихэвчлэн ганц ч робот үүнгүйгээр хийж чадахгүй. Хэрэв та дээрх кодыг ажиллуулбал Chrome цонх нээгдэх бөгөөд энэ нь робот нь сайтуудтай ажиллахад ашиглах болно.

Бяцхан туршилт хийж kayak.com вэб сайтыг тусдаа цонхонд нээцгээе. Бид нисэх гэж буй хот, хүрэхийг хүсч буй хот, мөн нислэгийн огноогоо сонгоно. Огноо сонгохдоо +-3 хоногийн хязгаарыг ашигласан эсэхийг шалгаарай. Би ийм хүсэлтийн дагуу сайт юу үйлдвэрлэдэгийг харгалзан кодыг бичсэн. Жишээлбэл, хэрэв та зөвхөн заасан огноогоор тасалбар хайх шаардлагатай бол ботын кодыг өөрчлөх магадлал өндөр байна. Би кодын талаар ярихдаа зохих тайлбарыг өгдөг, гэхдээ хэрэв та эргэлзэж байвал надад мэдэгдээрэй.

Одоо хайлтын товчийг дараад хаягийн мөрөнд байгаа холбоосыг харна уу. Энэ нь хувьсагчийг зарласан доорх жишээн дээр миний ашигладаг холбоостой төстэй байх ёстой kayak, URL-г хадгалдаг бөгөөд аргыг ашигладаг get вэб драйвер. Хайлтын товчийг дарсны дараа үр дүн нь хуудсан дээр гарч ирнэ.

Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм
Би тушаалыг ашигласан үед get Хэдхэн минутын дотор хоёроос гурван удаа давсан бол надаас reCaptcha ашиглан баталгаажуулалтыг дуусгахыг хүссэн. Та энэ шалгалтыг гараар давж, систем шинэ шалгалт явуулахаар шийдтэл туршилтаа үргэлжлүүлж болно. Би скриптийг туршиж үзэхэд эхний хайлтын сесс үргэлж жигд явагддаг юм шиг санагдсан тул хэрэв та кодыг туршиж үзэхийг хүсвэл зөвхөн үе үе гараар шалгаж, хайлтын хэсгүүдийн хооронд урт интервал ашиглан кодыг ажиллуулах хэрэгтэй болно. Хэрэв та энэ талаар бодох юм бол эрлийн ажиллагааны хооронд 10 минутын зайтай хүлээн авсан тасалбарын үнийн талаар мэдээлэл авах шаардлагагүй болно.

XPath ашиглан хуудастай ажиллах

Тиймээс бид цонх нээж сайтыг ачааллаа. Үнэ болон бусад мэдээллийг авахын тулд бид XPath технологи эсвэл CSS сонгогчийг ашиглах хэрэгтэй. Би XPath-тэй ажиллахаар шийдсэн бөгөөд CSS сонгогчийг ашиглах шаардлагагүй гэж үзсэн ч ийм байдлаар ажиллах бүрэн боломжтой. XPath ашиглан хуудасны эргэн тойронд навигац хийх нь миний тайлбарласан техникийг ашигласан ч гэсэн төвөгтэй байж болно энэ нь Хуудасны кодоос харгалзах таниулбаруудыг хуулахтай холбоотой нийтлэлээс харахад энэ нь үнэндээ шаардлагатай элементүүдэд хандах хамгийн оновчтой арга биш гэдгийг би ойлгосон. Дашрамд хэлэхэд, онд энэ нь Энэ ном нь XPath болон CSS сонгогч ашиглан хуудастай ажиллах үндсэн зарчмуудыг маш сайн тайлбарласан болно. Харгалзах вэб драйверын арга нь иймэрхүү харагдаж байна.

Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм
Тиймээс, робот дээр үргэлжлүүлэн ажиллацгаая. Хөтөлбөрийн боломжуудыг ашиглан хамгийн хямд тасалбарыг сонгоцгооё. Дараах зурган дээр XPath сонгогч кодыг улаанаар тодруулсан байна. Кодоо харахын тулд та сонирхож буй хуудасны элемент дээр хулганы баруун товчийг дараад гарч ирэх цэснээс Inspect командыг сонгох хэрэгтэй. Энэ тушаалыг хуудасны өөр өөр элементүүдэд дуудаж болох бөгөөд тэдгээрийн код нь код харагч дээр гарч ирэх бөгөөд тодруулна.

Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм
Хуудасны кодыг харах

Кодоос сонгогчийг хуулбарлахын сул талуудын талаархи миний үндэслэлийг батлахын тулд дараах шинж чанаруудад анхаарлаа хандуулаарай.

Та кодыг хуулахдаа дараах зүйлийг олж авна.

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

Иймэрхүү зүйлийг хуулахын тулд та сонирхож буй кодын хэсэг дээр хулганы баруун товчийг дараад гарч ирэх цэснээс Copy > Copy XPath командыг сонгох хэрэгтэй.

Хамгийн хямд товчийг тодорхойлохдоо би дараах зүйлийг дурдлаа.

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

Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм
Хуулах команд > XPath хуулах

Хоёрдахь хувилбар нь илүү энгийн харагдаж байгаа нь ойлгомжтой. Ашиглах үед энэ нь атрибуттай a элементийг хайдаг data-code, тэнцүү price. Эхний сонголтыг ашиглах үед элементийг хайдаг id тэнцүү байна wtKI-price_aTab, мөн элемент рүү хүрэх XPath зам иймэрхүү харагдаж байна /div[1]/div/div/div[1]/div/span/span. Хуудас руу хийх иймэрхүү XPath асуулга нь зөвхөн нэг удаа ажиллах болно. Би яг одоо үүнийг хэлж чадна id дараагийн удаа хуудсыг ачаалах үед өөрчлөгдөх болно. Тэмдэгтийн дараалал wtKI хуудас ачаалах бүрт динамикаар өөрчлөгддөг тул дараагийн хуудсыг дахин ачаалсны дараа үүнийг ашигласан код ашиггүй болно. Тиймээс XPath-ыг ойлгохын тулд хэсэг хугацаа зарцуулаарай. Энэ мэдлэг танд сайнаар үйлчлэх болно.

Гэсэн хэдий ч XPath сонгогчийг хуулах нь нэлээд энгийн сайтуудтай ажиллахад тустай байж болох бөгөөд хэрвээ та үүнд таатай байвал буруу зүйл байхгүй гэдгийг тэмдэглэх нь зүйтэй.

Одоо бүх хайлтын үр дүнг хэд хэдэн мөрөнд жагсаалт дотор авах шаардлагатай бол юу хийх талаар бодож үзье. Маш энгийн. Үр дүн бүр нь ангитай объект дотор байна resultWrapper. Бүх үр дүнг ачаалах нь доор үзүүлсэнтэй төстэй гогцоонд хийж болно.

Хэрэв та дээрх зүйлийг ойлгож байгаа бол бидний дүн шинжилгээ хийх кодын ихэнхийг хялбархан ойлгох хэрэгтэй гэдгийг тэмдэглэх нь зүйтэй. Энэ код ажиллаж байх үед бид ямар нэгэн замыг тодорхойлох механизм (XPath) ашиглан өөрт хэрэгтэй зүйлд (үнэндээ үр дүн нь ороосон элемент) ханддаг. Энэ нь элементийн текстийг авч, өгөгдлийг унших боломжтой объектод байрлуулахын тулд хийгддэг (эхлээд ашигласан). flight_containers, дараа нь - flights_list).

Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм
Эхний гурван мөрийг харуулсан бөгөөд бидэнд хэрэгтэй бүх зүйлийг тодорхой харж болно. Гэсэн хэдий ч бидэнд мэдээлэл олж авах илүү сонирхолтой аргууд байдаг. Бид элемент бүрээс өгөгдлийг тусад нь авах хэрэгтэй.

Ажилдаа явах!

Функц бичих хамгийн хялбар арга бол нэмэлт үр дүнг ачаалах явдал тул бид эндээс эхлэх болно. Би шалгалтад хүргэдэг үйлчилгээнд сэжиг төрүүлэхгүйгээр програмын мэдээлэл хүлээн авах нислэгийн тоог нэмэгдүүлэхийг хүсч байгаа тул хуудас гарч ирэх бүрт "Дэлгэрэнгүй үр дүнг ачаалах" товчийг дарна. Энэ кодонд та блок дээр анхаарлаа хандуулах хэрэгтэй try, заримдаа товчлуур зөв ачаалагддаггүй тул би үүнийг нэмсэн. Хэрэв танд ийм зүйл тохиолдвол функцийн кодонд энэ функцийн дуудлагыг тайлбарлана уу start_kayak, бид үүнийг доор авч үзэх болно.

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

Одоо, энэ функцийн талаар удаан хугацааны туршид дүн шинжилгээ хийсний дараа (заримдаа би санаа зовдог) хуудсыг хусах функцийг зарлахад бэлэн байна.

Дараах функцэд шаардлагатай ихэнх зүйлийг би аль хэдийн цуглуулсан page_scrape. Заримдаа буцаж ирсэн замын өгөгдлийг нэгтгэдэг тул би үүнийг салгах энгийн аргыг ашигладаг. Жишээлбэл, би хувьсагчийг анх удаа ашиглах үед section_a_list и section_b_list. Манай функц өгөгдлийн хүрээ буцаана flights_df, энэ нь бидэнд өөр өөр өгөгдлийг ангилах аргуудаас олж авсан үр дүнг салгаж, дараа нь нэгтгэх боломжийг олгодог.

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

Би кодыг ойлгомжтой болгохын тулд хувьсагчдыг нэрлэхийг оролдсон. -ээс эхэлдэг хувьсагчдыг санаарай a замын эхний шатанд хамаарах ба b - хоёр дахь нь. Дараагийн функц руу шилжье.

Дэмжих механизмууд

Бидэнд хайлтын нэмэлт илэрцүүдийг ачаалах функц болон тэдгээр үр дүнг боловсруулах функцтэй боллоо. Эдгээр хоёр функц нь өөрөө нээж болох хуудсуудыг хусахад шаардлагатай бүх зүйлийг хангадаг тул энэ нийтлэлийг энд дуусгах байсан. Гэхдээ бид дээр дурдсан зарим туслах механизмуудыг хараахан авч үзээгүй байна. Жишээлбэл, энэ нь имэйл болон бусад зүйлсийг илгээх код юм. Энэ бүгдийг функцээс олж болно start_kayak, үүнийг бид одоо авч үзэх болно.

Энэ функц нь хот, огнооны талаарх мэдээллийг шаарддаг. Энэ мэдээллийг ашиглан хувьсагчид холбоос үүсгэдэг kayak, энэ нь таныг асуулгад хамгийн сайн тохирох байдлаар эрэмбэлсэн хайлтын үр дүнг агуулсан хуудас руу хөтлөхөд ашиглагддаг. Эхний хусах сессийн дараа бид хуудасны дээд талд байгаа хүснэгтэд байгаа үнийн дүнтэй ажиллах болно. Тодруулбал, бид тасалбарын доод үнэ, дундаж үнийг олох болно. Энэ бүгдийг сайтаас гаргасан таамаглалын хамт цахим шуудангаар илгээх болно. Хуудасны зүүн дээд буланд харгалзах хүснэгт байх ёстой. Дашрамд хэлэхэд энэ хүснэгттэй ажиллах нь яг огноог ашиглан хайхад алдаа гаргаж болзошгүй тул энэ тохиолдолд хүснэгтийг хуудсан дээр харуулахгүй.

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

Би энэ скриптийг Outlook бүртгэл (hotmail.com) ашиглан туршиж үзсэн. Би үүнийг Gmail акаунттай зөв ажиллахын тулд туршиж үзээгүй, энэ цахим шуудангийн систем нэлээд түгээмэл боловч олон боломжит сонголтууд байдаг. Хэрэв та Hotmail хаяг ашигладаг бол бүх зүйл ажиллахын тулд код руу мэдээллээ оруулахад л хангалттай.

Хэрэв та энэ функцийн кодын тодорхой хэсгүүдэд яг юу хийж байгааг ойлгохыг хүсвэл тэдгээрийг хуулж, туршилт хийж болно. Кодтой туршилт хийх нь түүнийг жинхэнэ утгаар нь ойлгох цорын ганц арга зам юм.

Бэлэн систем

Одоо бид ярьсан бүх зүйлээ хийснийхээ дараа бид өөрсдийн функцүүдийг дууддаг энгийн гогцоо үүсгэж болно. Скрипт нь хэрэглэгчээс хот, огнооны талаарх мэдээллийг шаарддаг. Скриптийг байнга дахин ачаалснаар тест хийхдээ та энэ өгөгдлийг гар аргаар оруулахыг хүсэх магадлал багатай тул туршилтын хугацаанд холбогдох мөрүүдийг доороос нь тайлбаргүйгээр тайлбарлаж болно. скрипт нь хатуу кодлогдсон байна.

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

Скриптийг турших нь иймэрхүү харагдаж байна.
Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм
Скриптийг турших

Үр дүн

Хэрэв та өдий зэрэгт хүрсэн бол баяр хүргэе! Та одоо ажиллаж байгаа вэб хусагчтай болсон ч үүнийг сайжруулах олон арга замыг би харж байна. Жишээлбэл, үүнийг Twilio-тэй нэгтгэх боломжтой бөгөөд ингэснээр имэйлийн оронд текст мессеж илгээдэг. Та хэд хэдэн серверээс нэгэн зэрэг үр дүнг хүлээн авахын тулд VPN эсвэл өөр зүйл ашиглаж болно. Мөн сайтын хэрэглэгчийг хүн мөн эсэхийг шалгахад үе үе асуудал гардаг ч энэ асуудлыг шийдэж болно. Ямар ч байсан одоо та хүсвэл өргөжүүлж болох суурьтай боллоо. Жишээлбэл, Excel файлыг хэрэглэгч рүү имэйлийн хавсралт болгон илгээсэн эсэхийг шалгаарай.

Python бол аялах дуртай хүмүүст хямд тийз олох туслах юм

Зөвхөн бүртгэлтэй хэрэглэгчид санал асуулгад оролцох боломжтой. Нэвтрэх, гуйя.

Та вэб хусах технологи ашигладаг уу?

  • Тийм

  • Ямар ч

8 хэрэглэгч санал өгсөн. 1 хэрэглэгч түдгэлзсэн.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх