Невозможно щелкнуть по знакам на карте

Я написал сценарий на Python в сочетании с селеном, чтобы щелкнуть по каждому из знаков, доступных на карте. Однако, когда я выполняю свой скрипт, он выдает ошибку timeout exception при достижении этой строки wait.until(EC.staleness_of(item)).

Прежде чем ударить по этой строке, сценарий должен был щелкнуть один раз, но не смог? Как я могу щелкнуть по всем знакам на этой карте циклически?

Это ссылка на сайт.

Это мой код до сих пор (возможно, я пытаюсь с неправильными селекторами):

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

link = "https://www.findapetwash.com/"

driver = webdriver.Chrome()
driver.get(link)
wait = WebDriverWait(driver, 15)
for item in wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "#map .gm-style"))):
    item.click()
    wait.until(EC.staleness_of(item))
driver.quit()

Знаки, видимые на этой карте:

enter image description here

Post script: Я знаю, что это их API https://www.findapetwash.com/api/locations/getAll/ с помощью которого я могу получить контент JSON, но я хотел бы придерживаться способа Selenium. Благодарю.

Ответы

Ответ 1

Вы можете щелкнуть один за другим, используя Selenium, если по некоторым причинам вы не можете использовать API. Также можно извлекать информацию для каждого знака, не нажимая на них с помощью Selenium.

Здесь код, который нужно щелкнуть один за другим:

signs = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "li.marker.marker--list")))
for sign in signs:
     driver.execute_script("arguments[0].click();", sign)
     #do something

Попробуйте также без ожидания, вероятно, сработает.

Ответ 2

Я знаю, что вы написали, что не хотите использовать API, но использование Selenium для получения мест с маркеров карты не кажется хорошей практикой, и у вас могут возникнуть проблемы с этим, вместо этого, почему бы не позвонить их веб-службы с использованием запросов и разбора возвращенного json?

Вот рабочий сценарий:

import requests
import json

api_url='https://www.findapetwash.com/api/locations/getAll/'

class Location:
    def __init__(self, json):
        self.id=json['id']
        self.user_id=json['user_id']
        self.name=json['name']
        self.address=json['address']
        self.zipcode=json['zipcode']
        self.lat=json['lat']
        self.lng=json['lng']
        self.price_range=json['price_range']
        self.photo='https://www.findapetwash.com' + json['photo']

def get_locations():
    locations = []
    response = requests.get(api_url)
    if response.ok:
        result_json = json.loads(response.text)
        for location_json in result_json['locations']:
            locations.append(Location(location_json))

        return locations
    else:
        print('Error loading locations')
        return False

if __name__ == '__main__':
    locations = get_locations()
    for l in locations:
        print(l.name)

Селен

Если вы все еще хотите пойти по пути Selenium, вместо того, чтобы ждать загрузки всех элементов, вы можете просто остановить скрипт на несколько секунд или даже минуту, чтобы убедиться, что все загружено, это должно исправить исключение таймаута:

import time 

driver.get(link)
# Wait 20 seconds
time.sleep(20)

Для других возможных обходных решений см. Принятый ответ здесь: Сделать Selenium wait 10 секунд