Python Selenium JS выдает не все данные

Рейтинг: 0Ответов: 2Опубликовано: 02.06.2023

При использовании 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()

Ответы

▲ 1

У меня ваш код работает

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}')
▲ 0

Добавил скролинг вниз страницы и проблема решилась.

for p in range(0, 1080, 50):
    driver.execute_script(f"window.scrollTo(0, window.scrollY + {p})")
    time.sleep(random.choice([1, 2]))