Impossível clique em sinais em um mapa

votos
0

Eu escrevi um script em python em associação com selênio para clicar em cada um dos sinais disponíveis em um mapa. No entanto, quando eu executar o meu script, ele lança timeout exceptionerro ao atingir esta linha wait.until(EC.staleness_of(item)).

No entanto, antes de bater essa linha, o script deve ter clicado uma vez, mas não conseguiu? Como posso clicar em todos os sinais em que o mapa ciclicamente?

Este é o link do site

Este é o meu código até agora (talvez, eu estou tentando com os seletores erradas):

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()
Publicado 02/09/2018 em 05:42
fonte usuário
Em outras línguas...                            


2 respostas

votos
5

Você pode clicar em um por um usando Selenium se, por algum motivo, você não pode usar API. Também é possível extrair informações de cada sinal, sem clicar sobre eles com selênio.

Aqui código de clicar um por um:

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

Tentar também sem esperar, provavelmente irá funcionar.

Respondeu 05/09/2018 em 19:43
fonte usuário

votos
5

Eu sei que você escreveu você não quiser usar a API mas usando Selenium para obter os locais do mapa de marcadores não parece ser uma boa prática e que são susceptíveis de ter problemas com ele, em vez disso, por que não fazer uma chamada para seu serviço web usando solicitações e analisar o JSON retornado?

Aqui está um programa de trabalho:

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)

Selênio

Se você ainda quer ir a maneira Selênio, em vez de esperar até que todos os elementos são carregados, você pode simplesmente parar o script por alguns segundos ou até um minuto para se certificar que tudo é carregado, isso deve corrigir a exceção timeout:

import time 

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

Para outras soluções possíveis, ver a resposta aceita aqui: Faça selênio aguarde 10 segundos

Respondeu 04/09/2018 em 07:33
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more