Невозможно щелкнуть по знакам на карте
Я написал сценарий на 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()
Знаки, видимые на этой карте:
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 секунд