Skip to content

Commit dd57954

Browse files
authored
Merge pull request larymak#320 from shadowfaxx1/main
Trip booking Bot for the Website Booking.com
2 parents 606d6aa + f3a13ee commit dd57954

14 files changed

+265
-0
lines changed
Loading
253 Bytes
Binary file not shown.

WEB SCRAPING/bot/additional.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
def booking_count():
3+
# cz=ec.visibility_of_element_located((By.CSS_SELECTOR,'button[class="fc63351294 a822bdf511 e3c025e003 fa565176a8 f7db01295e c334e6f658 e1b7cfea84 d64a4ea64d"]'))
4+
# adult_btn=wait.until(cz)
5+
# time.sleep(0.1)
6+
# div_element2 = self.find_element(By.CLASS_NAME,"b2b5147b20")
7+
# class_div=child_btn=div_element2.find_element(By.CLASS_NAME,"e98c626f34")
8+
# child_btn=class_div.find_element(By.CSS_SELECTOR,"button.fc63351294.a822bdf511.e3c025e003.fa565176a8.f7db01295e.c334e6f658.e1b7cfea84.d64a4ea64d")
9+
# child_btn.click()
10+
11+
# Find the <div> element by class name
12+
13+
# div_child=self.find_element(By.CLASS_NAME,'b2b5147b20')
14+
# # children_btn=div_child.find_element(By.CSS_SELECTOR,(By.CSS_SELECTOR,'button[class="fc63351194 a822bdf511 e3c025e003 fa565176a8 f7db01295e c334e6f658 e1b7cfea84 d64a4ea64d"]'))
15+
# # children_btn=wait.until(cz)
16+
# children_btn = div_child.find_element(By.CSS_SELECTOR, 'button.fc63351194.a822bdf511.e3c025e003.fa565176a8.f7db01295e.c334e6f658.e1b7cfea84.d64a4ea64d')
17+
18+
# while(child):
19+
# children_btn.click()
20+
# time.sleep(0.02)
21+
# child-=1
22+
# time.sleep(0.1)
23+
24+
# room_btn=self.find_element(By.CSS_SELECTOR,'button[class="fc63351294 a822bdf511 e3c025e003 fa565176a8 f7db01295e c334e6f658 e1b7cfea84 d64a4ea64d"]')
25+
# if(rooms==1):
26+
# print("rooms adjusted")
27+
# else:
28+
# while(rooms):
29+
# room_btn.click()
30+
# time.sleep(0.02)
31+
# rooms-=1
32+
# print("rooms adjusted")

WEB SCRAPING/bot/booking/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# print("i will be first")
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

