Py学习  »  Python

廉价航班项目/按钮元素返回“NoneType”对象错误Selenium python

johnnybigH • 4 年前 • 777 次点击  

我正在做一个小的硒方面的项目,这将帮助我找到便宜的航班,无论何时何地。 按钮元素有问题。不能成功。

代码: https://github.com/johnnybigH/wizzscrap

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.action_chains import ActionChains


class wizzScrap:

    def __init__(self, url):
        self.driver = None
        self.url = url
        self.by = None
        self.value = None

        self.web_element = None
        # self.find()


    def setUpDriver(self):
        #  Set up driver
        options = webdriver.ChromeOptions()
        options.add_argument('--ignore-certificate-errors')
        options.add_argument('--no-proxy-server')
        options.add_argument('--incognito')
        prefs = {"profile.default_content_setting_values.geolocation" :2}
        options.add_experimental_option("prefs",prefs)
        self.driver = webdriver.Chrome( 
                "/Users/adamke/Downloads/chromedriver", 
                options=options)
        return self.driver


    def startDriver(self):
        self.driver.get(self.url)


    def find(self, by, value):
        element = WebDriverWait(
            self.driver, 20).until(
            EC.visibility_of_element_located((by, value)))
        self.web_element = element
        return None        


    def inputText(self, text):
        return self.web_element.send_keys(text)


    def click(self, by, value):
        element = WebDriverWait(
            self.driver, 30).until(
            EC.element_to_be_clickable((by, value)))
        self.web_element = element
        element.click()
        return self.web_element


    def text(self):
        text = self.web_element.text
        return text


    def switch_tabs(self):
        #  Close unneded tab and focus on the main one
        WebDriverWait(self.driver, 20).until(
            EC.number_of_windows_to_be(2))

        mainWindow = self.driver.window_handles[1]  #  Thats the Tab we want
        self.driver.close()
        self.driver.switch_to.window(mainWindow)


    def isElementPresent(self, by, value):
        try:
            self.find(by, value)
        except NoSuchElementException:
            result = False
        else: 
            result = True
        print(result)


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


    def getDestArriv(self):
        #  Choose the Origin and Destination for your fly
        try:
            #  Origin
            self.click(By.XPATH, "//*[@id='search-departure-station']")
            self.inputText('Katowice')
            self.click(By.CSS_SELECTOR, 
            "strong[class='locations-container__location__name']")
            #  Arrival
            self.click(By.XPATH, "//*[@id='search-arrival-station']")
            self.inputText('malaga')
            self.click(By.CSS_SELECTOR, 
            "strong[class='locations-container__location__name']")
            #  Start searching
            self.click(By.CSS_SELECTOR, "button[data-test='flight-search-submit']")
        except Exception:
            print('Thats shitty code man, work on it!')



    def parse(self):
        self.setUpDriver()
        self.startDriver()
        self.getDestArriv()

        # Switch to the Tab that contains tickets prices for next few days
        self.switch_tabs()

        # Button "Next"
        self.isElementPresent(By.XPATH, '//*[@id="outbound-fare-selector"]/div[2]/div[1]/button[2]')
        self.click(By.XPATH, '//*[@id="outbound-fare-selector"]/div[2]/div[1]/button[2]')


url = 'https://wizzair.com'
Page = wizzScrap(url)
Page.parse()
Page.closeDriver()

在选择了机场之后,我将切换到包含未来几天机票价格的标签。有两个按钮“上一个”和“下一个”。 两者都返回空或非类型。

这是我有问题的元素。 “button next”的xpath:

self.click(By.XPATH, '//*[@id="outbound-fare-selector"]/div[2]/div[1]/button[2]')

函数“Endo.IsEngEngestOutlook”返回true,因此元素存在。

我尝试通过.Xpath、CSS_选择器(x,y位置)、ActionChain和其他一些方法与之交互,但没有任何效果。 我还通过执行以下操作返回96个元素:

button_test = self.driver.find_elements_by_tag_name('button')
    collection_of_buttons = []
    for button in button_test:
        collection_of_buttons.append(button)

    for button in collection_of_buttons:
        print(button)

这和我在浏览器控制台中得到的数字是一样的,所以如果我理解得很好的话,看起来没有什么是隐藏的。 我也试过执行脚本,但效果不太好。

我没有更多的想法,所以将非常感谢任何帮助。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/50600
 
777 次点击  
文章 [ 2 ]  |  最新文章 4 年前
Moshe Slavin johnnybigH
Reply   •   1 楼
Moshe Slavin johnnybigH    4 年前

有效的方法是:

self.driver.execute_script("return 
document.getElementsByClassName('flight-select__flight-date-picker__button 
flight-select__flight-date-picker__button--next')[0].click();")
Moshe Slavin johnnybigH
Reply   •   2 楼
Moshe Slavin johnnybigH    4 年前

你的方法 find 始终不返回,因此出现错误 'NoneType' object :

def find(self, by, value):
    element = WebDriverWait(
        self.driver, 20).until(
        EC.visibility_of_element_located((by, value)))
    self.web_element = element
    return None     

你应该做的是返回元素。。。

def find(self, by, value):
    element = WebDriverWait(
        self.driver, 20).until(
        EC.visibility_of_element_located((by, value)))
    self.web_element = element
    return self.web_element # or return element

另外,将XPath更改为更健壮的使用:

# Button "Next"
self.click(By.XPATH, '//button[@class="flight-select__flight-date-picker__button flight-select__flight-date-picker__button--next"]')

编辑:

你可以用 ActionChains 要使用偏移单击:

button_element = self.find(By.XPATH, '//button[@class="flight-select__flight-date-picker__button flight-select__flight-date-picker__button--next"]')
action = webdriver.common.action_chains.ActionChains(driver)
action.move_to_element_with_offset(button_element, 5, 5).click().perform()

希望这对你有帮助!