sor*_*tas 8 python selenium webdriver python-3.x selenium-webdriver
我使用 Selenium 和 Python 来解析来自数据库站点的搜索结果。搜索输出是动态的,因此,当我输入新请求时,页面不会重新加载,但搜索结果是新的。
问题是 Selenium 不会更新 WebDriver DOM 数据,所以下次我尝试类似driver.find_elements_by_class_name('query_header')我从以前的搜索请求和StaleError.
使用WebDriverWait(driver, timeout).until(element_present)没有帮助。元素在那里(所有搜索结果块都有相同的类、名称等),但它们很旧:)
我通过driver.refresh()在每次请求后重新加载页面来修复它,但它看起来有点不自然+双重请求。
有没有办法刷新 Selenium DOM 数据,这样我就可以在find_elements不重新加载页面的情况下获得新元素?
在不知道页面内容的情况下,很难为您的问题制定解决方案。
当从您的webdriver硒代码选择元素,在页面上这样做,因为它的加载,当你选择的代码执行,这意味着页面不没有需要,以获取新的元素被重新加载。相反,您的问题似乎是页面上尚不存在这些元素,这意味着当您的选择器尝试获取元素的新副本时,搜索结果可能尚未加载。
一个简单的解决方案是增加开始搜索和选择搜索结果之间的等待时间,为页面加载搜索结果留出时间
from selenium import webdriver
import time
# Load page
driver = webdriver.Firefox()
driver.get('https://www.example.com')
# Begin search
driver.find_element_by_tag_name('a').click()
# Wait for search results to load
time.sleep(5)
# Retrieve search results
results = driver.find_elements_by_class_name('result')
Run Code Online (Sandbox Code Playgroud)
这样做的缺点是它实际上取决于网络 QoS 以及搜索查询在您的页面上执行所需的时间。
一个更复杂但规范的解决方案是等待页面加载搜索结果,可能通过检查 Ajax 搜索加载图标或查看结果是否更改。一个很好的起点是查看Selenium中的WebDriverWait。
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
# Load page
driver = webdriver.Firefox()
driver.get('https://www.example.com')
# Begin search
driver.find_element_by_tag_name('a').click()
# Wait for search results to load
WebDriverWait(driver, 30).until(
expected_conditions.invisibility_of_element_located((By.ID, 'ajax_loader'))
)
# Retrieve search results
results = driver.find_elements_by_class_name('result')
Run Code Online (Sandbox Code Playgroud)
这种方法的缺点是可能需要很多时间来弄清楚如何让它工作,并且需要为您想要等待更新的每个页面定制它。
您提到这种方法似乎对您不起作用。对此的建议是(如果它不会破坏页面)在等待新结果加载之前操作 DOM 预搜索以清除任何现有结果或与您的选择器匹配的元素。WebDriverWait在等待与搜索结果的选择器匹配的元素存在时,这应该可以解决 Selenium 的问题。
driver.execute_script("el = document.getElementById('#results');el.parentElement.removeChild(el)")
Run Code Online (Sandbox Code Playgroud)
此外,由于您提到不应重新加载页面,可能是您的页面使用 Ajax 加载搜索结果,然后使用 JavaScript 修改 DOM。检查网络流量(大多数浏览器的 DevTools 应该有一个“网络”选项卡)并尝试反向工程网站如何发送搜索查询和解析数据可能很有用。
import requests
# Search term (birds)
term = 'ja'
# Send request
request = requests.get('https://jqueryui.com/resources/demos/autocomplete/search.php?term=' + term)
# Print response
print(request.json())
Run Code Online (Sandbox Code Playgroud)
这可能会违反某些网站的 TOS 或政策(实际上这些方法中的任何一种都可能),因此请注意这一点,并且一开始可能很难找出如何在比 DOM 上加载的更低级别发送和解析请求在页面加载更传统的搜索结果之后。从好的方面来说,假设使用了类似 Ajax 的搜索,这可能是获得搜索结果的最佳(性能、可靠性)方式。
| 归档时间: |
|
| 查看次数: |
24228 次 |
| 最近记录: |