社区所有版块导航
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

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

梦想橡皮擦 • 3 年前 • 436 次点击  

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

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

封装元素定位函数

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 获取对象也封装成了一个函数。最终形成的目录结构如下。

20201221223658360[1].png

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/')

写在后面

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


如果你想跟博主建立亲密关系,可以关注同名公众号 <font color="red">梦想橡皮擦</font>,近距离接触一个逗趣的互联网高级网虫。
博主 ID:梦想橡皮擦,希望大家<font color="red">点赞</font>、<font color="red">评论</font>、<font color="red">收藏</font>。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/120535
 
436 次点击