Untitled
unknown
python
a year ago
10 kB
9
Indexable
from elems import Elems
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
import time
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.firefox.options import Options
from selenium import webdriver
from selenium.webdriver.firefox.service import Service as FirefoxService
from webdriver_manager.firefox import GeckoDriverManager
from typing import Optional, Any
from exceptions import ERRORS
from utilities import get_date_from_days, read_csv
import os
import csv
import pandas as pd
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QLabel, QFileDialog,
QLineEdit, QCalendarWidget, QPushButton, QCheckBox, QTabWidget, QMessageBox)
from datetime import datetime
class BookingBot(Elems):
FIELD_NAMES = ["NAME", "PRICE", 'START_DATE', 'END_DATE']
def __init__(self, driver: webdriver.Firefox) -> None:
self.driver = driver
self.errors = []
self.filename = str(round(time.time(), 0)).replace(".0", "")
def open_page(self, url) -> Optional[Any]:
self.driver.get(url)
def div_control(self):
try:
self.wait_element(self.CARD_DIV)
except NoSuchElementException:
self.is_continue = False
self.errors.append({"code": 1000,
"message": ERRORS.get(1000)})
def get_price(self):
try:
div = self.driver.find_element(*self.CARD_DIV)
return div.find_element(*self.PRICE_SPAN).text
except NoSuchElementException:
return "Rezervasyon Bulunamadi"
def record_to_csv(self, data: list):
if not os.path.exists(f"datas/{self.filename}.csv"):
with open(f"./datas/{self.filename}.csv", 'w', encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=self.FIELD_NAMES)
writer.writeheader()
with open(f"./datas/{self.filename}.csv", "a+", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=self.FIELD_NAMES)
writer.writerow(
{"NAME": data[0], "PRICE": data[1], "START_DATE": data[2], "END_DATE": data[3]})
def wait_element(self, selector, time=10):
element = WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located(
selector)
)
return element
def close_driver(self):
self.driver.quit()
def csv_summary(self, adult_count, child_count, room_count):
# CSV dosyasını oku
df = pd.read_csv(f"./datas/{self.filename}.csv")
# Euro simgesini ve binlik ayracı kaldır
df['PRICE'] = df['PRICE'].replace({'€': ' '}, regex=True)
df['PRICE'] = df['PRICE'].str.replace(
r'(?<=\d)\.(?=\d{3})', '', regex=True)
# "Rezervasyon Bulunamadı" olanları temizle ve sayısal değere dönüştür
# Geçersiz değerleri NaN ile değiştirir
df['PRICE'] = pd.to_numeric(df['PRICE'], errors='coerce')
# NaN olanları kaldır
df = df.dropna(subset=['PRICE'])
# Pozitif fiyatları filtrele
filtered_df = df[df['PRICE'] > 0]
if filtered_df.empty:
print("Filtrelenmiş veri çerçevesi boş. Fiyat verisi içermiyor.")
return
# Ortalama fiyat, en düşük ve en yüksek fiyatı hesapla
average_price = filtered_df['PRICE'].mean()
min_price = filtered_df['PRICE'].min()
max_price = filtered_df['PRICE'].max()
std_dev = filtered_df['PRICE'].std()
# En düşük ve en yüksek fiyatlı otel isimlerini bulma
min_price_hotel = filtered_df.loc[filtered_df['PRICE']
== min_price, 'NAME'].values
max_price_hotel = filtered_df.loc[filtered_df['PRICE']
== max_price, 'NAME'].values
if min_price_hotel.size == 0 or max_price_hotel.size == 0:
print("En düşük veya en yüksek fiyatlı otel bilgisi bulunamadı.")
return
# İlk otel adını al (Çoğunlukla tek bir otel olur ama bu, birden fazla otel varsa en iyisidir)
min_price_hotel_name = min_price_hotel[0]
max_price_hotel_name = max_price_hotel[0]
# Summary metni oluştur
summary = (f"\nFiltreler:\nSorgu Tarihi: {datetime.today()}\nYetiskin Sayisi: {adult_count}\nCocuk Sayisi: {child_count}\nOda Sayisi: {room_count}\n\n"
f"Ortalama Fiyat: {average_price:.2f}\n"
f"Standart Sapma: {std_dev:.2f}\n"
f"En Dusuk Fiyat: {min_price:.2f} (En Dusuk Fiyatli Otel: {
min_price_hotel_name})\n"
f"En Yuksek Fiyat: {max_price:.2f} (En Yuksek Fiyatli Otel: {max_price_hotel_name})")
# Sonuçları dosyaya yaz
with open(f"./datas/{self.filename}.csv", 'a', encoding="utf-8") as file:
file.write(summary)
def csv_to_excel(self):
# CSV dosyasının yolu
csv_file = f"./datas/{self.filename}.csv"
# CSV dosyasını pandas ile oku
df = pd.read_csv(csv_file)
# Excel dosyasının yolu
excel_file = f"./datas/{self.filename}.xlsx"
# CSV'yi Excel'e dönüştür
df.to_excel(excel_file, index=False)
# CSV dosyasını sil
if os.path.exists(csv_file):
os.remove(csv_file)
else:
print(f"{csv_file} bulunamadi.")
def run_bot(adult_count, child_count, room_count, start_date, end_date, background):
firefox_options = Options()
firefox_options.set_preference(
"dom.disable_open_during_load", True) # Pop-up'ları engelle
firefox_options.set_preference("dom.webnotifications.enabled", False)
if background:
firefox_options.add_argument("--headless")
driver = webdriver.Firefox(
service=FirefoxService(GeckoDriverManager().install()),
options=firefox_options
)
driver.maximize_window()
bot = BookingBot(driver=driver)
data = read_csv("./new_urls.csv")
for name, url in data:
url = url.replace("||start_date||", start_date).replace(
"||end_date||", end_date).replace(
"||adult_count||", adult_count).replace(
"||children_count||", child_count).replace(
"||room_count||", room_count)
bot.open_page(url)
time.sleep(1)
if bot.errors:
price = str(bot.errors)
else:
price = bot.get_price()
bot.record_to_csv([name, price, start_date, end_date])
time.sleep(2)
bot.driver.quit()
bot.csv_summary(adult_count, child_count, room_count)
bot.csv_to_excel()
def check_inputs():
adult_count = yetiskin_input.text()
child_count = cocuk_input.text()
room_count = oda_input.text()
start_date = start_calendar.selectedDate().toString("yyyy-MM-dd")
end_date = end_calendar.selectedDate().toString("yyyy-MM-dd")
background = background_checkbox.isChecked()
valid = True
if not adult_count or not child_count or not room_count:
QMessageBox.warning(window, 'Hata', 'Tüm alanları doldurun!')
valid = False
if end_date < start_date:
QMessageBox.warning(
window, 'Hata', 'Çıkış tarihi giriş tarihinden önce olamaz!')
valid = False
if valid:
# run_bot fonksiyonuna takvimden seçilen tarihleri de gönderiyoruz
run_bot(adult_count, child_count, room_count,
start_date, end_date, background)
QMessageBox.information(window, 'Başarılı', 'Bot çalıştırıldı!')
QApplication.quit()
if __name__ == "__main__":
app = QApplication([])
window = QWidget()
window.setWindowTitle('Booking')
tab_widget = QTabWidget()
general_tab = QWidget()
general_layout = QVBoxLayout()
# Kaç gün sonrası input alanı
day_label = QLabel('Kaç gün sonrası: ')
day_input = QLineEdit()
# Yetişkin sayısı input alanı
yetiskin_label = QLabel('Yetişkin sayısı (1-30):')
yetiskin_input = QLineEdit()
# Çocuk sayısı input alanı
cocuk_label = QLabel('Çocuk sayısı (1-10):')
cocuk_input = QLineEdit()
# Oda sayısı input alanı
oda_label = QLabel('Oda sayısı (1-30):')
oda_input = QLineEdit()
# Genel bilgileri layout'a ekle
general_layout.addWidget(yetiskin_label)
general_layout.addWidget(yetiskin_input)
general_layout.addWidget(cocuk_label)
general_layout.addWidget(cocuk_input)
general_layout.addWidget(oda_label)
general_layout.addWidget(oda_input)
general_tab.setLayout(general_layout)
# İkinci sekme (Tarih Seçimi)
date_tab = QWidget()
date_layout = QVBoxLayout()
# Başlangıç ve bitiş tarihi için QCalendarWidget
start_calendar_label = QLabel('Başlangıç Tarihi Seçin:')
start_calendar = QCalendarWidget()
start_calendar.setGridVisible(True)
end_calendar_label = QLabel('Bitiş Tarihi Seçin:')
end_calendar = QCalendarWidget()
end_calendar.setGridVisible(True)
# Takvim widget'larını layout'a ekle
date_layout.addWidget(start_calendar_label)
date_layout.addWidget(start_calendar)
date_layout.addWidget(end_calendar_label)
date_layout.addWidget(end_calendar)
date_tab.setLayout(date_layout)
# Üçüncü sekme (Diğer Ayarlar)
other_tab = QWidget()
other_layout = QVBoxLayout()
# Arka planda çalıştırma için QCheckBox
background_checkbox = QCheckBox("Arka planda çalıştırılsın mı?")
# Gönder butonu
submit_button = QPushButton('Gönder')
submit_button.clicked.connect(check_inputs)
# Diğer ayarları layout'a ekle
other_layout.addWidget(background_checkbox)
other_layout.addWidget(submit_button)
other_tab.setLayout(other_layout)
# Sekmeleri QTabWidget'e ekle
tab_widget.addTab(general_tab, "Genel Bilgiler")
tab_widget.addTab(date_tab, "Tarih Seçimi")
tab_widget.addTab(other_tab, "Botu Başlat")
# Ana layout oluştur ve tab widget'ı ekle
layout = QVBoxLayout()
layout.addWidget(tab_widget)
window.setLayout(layout)
window.show()
app.exec_()
Editor is loading...
Leave a Comment