2015-08-04 4 views
0

я пытаюсь скрести данные о ценах на каждые многочисленные транспортные средства, например: http://www.leasingcar.dk/privatleasing/Citro%C3%ABn-C1/VTi-68-FeelМогу ли я сделать Селен ждать завершения XHR запросы

I'm итерацию коробки отбора «leasingPeriod», а затем «annualMileage ».

Моя проблема заключается в том, что к моменту возвращения запроса я уже очищал данные, поэтому каждый раз получаю одну и ту же цену. Я пытался использовать неявное ожидание, но оно, похоже, не имеет никакого эффекта? Я также пытался дождаться завершения вызовов ajax, но безрезультатно.

Мой код выглядит следующим образом:

enter code# -*- coding: utf-8 -*- 
from selenium import webdriver 
from selenium.webdriver.support.select import Select 
from selenium.common.exceptions import StaleElementReferenceException, WebDriverException 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.wait import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 
import unittest 

class DataTest(unittest.TestCase): 
    def setUp(self): 
     self.driver = webdriver.Firefox() 
     self.driver.get("http://www.leasingcar.dk/privatleasing") 

    def testData(self): 
     driver = self.driver 

     vehicleLinksList = [] 

     vehicleLinks =driver.find_elements_by_css_selector('div.vehicle[data-nice_url]') 
     for linkElement in vehicleLinks: 
      vehicleLinksList.append(linkElement.get_attribute("data-nice_url")) 

     for link in vehicleLinksList: 
     fullUrl = "" 
     fullUrl = "http://www.leasingcar.dk" + str(link) 
     driver.get(fullUrl) 

     leasingPeriodElements = driver.find_element_by_css_selector("select[id=leasingPeriod]") #get the select element 
     periodsOptions = leasingPeriodElements.find_elements_by_tag_name("option") #get all the options into a list 

     mileageElements = driver.find_element_by_css_selector("select[id=annualMileage]") #get the select element 
     mileageOptions = mileageElements.find_elements_by_tag_name("option") #get all the options into a list 

     periodOptionsList = [] 
     mileageOptionList = [] 

      for option in periodsOptions: 
       periodOptionsList.append(option.get_attribute("value")) 

      for option in mileageOptions: 
       mileageOptionList.append(option.get_attribute("value")) 

      for optionValue in periodOptionsList: 
       print "starting loop on option %s" % optionValue 
       leasingPeriodElement = Select(driver.find_element_by_css_selector("select[id=leasingPeriod]")) 
       leasingPeriodElement.select_by_value(optionValue) 

       for mileageValue in mileageOptionList: 

        mileageElement = Select(driver.find_element_by_css_selector("select[id=annualMileage]")) 
        mileageElement.select_by_value(mileageValue) 

        #driver.implicitly_wait(10) 
        #WebDriverWait(driver, 10).until(ajax_complete, "Timeout waiting for page to load") 

        wait = WebDriverWait(driver, 10) 
        price = wait.until(wait_for_visible_element_text_to_contain((By.CSS_SELECTOR, "span.total-price"), "Kr.")) 

        print price.text 

        #driver.refresh() 
        #driver.implicitly_wait(10) 

def tearDown(self): 
     self.driver.quit() 


if __name__ == '__main__': 
    unittest.main() 


class wait_for_visible_element_text_to_contain(object): 
    def __init__(self, locator, text): 
     self.locator = locator 
     self.text = text 

    def __call__(self, driver): 
     try: 
      elements = EC._find_elements(driver, self.locator) 
      for element in elements: 
       if self.text in element.text and element.is_displayed(): 
        return element 
     except StaleElementReferenceException: 
      return False 

def ajax_complete(driver): 
    try: 
     return 0 == driver.execute_script("return jQuery.active") 
    except WebDriverException: 
     pass 

Есть ли способ, чтобы проверить, были ли завершены запросы, или если значение было обновилась?

ответ

0

Франк,

Используйте explicit wait, чтобы определить, когда «период лизинга» изменения в таблице данных. Что-то вроде:

from selenium.webdriver.support.ui import WebDriverWait 

xpath = "//div[@class='data-last']/span[@class='period']" 

for elm in driver.find_elements_by_xpath(xpath): 
    if elm.is_displayed(): 
     WebDriverWait(driver, 10).until(
      lambda _: elm.text == "48" 
     ) 

Примечания: Я должен был использовать find_elements_by_xpath и проверить, если элементы будут отображаться, так есть скрытый элемент с таким же XPath.

+0

благодарит за ответ. Я не думаю, что я сделал себе достаточно ясно. Моя проблема заключается в том, что ежегодный пробег изменяется от 15 000 км до 20 000 км и отправляется запрос на новую цену, я очищаю данные до того, как будет возвращена новая цена. Мне нужно как-то отложить процесс до тех пор, пока некоторые данные страницы не будут обновлены? – Frank

+0

Тогда вы бы сделали то же самое для пробега. Когда вы настраиваете окно выбора, просто подождите, пока значение индикатора пробега изменится с помощью WebDriverWait.until и поиска скорректированного значения. Selenium целенаправленно не позволяет вам видеть бэкэнд системы и что происходит. Это сделано для пользовательских приемочных испытаний. Пользователи не собираются знать/заботиться о том, что существует запрос AJAX, только что изменившиеся значения изменились. –

Смежные вопросы