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]*)")
)