Selenium 项目代码的优化与重构之路,滚雪球学 Python 番外篇

举报
梦想橡皮擦 发表于 2021/08/19 22:05:23 2021/08/19
【摘要】 今天是持续写作的第 31 / 100 天。如果你有想要交流的想法、技术,欢迎在评论区留言。本篇文章主要承接的是《用 Selenium 搞定自动化测试项目,途牛搜机票。》 ,本文将对其代码进行优化与重构。@[toc] 封装元素定位函数Selenium 中,经常需要复用某些元素获取的方法,毕竟每次都 find_element_by_xxx 有点太繁琐了。我们可以将一些常用的方法进行二次封装,在弄...

今天是持续写作的第 31 / 100 天。
如果你有想要交流的想法、技术,欢迎在评论区留言。

本篇文章主要承接的是《用 Selenium 搞定自动化测试项目,途牛搜机票。》 ,本文将对其代码进行优化与重构。

@[toc]

封装元素定位函数

Selenium 中,经常需要复用某些元素获取的方法,毕竟每次都 find_element_by_xxx 有点太繁琐了。

我们可以将一些常用的方法进行二次封装,在弄一个简单的函数出来。

from selenium import webdriver
import selenium
from selenium.webdriver.common.action_chains import ActionChains


# 通过 ID  获取元素
def id(element):
    return driver.find_element_by_id(element)

# 通过 CSS 获取元素
def css(element):
    return driver.find_element_by_css_selector(element)

# 通过 name 获取
def name(element):
    return driver.find_element_by_name(element)

添加几个函数之后,就可以对代码进行重构了。对比一下修改前与修改后的代码如下。

其它的一些内容,可以自己在进行进一步的封装,例如 find_element_by_xpath 方法,执行 JS 的方法 driver.execute_script

提炼函数到单独的文件中

函数写完之后,但是还是与所有的 Python 代码混合在一起,可以通过代码分层,将一些函数提炼到一个单独的文件中。例如可以将上文写的几个函数提炼到一个 functions.py 文件中。

functions.py 文件

该文件主要用于编写项目中用到的通用函数,可以重复在其它文件中进行使用,而不用在重复编写。

from selenium import webdriver

driver =  webdriver.Firefox()
def id(element):
    return driver.find_element_by_id(element)

# 通过 CSS 获取元素
def css(element):
    return driver.find_element_by_css_selector(element)

def return_driver():
    return driver

注意,我将 driver 获取对象也封装成了一个函数。最终形成的目录结构如下。

main_pro.py 文件中,值需要导入模块对应的函数即可。

from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains
from functions import id,css,return_driver

driver = return_driver()
driver.maximize_window()

driver.get('https://flight.tuniu.com/')

# 定义好出发和到达的城市
from_city = "SJZ"
to_city = "SY"
from_date = "2021-01-01"

id("J_FormDepartCity").send_keys(from_city)
time.sleep(2)
driver.find_element_by_xpath("//div[@class='autocomplete-suggestions'][1]/div[1]").click()

id("J_FormDestCity").send_keys(to_city)
time.sleep(2)
driver.find_element_by_xpath("//div[@class='autocomplete-suggestions'][2]/div[2]").click()

# 删除时间控件的只读属性
driver.execute_script("document.getElementById('J_FormDepartDate').removeAttribute('readonly')")
# 设置时间
id("J_FormDepartDate").clear()
id("J_FormDepartDate").send_keys(from_date)

# 点击一下其他位置,清除浮窗
ActionChains(driver).move_by_offset(0,10).click().perform()

# 点击搜索按钮
time.sleep(1)
id("J_Search").click()

依旧是相同的手段,可以将所有的通用内容都提炼到 functions.py 这个文件中,而 main_pro.py 只保留业务逻辑代码。

再往深处去学习,就涉及基础代码层,业务代码层,测试代码层的编写了。本系列不做展开,滚雪球学 Python 中将有所涉及。代码随着编写的深入是需要不断进行重构与迭代的,项目越大越需要复杂的设计,小 Demo 类的项目一般是用不到特别复杂的层级的,主要是没有必要,分层之后代码写起来比较费劲。

Selenium 代码异常

项目除了结构设计的合理以外,还需要较高的异常处理能力,在 Selenium 中,常见的异常都可以在下述网址直接查询到。

https://www.selenium.dev/selenium/docs/api/py/common/selenium.common.exceptions.html#module-selenium.common.exceptions

最常出现的还是 NoSuchElementException,找不到元素,其它错误异常在代码编写过程中,碰到就去官网查询一下即可,要记住编程是离不开手册的,工作多少年都一样。

补充知识点 implicitly_wait() 方法

在使用 Selenium 进行网页元素定位的时候,有时页面加载会慢,可能是受网速影响,也可能其它原因,这时需要一个获取元素的等待时间,之前都是采用 time 模块的 sleep 方法实现的,其实 Selenium 也给我们提供了一个自带的方法,即 implicitly_wait 智能等待,设置一个全局智能等待的时间,那获取元素的时候,就会按照这个时间进行等待,例如设置了 10 秒,如果 5 秒元素获取到了,那智能等待就等于 5 秒,反之,等待 10 秒还没有获取到,就会进行下一步计算或者报错。

具体的代码格式如下:

# 设置全局等待时间为 10 秒
driver.implicitly_wait(10)
driver.get('https://flight.tuniu.com/')

写在后面

任何项目在编写的过程中都是不断优化与重构的,所以在项目之初就带着全局的眼光去编写程序,过程中反复调整,不断提高自己的项目把控与设计能力,此乃上技。


博主 ID:梦想橡皮擦,希望大家点赞评论收藏

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。