我正在尝试编写一个网页编写程序:
1)在搜索栏中输入名称
2)按下
3)找到第一个搜索结果,这是指向另一个页面的链接
4)点击第一个结果
5)在结果页面上找到一个指定的元素
6)复制该元素
7)在PyCharm中打印该元素
8)对预装数组中的每个条目重复(设置为"名称")
以下是为此而设计的代码部分。
from selenium import webdriver
import time
import xlrd
driver = webdriver.Chrome("path")
i=0
while i < len(names):
a = names[i]
driver.set_page_load_timeout(25)
driver.get("https://www.healthgrades.com/")
driver.find_element_by_id("search-term-selector-child").send_keys(a)
driver.find_element_by_id("search-term-selector-
child").send_keys(u'\ue007')
driver.implicitly_wait(20)
first = driver.find_element_by_class_name('uCard__name')
first.click()
driver.implicitly_wait(20)
elem= driver.find_element_by_class_name("office-street1")
entry1 = elem.text
time.sleep(1)
print(entry1)
i += 1
当我运行程序时,看起来代码在该步骤中的元素成为链接之前完成了步骤4(第13行);我最常收到的错误是
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"class name","selector":"office-street1"}
我认为这意味着它通过find_element_by_class_name并执行点击。但是当我观看自动化网页时,我注意到下一页从未打开过。
为了解决这个问题,我在搜索uCard元素之前试图进行隐式等待(第15行),但我仍然遇到同样的错误。
其他尝试的解决方案:
使用显式等待等待uCard_name元素
使用每个循环清除缓存/删除搜索记录
使用WebDriverWait暂停程序
其他信息:
在Pycharm中工作,Python版本3.6
Windows 10,64位
答案 0 :(得分:0)
最佳做法是使用显式等待感兴趣的元素。通过这种方式,您可以在点击它或以其他方式与之交互之前知道它。
所以一定要添加这些导入:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome("path")
# Only need to do this once per session
driver.implicitly_wait(20)
i=0
while i < len(names):
a = names[i]
driver.set_page_load_timeout(25)
driver.get("https://www.healthgrades.com/")
driver.find_element_by_id("search-term-selector-child").send_keys(a)
driver.find_element_by_id("search-term-selector-child").send_keys(u'\ue007')
first = driver.find_element_by_class_name('uCard__name')
first.click()
timeout = 20
# Explicitly wait 20 seconds for the element to exist.
# Good place to put a try/except block in case of timeout.
elem = WebDriverWait(driver, timeout).until(
EC.presence_of_element_located(('className', 'office-street1'))
)
entry1 = elem.innerText
...