社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

johnnybigH • 5 年前 • 967 次点击  

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

代码: 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
 
967 次点击  
文章 [ 2 ]  |  最新文章 5 年前
Moshe Slavin johnnybigH
Reply   •   1 楼
Moshe Slavin johnnybigH    6 年前

有效的方法是:

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    6 年前

你的方法 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()

希望这对你有帮助!