WEB SCRAPING/bot/booking/booking.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import types
2+
import typing
3+
from selenium import webdriver
4+
import booking.constants as cons
5+
from selenium.webdriver.common.by import By
6+
from selenium.webdriver.support.ui import WebDriverWait
7+
from selenium.webdriver.support import expected_conditions as ec
8+
import os
9+
from selenium.webdriver.common.keys import Keys as keys
10+
from booking.booking_filteration import booking_filter
11+
import time
12+
from booking.booking_report import booking_report
13+
from selenium.common.exceptions import StaleElementReferenceException, NoSuchElementException
14+
from prettytable import PrettyTable
15+
16+
class booking(webdriver.Chrome):
17+
18+
def __init__(self,driver_path=r"C:\Users\kaifk\lpth\selenium",teardown=False):
19+
self.teardown=teardown
20+
self.driver_path=driver_path
21+
os.environ['PATH']+=self.driver_path
22+
# options=webdriver.ChromeOptions()
23+
# options.add_experimental_option('excludeswitches',['enable-logging'])
24+
25+
super(booking,self).__init__()
26+
self.implicitly_wait(15)
27+
self.maximize_window()
28+
29+
def __exit__(self, exc_type, exc_val, exc_tb):
30+
if(self.teardown):
31+
self.quit()
32+
33+
def land_first_page(self):
34+
self.get(cons.base_url)
35+
36+
def cross_check(self):
37+
try:
38+
wait=WebDriverWait(self,15)
39+
condition = ec.visibility_of_element_located((By.CSS_SELECTOR,'button[aria-label="Dismiss sign-in info."]'))
40+
btn=wait.until(condition)
41+
btn.click()
42+
except Exception as e :
43+
time.sleep(0.2)
44+
45+
46+
47+
48+
49+
50+
def change_currency(self,currency=None):
51+
wait=WebDriverWait(self,15)
52+
# condition2 = ec.visibility_of_element_located((By.CSS_SELECTOR, 'button[data-testid="' + str('header-currency-picker-trigger') + '"]'))
53+
condition2 = ec.visibility_of_element_located((By.CSS_SELECTOR, 'button[data-testid="header-currency-picker-trigger"]'))
54+
currency_btn=wait.until(condition2)
55+
currency_btn.click()
56+
57+
selected_item=ec.visibility_of_element_located((By.CSS_SELECTOR,'button[class="fc63351294 ea925ef36a bf97d4018a ae8177da1f cddb75f1fd"]'))
58+
selected_item_btn=wait.until(selected_item)
59+
selected_item_btn.click()
60+
def select_searchbar(self,place_to_go):
61+
search_field=self.find_element(By.ID,":Ra9:")
62+
search_field.clear()
63+
time.sleep(0.5)
64+
search_field.send_keys(place_to_go)
65+
time.sleep(2)
66+
search_field.send_keys(keys.ENTER)
67+
def enter_dates(self,checkin,checkout):
68+
wait=WebDriverWait(self,15)
69+
condition2 = ec.visibility_of_element_located((By.CSS_SELECTOR, f'span[data-date="{checkin}"]'))
70+
checkin_date=wait.until(condition2)
71+
checkin_date.click()
72+
condition2 = ec.visibility_of_element_located((By.CSS_SELECTOR, f'span[data-date="{checkout}"]'))
73+
checkout_data=wait.until(condition2)
74+
checkout_data.click()
75+
def booking_count_inc(self,adult,child=None,rooms=None):
76+
wait=WebDriverWait(self,10)
77+
selector=self.find_element(By.CSS_SELECTOR,'button[data-testid="occupancy-config"]')
78+
selector.click()
79+
time.sleep(1)
80+
div_element = self.find_element(By.CLASS_NAME,"e98c626f34") # Find the <div> element by class name
81+
adult_btn = div_element.find_element(By.CSS_SELECTOR,"button.fc63351294.a822bdf511.e3c025e003.fa565176a8.f7db01295e.c334e6f658.e1b7cfea84.d64a4ea64d") # Find the button within the <div> using CSS selector
82+
83+
if(adult==1):
84+
adult_btn = div_element.find_element(By.CSS_SELECTOR,'button[class="fc63351294 a822bdf511 e3c025e003 fa565176a8 f7db01295e c334e6f658 e1b7cfea84 cd7aa7c891"]') # Find the button within the <div> using CSS selector
85+
adult_btn.click()
86+
87+
if(adult==2):
88+
print("guests added successfully")
89+
else:
90+
while(adult-2):
91+
adult_btn.click()
92+
time.sleep(0.02)
93+
adult-=1
94+
print("guests added successfully")
95+
# outer_div=self.find_element(By.CLASS_NAME , 'df856d97eb')
96+
# print(outer_div)
97+
98+
99+
100+
101+
def click_search(self):
102+
search_icon=self.find_element(By.CSS_SELECTOR,"button[class='fc63351294 a822bdf511 d4b6b7a9e7 cfb238afa1 c938084447 f4605622ad aa11d0d5cd']")
103+
search_icon.click()
104+
105+
def apply_filtration(self):
106+
filteration=booking_filter(driver=self)
107+
filteration.apply_star(4,5)
108+
filteration.sort_low_to_high()
109+
110+
def report_results(self):
111+
boxes=self.find_element(By.ID,"search_results_table")
112+
report=booking_report(boxes)
113+
table=PrettyTable(
114+
field_names=["Hotel Name", "Price per night","Star Rating"]
115+
116+
)
117+
table.add_rows(report.pull_attributes())
118+
print(table)
119+
120+
121+
122+
123+
124+
125+
126+
127+
128+
129+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from selenium.webdriver.remote.webdriver import WebDriver
2+
from selenium.webdriver.common.by import By
3+
from selenium.webdriver.support import expected_conditions as ec
4+
from selenium.webdriver.support.ui import WebDriverWait
5+
import time
6+
class booking_filter:
7+
def __init__(self,driver:WebDriver):
8+
self.driver=driver
9+
10+
11+
12+
13+
def apply_star(self,*stars):
14+
box=self.driver.find_element(By.CSS_SELECTOR,"div[data-filters-group='class']")
15+
star_child_elements=box.find_elements(By.CSS_SELECTOR,"*")
16+
for s in stars:
17+
time.sleep(0.2)
18+
for i in star_child_elements:
19+
if str(i.get_attribute('innerHTML')).strip() == f'{s} stars':
20+
i.click()
21+
def sort_low_to_high(self):
22+
low_price = self.driver.find_element(By.CSS_SELECTOR,'button[data-testid="sorters-dropdown-trigger"]')
23+
low_price.click()
24+
wait=WebDriverWait(self.driver,10)
25+
26+
condition=ec.visibility_of_element_located((By.CSS_SELECTOR,'button[data-id="class"]'))
27+
btn_sort=wait.until(condition)
28+
btn_sort.click()
29+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#file is going to include methods that will parse
2+
# the specific data that we need from each boxes
3+
from selenium.webdriver.remote.webelement import WebElement
4+
from selenium.webdriver.common.by import By
5+
6+
from selenium.common.exceptions import StaleElementReferenceException, NoSuchElementException
7+
8+
class booking_report:
9+
def __init__(self,boxes_sec:WebElement) -> None:
10+
self.boxes_sec=boxes_sec
11+
self.hotel_names=self.pull_deal_boxes()
12+
13+
def pull_deal_boxes(self):
14+
return self.boxes_sec.find_elements(By.CLASS_NAME,"a826ba81c4")
15+
16+
17+
def pull_attributes(self):
18+
collections=[]
19+
try:
20+
if len(self.hotel_names) > 0:
21+
for i in self.hotel_names:
22+
try:
23+
hotel_name_element = i.find_element(By.CSS_SELECTOR,"[data-testid='title']")
24+
hotel_name = hotel_name_element.get_attribute('innerHTML').strip()
25+
26+
hotel_price=i.find_element(By.CSS_SELECTOR,"span[data-testid='price-and-discounted-price']").get_attribute('innerHTML').strip()
27+
score_element = i.find_element(By.CSS_SELECTOR, "div[data-testid='review-score'] div[class='b5cd09854e d10a6220b4']")
28+
collections.append([hotel_name,hotel_price,score_element.text])
29+
30+
31+
32+
except StaleElementReferenceException:
33+
print("Stale element reference exception occurred while retrieving hotel name.")
34+
except NoSuchElementException:
35+
print("Hotel name element not found for this item.")
36+
else:
37+
collections.append([None,None,None])
38+
except StaleElementReferenceException:
39+
self.refresh()
40+
41+
return collections
42+

WEB SCRAPING/bot/booking/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
base_url="https://www.booking.com"
2+

WEB SCRAPING/bot/run.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from booking.booking import booking
2+
import time
3+
bot=booking()
4+
try:
5+
with bot:
6+
bot.land_first_page()
7+
print('exiting .......')
8+
bot.cross_check()
9+
bot.change_currency()
10+
bot.select_searchbar("New York")
11+
bot.enter_dates(checkin="2023-07-16",checkout="2023-07-21")
12+
bot.booking_count_inc(4,None,None)
13+
bot.click_search()
14+
bot.apply_filtration()
15+
bot.refresh()
16+
bot.report_results()
17+
18+
# print(len(bot.report_results()))
19+
20+
except Exception as e:
21+
if 'in PATH' in e:
22+
print("there is a problem at CLI ", e )
23+
print("add path as ")
24+
print("windows : PATH=%PATH%;C:PATH-TO-YOUR-FOLDER")
25+
else:
26+
raise
27+
28+
29+
time.sleep(100)
30+
bot.quit()

0 commit comments

Comments
 (0)