无法点击地图上的标志

时间:2018-09-02 05:42:44

标签: python python-3.x selenium selenium-webdriver web-scraping

我已经用Python与硒相关联地编写了一个脚本,以单击地图上可用的每个标志。但是,当我执行脚本时,到达此行timeout exception时它将引发wait.until(EC.staleness_of(item))错误。

在点击该行之前,脚本应该已经单击一次,但是不能?如何周期性地单击该地图中的所有标志?

This is the site link

到目前为止,这是我的代码 (也许我正在尝试使用错误的选择器):

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

  

后脚本:我知道这是他们的API https://www.findapetwash.com/api/locations/getAll/,通过它我可以获取JSON内容,但我想坚持使用Selenium方式。谢谢。

2 个答案:

答案 0 :(得分:5)

我知道您曾经写过您不想使用API​​,但是使用Selenium从地图标记中获取位置似乎对此有些大材小用,相反,为什么不使用请求来调用其Web服务并解析返回json?

这是一个有效的脚本:

#command_players
RewriteRule ^command_players/([0-9]+)/?$ site/command_players.php?id=$1 [NC,L]



 if (password_verify($_POST['pass'], $results['pass'])) {
                                $_SESSION['command']= 'ok';
                                $_SESSION['id'] = $results['id'];
                                //redirect("command/list.php/$results[id]/");
                                redirect("/command_players/{$results['id']}/");
                            }

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

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)

有关其他可能的解决方法,请在此处查看已接受的答案:Make Selenium wait 10 seconds

答案 1 :(得分: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

也可以立即尝试,可能会起作用。