我可以让Selenium等待Xhr请求的完成

时间:2015-08-04 18:54:08

标签: python selenium xmlhttprequest

我试图为每辆车扫描定价数据,例如: http://www.leasingcar.dk/privatleasing/Citro%C3%ABn-C1/VTi-68-Feel

我在选择框“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

有没有办法检查请求是否已完成,或者值是否已刷新?

1 个答案:

答案 0 :(得分: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的隐藏元素。