无法点击地图上的标志

SIM*_*SIM 13 python selenium web-scraping python-3.x selenium-webdriver

我用Python编写了一个与selenium相关的脚本,点击地图中的每个标志.但是,当我执行我的脚本时,它会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()
Run Code Online (Sandbox Code Playgroud)

在该地图上可见的标志如:

在此输入图像描述

发布脚本:我知道这是他们https://www.findapetwash.com/api/locations/getAll/用来获取JSON内容的API ,但我想坚持使用Selenium方式.谢谢.

Ism*_*sma 5

我知道你写道你不想使用API​​但是使用Selenium从地图标记中获取位置似乎不是一个好习惯而且你可能会遇到问题,相反,为什么不打电话给他们的Web服务使用请求并解析返回的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)
Run Code Online (Sandbox Code Playgroud)

如果您仍然希望采用Selenium方式,而不是等到加载所有元素,您可以暂停脚本几秒钟甚至一分钟以确保所有内容都已加载,这应该可以解决超时异常:

import time 

driver.get(link)
# Wait 20 seconds
time.sleep(20)
Run Code Online (Sandbox Code Playgroud)

有关其他可能的解决方法,请参阅此处接受的答案:让Selenium等待10秒钟

  • OP明确表示他们宁愿不使用API​​并坚持使用Selenium Edit:现在看来已经解决了 (2认同)

Ser*_*ers 5

如果由于某些原因您无法使用API​​,则可以使用Selenium逐个单击.此外,还可以为每个符号提取信息,而无需使用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
Run Code Online (Sandbox Code Playgroud)

也可以不用等待尝试,也许会奏效.