python - 廉价航班项目/按钮元素返回“NoneType”对象错误 Selenium python
问题描述
我正在做一个小的 Selenium 项目,它可以帮助我随时随地找到便宜的航班。我有一个 Button 元素的问题。不能让它工作。
代码: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()
选择机场后,我将切换到包含接下来几天机票价格的选项卡。有“上一个”和“下一个”两个按钮。两者都返回空或非类型。
这是我有问题的元素。 “按钮下一步”的xpath:
self.click(By.XPATH, '//*[@id="outbound-fare-selector"]/div[2]/div[1]/button[2]')
函数“self.isElementPresent”返回 True,因此元素存在。
我尝试通过.Xpath、CSS_SELECTOR、(x,y location)、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)
这与我在浏览器控制台中得到的数字相同,所以如果我理解得很好,看起来什么都没有隐藏。我也尝试过 execute_script,但效果不佳。
我没有更多的想法,所以非常感谢任何帮助。
解决方案
您的方法find
总是返回 None 因此错误'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()
希望这对你有帮助!
推荐阅读
- python - 组合中这个继承问题的解决方案
- ssl - SSL 证书和添加 CA 根证书
- local-storage - 从待办事项列表+本地存储中删除任务
- python - 熊猫图中的基本趋势线
- numpy - 如何矢量化将 PyTorch 张量中的所有非零值复制到最左侧位置而没有任何间隙的操作?
- c++ - 比较字符总是输出假,即使它应该是真的
- python - 如何使用 Python zeep 从具有多个绑定的 Python Soap 客户端访问所有 Web 服务方法
- rest - BitBucket 服务器 Rest API 调用以获取 2 个标签之间合并的拉取请求列表
- javascript - WebAudio API:是否可以使用 StereoPanner 节点数据导出 AudioBuffer?
- visual-studio-code - 如何隐藏 VS Code 在花括号后放置的竖线?