Python Selenium JS выдает не все данные
При использовании Selenium сайт выдает только одно значение. Остальные игнорируются. Поиск идет только по XPATH, причем вывод данных может быть разный при следующем запуске. Поиск по классу выдает ошибку. На сайте JS, видимо он не успевает подгружаться, sleep ничего не дал
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
options = webdriver.ChromeOptions()
options.add_argument(
"user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
)
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver_file = "/Users/idim/PycharmProjects/rentaboat/chromedriver" # path to ChromeDriver
url = "https://www.boataround.com/ru/search?destinations=turkey&checkIn=2023-10-07&checkOut=2023-10-14&category=sailing-yacht&toilets=2-&year=2015-&boatLength=9-14&maxSleeps=6-&price=-300000&cabins=3-"
def get_source_html(url):
s = Service("/Users/idim/PycharmProjects/rentaboat/chromedriver")
driver = webdriver.Chrome(service=s, options=options)
# driver.maximize_window()
try:
driver.get(url=url)
time.sleep(3)
number_boats = int(driver.find_element(By.XPATH,'//*[@id="search-autogen"]/h2').text.split()[-1])
# number_pages = driver.find_element(By.XPATH, '//*[@id="search"]/div[3]/div[2]/section[2]/div/div/ul/li[4]/a')
# print(number_pages.text)
print(f'Всего яхт: {number_boats}')
for i in range(1, 19):
boat_name = driver.find_element(
By.XPATH, f'/html/body/main/div[2]/div/div[3]/div[2]/section[1]/ul/li[{i}]/a/div[2]/h3'
)
boat_price = driver.find_element(
By.XPATH, f'//*[@id="search"]/div[3]/div[2]/section[1]/ul/li[{i}]/a/div[3]/div[2]/div[3]/div[1]/div/span[2]')
print(f'{i} : {boat_name.text} --> {boat_price.text}')
except Exception as _ex:
print(_ex)
finally:
driver.close()
driver.quit()
def main():
get_source_html(url=url)
if __name__ == '__main__':
main()
Ответы (2 шт):
Автор решения: Сергей Ш
→ Ссылка
У меня ваш код работает
from bs4 import BeautifulSoup
from selenium import webdriver
import time
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service as ChromeService
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
url = "https://www.boataround.com/ru/search?destinations=turkey&checkIn=2023-10-07&checkOut=2023-10-14" \
"&category=sailing-yacht&toilets=2-&year=2015-&boatLength=9-14&maxSleeps=6-&price=-300000&cabins=3-"
driver.get(url)
Проверка статуса загрузки страницы
page_loaded = driver.execute_script("return document.readyState")
if page_loaded == "complete":
print("Страница полностью загружена")
Скрол страницы до конца (иногда помогает)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(3)
BeautifulSoup. Если страница не прогрузилась мы получим бублик.
time.sleep(3)
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
for i, link in enumerate(soup(class_="search-result-wrapper"), 1):
boat_name = link.find(class_="mr-2").text
boat_price = link.find(class_="ml-2").text
print(f'{i} : {boat_name} --> {boat_price}')
Альтернатива селенимум, requests. API сайта.
import requests
params = {
'destinations': 'turkey',
'category': 'sailing-yacht',
'page': '1',
'checkIn': '2023-10-07',
'checkOut': '2023-10-14',
'cabins': '3-',
'toilets': '2-',
'year': '2015-',
'boatLength': '9-14',
'price': '-300000',
'lang': 'ru_RU',
'sort': 'rank',
'currency': 'RUB',
'maxSleeps': '6-',
'loggedIn': '0',
}
response = requests.get('https://api.boataround.com/v1/search', params=params)
#print(response.json()['data'][0]['data'])
for i, res in enumerate(response.json()['data'][0]['data'], 1):
boat_name = res['title']
boat_price = res['price']
print(f'{i} : {boat_name} --> {boat_price}')
Автор решения: dim
→ Ссылка
Добавил скролинг вниз страницы и проблема решилась.
for p in range(0, 1080, 50):
driver.execute_script(f"window.scrollTo(0, window.scrollY + {p})")
time.sleep(random.choice([1, 2]))