Selenium: дождитесь изменения текста в WebElement
Я использую selenium
С Python 2.7. чтобы получить содержимое из окна поиска на веб-странице. Поле поиска динамически извлекает и отображает результаты в самом поле.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import pandas as pd
import re
from time import sleep
driver = webdriver.Firefox()
driver.get(url)
df = pd.read_csv("read.csv")
def crawl(isin):
searchkey = driver.find_element_by_name("searchkey")
searchkey.clear()
searchkey.send_keys(isin)
sleep(11)
search_result = driver.find_element_by_class_name("ac_results")
names = re.match(r"^.*(?=(())", search_result.text).group().encode("utf-8")
product_id = re.findall(r"((?<=()[0-9]*)", search_result.text)
return pd.Series([product_id, names])
df[["insref", "name"]] = df["ISIN"].apply(crawl)
print df
соответствующая часть кода может быть найдена в разделе def crawl(isin):
- программа вводит, что искать в поле поиска (коробка плохо названа как
searchkey
). - затем
sleep()
и ждет содержимого, чтобы показать в выпадающее поле поля поискаac_results
. - затем получает две переменные
insrefs
иnames
С помощью регулярных выражений.
вместо sleep()
, Я хотел бы, чтобы он ждал содержимого в WebElement ac_results
загрузить.
поскольку он будет постоянно использовать поле поиска для получения новых данных, введя новые условия поиска из списка, можно было бы использовать регулярное выражение для определения, когда есть новое содержимое в ac_results
это не идентично предыдущему содержание.
есть ли способ для этого? Важно отметить, что содержимое в поле поиска динамически загружается, поэтому функция должна будет распознать, что что-то изменилось в WebElement.
2 ответов
вам нужно применить Явное Ждать концепции. Е. Г. подождите, пока элемент станет видимым:
wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located((By.CLASS_NAME, 'searchbox')))
здесь, он будет ждать до 10 секунд проверка видимости элемента каждые 500 мс.
существует набор встроенных ожидаемых условий для ожидания, и также легко написать свой пользовательское ожидаемое состояние.
FYI, вот как мы подошли к нему после мозгового штурма это в чате. Мы ввели пользовательское ожидаемое условие, которое будет дождитесь изменения текста элемента. Это помогло нам определить, когда появляются новые результаты поиска:
import re
import pandas as pd
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import _find_element
class text_to_change(object):
def __init__(self, locator, text):
self.locator = locator
self.text = text
def __call__(self, driver):
actual_text = _find_element(driver, self.locator).text
return actual_text != self.text
#Load URL
driver = webdriver.Firefox()
driver.get(url)
#Load DataFrame of terms to search for
df = pd.read_csv("searchkey.csv")
#Crawling function
def crawl(searchkey):
try:
text_before = driver.find_element_by_class_name("ac_results").text
except NoSuchElementException:
text_before = ""
searchbox = driver.find_element_by_name("searchbox")
searchbox.clear()
searchbox.send_keys(searchkey)
print "\nSearching for %s ..." % searchkey
WebDriverWait(driver, 10).until(
text_to_change((By.CLASS_NAME, "ac_results"), text_before)
)
search_result = driver.find_element_by_class_name("ac_results")
if search_result.text != "none":
names = re.match(r"^.*(?=(\())", search_result.text).group().encode("utf-8")
insrefs = re.findall(r"((?<=\()[0-9]*)", search_result.text)
if search_result.text == "none":
names = re.match(r"^.*(?=(\())", search_result.text)
insrefs = re.findall(r"((?<=\()[0-9]*)", search_result.text)
return pd.Series([insrefs, names])
#Run crawl
df[["Insref", "Name"]] = df["ISIN"].apply(crawl)
#Print DataFrame
print df
Я предлагаю использовать ожидаемое условие ниже в WebDriverWait.
WebDriverWait(driver, 10).until(
text_to_be_present_in_element((By.CLASS_NAME, "searchbox"), r"((?<=\()[0-9]*)")
)
или
WebDriverWait(driver, 10).until(
text_to_be_present_in_element_value((By.CLASS_NAME, "searchbox"), r"((?<=\()[0-9]*)")
)