python之web自动化<一>

python之web自动化<二> 戳这里
一图了解整个代码驱动浏览器的过程:
python之web自动化<一>_第1张图片

前提:Chrome浏览器驱动下载地址:http://chromedriver.storage.googleapis.com/index.html
Firefox(火狐)浏览器驱动:https://github.com/mozilla/geckodriver/releases/

一、基本操作

a.

from selenium import webdriver

# 启动浏览器
driver = webdriver.Chrome(service_log_path='C:\\Users\\joinkwang\\test\\test_project\\common\\chormelog.log')

# 访问一个网页
driver.get("http://devci01:8080/login?from=%2F")

# 退出访问或者会话 杀掉进程 不占用资源
driver.quit()

# 关闭当前窗口 没有杀掉进程 没有退出浏览器进程
driver.close()

b.

from selenium import webdriver
import time
# 启动浏览器
driver = webdriver.Chrome(service_log_path='C:\\Users\\joinkwang\\test\\test_project\\common\\chormelog.log')
# 访问一个网页
driver.get("http://devci01:8080/login?from=%2F")
# 窗口最大化
driver.maximize_window()
# 访问另一个网页
driver.get("http://www.taobao.com")
# 退回上一页
driver.back()
time.sleep(1) # 强制等待1S
driver.implicitly_wait(5)  # 隐形等待5S,如果等到了进程马上运行,如没有等到,5秒后报错
# 退回下一页
driver.forward()
# 刷新
driver.refresh()
# 获取标题
print(driver.title)
# 获取网址
print(driver.current_url)
# 窗口的ID
print(driver.current_window_handle)

二、元素定位。

方式一三:定位对象
在这里插入图片描述
方式二:定位对象
在这里插入图片描述
方式五:定位对象
python之web自动化<一>_第2张图片

# 元素定位
# id、classname、tagname、name、

# 启动浏览器
driver = webdriver.Chrome(service_log_path='C:\\Users\\join\\test\\test_project\\common\\chormelog.log')
# 访问一个网页
driver.get("http://devci01:8080/login?from=%2F")

# 方式一
# 查找页面的ID属性,定位元素
ele = driver.find_element_by_id("j_username")
print(ele)
# 通过查找ID属性对象获取里面的其他属性 autocorrect 和 name等
print(ele.get_attribute("autocorrect"))
print(ele.get_attribute("name"))

# 方式一结果:
<selenium.webdriver.remote.webelement.WebElement (session="026d2df4659386ea5bfbe5e25f86e615", element="289aa174-5587-4988-95f2-af72c59254b4")>
off
j_username

# 方式二
# find_elements_by_class_name 找class属性 找到class=“noedge”的列表 可能存在多个 noedge 的元素
eles = driver.find_elements_by_class_name("yui-button")
print(eles[0])
print(eles[0].get_attribute("name"))

# find_element_by_class_name 只找到class=“noedge” 的第一个元素(从上往下第一个出现的class=noedge)
eles = driver.find_element_by_class_name("yui-button") # 如果存在多个对象值 选其中一个即可
print(eles)
print(eles.get_attribute("name"))

方式二结果:
<selenium.webdriver.remote.webelement.WebElement (session="36d96286eefc3d36e109e1911fb47fc6", element="ea3c71e9-c02a-4192-acd6-ec671d99b639")>
Submit

# 方式三
# 与方式二一样,elements 返回对象为列表 查找多个 找name属性
eles = driver.find_elements_by_name("j_username")
eles = driver.find_element_by_name("j_username")

# 结果与方式一一致


# 方式四 查找标签名 与方式二一样
eles = driver.find_elements_by_tag_name("input")
# eles = driver.find_element_by_tag_name("input")
for i in eles:
    print(i)

# 返回结果:
<selenium.webdriver.remote.webelement.WebElement (session="2dece12c51717c69dfd1bcff663d118a", element="043cfe82-17b2-42f4-9d10-57fdcadea7f7")>
<selenium.webdriver.remote.webelement.WebElement (session="2dece12c51717c69dfd1bcff663d118a", element="be6b54a1-392f-4b41-ad9b-c310c14786f7")>
<selenium.webdriver.remote.webelement.WebElement (session="2dece12c51717c69dfd1bcff663d118a", element="4d1ab5e9-4357-40e7-9dcd-ce8cdef7e81f")>
<selenium.webdriver.remote.webelement.WebElement (session="2dece12c51717c69dfd1bcff663d118a", element="62ff10dc-6e36-44d4-a0e3-45926ab4bf0c")>
<selenium.webdriver.remote.webelement.WebElement (session="2dece12c51717c69dfd1bcff663d118a", element="b779310a-b10d-470f-b231-6bf129e940dc")>
<selenium.webdriver.remote.webelement.WebElement (session="2dece12c51717c69dfd1bcff663d118a", element="9319edf1-e164-4784-84c0-dedad1cd06fa")>
<selenium.webdriver.remote.webelement.WebElement (session="2dece12c51717c69dfd1bcff663d118a", element="1658fbe0-a20d-43f2-835b-34dc89381dae")>
<selenium.webdriver.remote.webelement.WebElement (session="2dece12c51717c69dfd1bcff663d118a", element="a9f6bd6b-8255-407e-bf3f-8822653350ed")>

# 方式五 针对链接 文字
eles = driver.find_element_by_partial_link_text("log in")  # 精准查找
# driver.find_elements_by_partial_link_text("in")  # 模糊查找
# driver.find_element_by_partial_link_text("in")  # 模糊查找
print(eles.get_attribute("href"))

# 返回结果:
http://devci01:8080/login?from=%2F

方式六:xpath定位
python之web自动化<一>_第3张图片xpath:1、相对定位和绝对定位: jenkins登录页面

# expat 和 css 多种定位条件的综合组合
# 相对定位 以//开头 不依赖于页面的顺序和位置 只看整个页面有没有符合表达式的元素
# //标签名称[@属性名称=值]
# 单个条件://input[@name="j_username"]
# 多个条件://input[@name="j_username" and @type="text"]
ls = '//input[@name="j_username"]'
eles = driver.find_element_by_xpath(ls)
print(eles.get_attribute("id"))

# 返回值:
j_username

# 绝对定位 以//开头 非常依赖于页面的顺序和位置
//*[@id="main-panel"]/div/form/table/tbody/tr[2]/td[2]/input

绝对定位快捷方便,但是后续不稳定,如图:
python之web自动化<一>_第4张图片
xpath:2、相对定位中的层级定位:jenkins登录页面
python之web自动化<一>_第5张图片

# xpath中相对定位中的层级定位 注意:// 代表后代的子子孙孙后代;/代表是直系下一代。
ls = '//div[@style="margin: 2em;"]//input[@name="j_username"]'
# ls = '//*[@style="margin: 2em;"]//input[@name="j_username"]'
eles = driver.find_element_by_xpath(ls)
print(eles.get_attribute("name"))

# 返回值:
j_username

xpath:3、相对定位中文本text()函数定位:baidu页面python之web自动化<一>_第6张图片当如果父类下的所有元素一样,仅仅文本不一样的时候,使用text()函数;
//*[@id="s-top-left"]//a[text()="视频"] 读取

xpath:4、相对定位部分contains()定位函数:baidu页面
python之web自动化<一>_第7张图片
contains(@属性/text(),value):包含部分定位函数
例如:contains(@class,“XXXX”)、contains(text(),“XXXX”)
1.//span[contains(@class,"quickdelete-wrap")]

逻辑运算:
and 表示条件 与
or 表示条件 或
2.//span[contains(@class,"quickdelete-wrap") and contains(@class,"s_ipt_wr")]
3.//div[@class="XXXX" and contains(@style,"display:visibility")]

xpath:5、轴定位:jenkins登录页面

ancestor:祖先节点
parent:父节点
preceding-sibling:当前元素节点标签之前的所有兄弟节点
following-sibling:当前元素节点标签之后的所有兄弟节点

使用语法:
/轴名称::节点名称
例如1://input[contains(@id,"j_username")]/ancestor::tbody//input[@type="password"]
python之web自动化<一>_第8张图片祖先定位://input[contains(@id,"j_username")]/ancestor::tbody//input[@type="password"]
其中 /ancestor::tbody是指回到祖先节点tbody

例如2:祖先兄弟后定位://input[contains(@id,"j_username")]/ancestor::tr/following-sibling::tr//input
python之web自动化<一>_第9张图片

三、等待

# 时间等待方式
# 第一种:固定延迟 5s
import time
time.sleep(5)

# 第二种:隐形等待 如果等到了进程马上运行,如没有等到,5秒后报错
# 启动Chrome驱动
from selenium import webdriver
from selenium.webdriver.common.by import By

# 启动Chrome驱动
driver = webdriver.Chrome()
driver.implicitly_wait(30) # 在启动后到启动结束所有进程都保持30S处理时间。
# 打开一个网页
driver.get('https://www.baidu.com/')
# 点击登录
driver.find_element(By.XPATH, '//div[@id="u1"]//a[@name="tj_login"]').click()
# 点击短信登录
driver.find_element(By.ID, "TANGRAM__PSP_11__changeSmsCodeItem").click()

# 第三种:显形等待
# 明确等待某个条件的满足之后,再去执行下一步的操作。
# 程序每隔XX秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置最长时间,然后抛出TimeoutException。

# 使用之前,引入相关的库
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By  # 八种定位方式

# WebDriverWait类:显性等待类
# WebDriverWait(driver,等待时常,轮询周期).until()条件/until_not()直到条件不成立

# expected_conditions模块:提供了一系列期望发生的条件。
# driver.find_element(By.ID, 'TANGRAM__PSP_28__changePwdCodeItem')

# 启动Chrome驱动
driver = webdriver.Chrome()
# driver.implicitly_wait(30)
# 打开一个网页
driver.get('https://www.baidu.com/')
# 点击登录
driver.find_element(By.XPATH, '//div[@id="u1"]//a[@name="tj_login"]').click()

# 以下是显性等待使用方法:
# 1、先确认元素的定位表达式
s_id = 'TANGRAM__PSP_11__regLink'  # ID定位立即注册按钮

# 2、设置显性等待 WebDriverWait(driver,等待时常:10S,轮询周期:默认值0.5S).until()/until_not():条件成立/直到条件不成立
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, s_id)))  # 条件 (元素定位为的类型,元素定位的表达式)

# 3、使用后续的方法 比如:点击
driver.find_element(By.ID, 'TANGRAM__PSP_11__regLink').click()

附:常用的 expected_conditions 模块下的条件:


# EC.presence_of_element_located():元素存在
# EC.visibility_of_element_located():元素可见
# EC.element_to_be_clickable():元素可点击
# EC.new_window_is_opened()  # 新窗口是否打开
# EC.frame_to_be_available_and_switch_to_it()  # 可用并且切换进去
# EC.alert_is_present()  # 弹出框的出现
# EC.element_selection_state_to_be()  # 下拉列表状态
# EC.element_to_be_selected()  # 某一个定位表达式的值应该是被选中的
# EC.element_selection_state_to_be()  # 定位表达式的选中状态是什么
# EC.element_to_be_selected()  # 元素可用被选中的
# EC.invisibility_of_element()  # 隐形的元素
# EC.number_of_windows_to_be()  # 窗口的个数应该为
# # EC.presence_of_all_elements_located()  # 所有元素应该都存在
# EC.text_to_be_present_in_element()  # 元素出现的文本内容
# EC.text_to_be_present_in_element_value()  # 元素出现的文本内容值
# EC.url_changes()  # url的改变
# EC.url_contains()  # url的包含
# EC.url_matches()  # url的匹配
# EC.url_to_be()  # url的应该是什么

四、切换一,iframe

1.先切换iframe元素再定位到对应html页面下元素。

# 切换 iframe=进入另外一个html页面。 一个页面可能存在多个html (原则上一个iframe下存在对应一个Html页面).
# 如果页面定位不好到下一个html页面中的元素,可以先切换到ifranme对应的html页面再然后去定位这个html页面下的元素。
# 下面总体的三种方法就代表:先进入另外一个html页面。
# iframe 定位三种方法,第一种是定位iframe的name属性
driver.switch_to.frame('name')
# 第二种是 iframe 里面根据下标,根据html页面的iframe的个数 从1开始
driver.switch_to.frame(3)
# 第三种是 iframe 里面属性根据属性名称来取值,iframe从0开始取值
driver.switch_to.frame(driver.find_elements(By.TAG_NAME, "iframe")[0])
# 不管哪种方法接下来都是等待0.5S,加载定位完成到html页面后,再根据定位方法定位到对应元素上。
time.sleep(0.5)  # 等待一下
driver.find_element(By.XPATH, "//iframe[@id='qrlogin_img']")

例:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By  # 八种定位方式
import time
# 启动驱动,点击登录
driver = webdriver.Chrome()
driver.get('https://ke.qq.com/')
driver.find_element(By.XPATH, '//a[@id="js_login"]').click()  # 点击登录,登录后自动跳转到微信扫码页面的html。思路:先跳转到iframe,再点击账号密码登录
# 切换里面其中另一个html页面,iframe 在第三个位置 //iframe[@scrolling="no" and @width="368px"]
# WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it('iframe')[2])
# 通过第三种方法,iframe的取值从0开始取值。
driver.switch_to.frame(driver.find_elements(By.TAG_NAME, "iframe")[2])
time.sleep(0.5)
driver.find_element(By.XPATH, "//a[@id='switcher_plogin' and text()='帐号密码登录']").click()

2.iframe切换

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By  # 八种定位方式
import time
# 这种frame_to_be_available_and_switch_to_it方法利用iframe一定存在,采用的方法,后面参数与切换1一致,但是对于切换中的第三种取值方法不适应,这点要注意。
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it('name'))
time.sleep(0.5)  # 等待一下
driver.find_element(By.XPATH, "//iframe[@id='qrlogin_img']")


3.回到

# 从iframe回到主页面的html。
driver.switch_to.default_content()

# 从iframe回到上一级的html页面,即是一个html页面回到上级html页面。
driver.switch_to.parent_frame()

切换二 窗口切换(句柄切换)

1、

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By  # 八种定位方式
import time
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches",["enable-automation"])
driver = webdriver.Chrome(options=options)

driver.get('https://www.baidu.com/')

driver.find_element(By.ID, 'kw').send_keys('柠檬班')
driver.find_element(By.ID, 'su').click()
WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH,'//a[contains(text(),"吧 - 百度贴吧")]')))
driver.find_element(By.XPATH, '//a[contains(text(),"吧 - 百度贴吧")]').click()

time.sleep(0.5)
# 窗口切换
# step1: 获取窗口的总数以及句柄 (新打开的窗口,位于最后一个。)
handles = driver.window_handles
print(handles)
# ['CDwindow-302305DC0B30AA06F25F38445E5F9C81', 'CDwindow-AC6C8AB9635F7F6B54C1A606E888511B']

# 获取当前窗口的句柄
# print(driver.current_window_handle)
# 切换浏览器的页面
driver.switch_to.window(handles[-1])
WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.ID,'j_head_focus_btn')))
driver.find_element(By.ID, 'j_head_focus_btn').click()

2、

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By  # 八种定位方式
import time

# 使用后打开浏览器不显示自动化测试工具的title
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches",["enable-automation"])
driver = webdriver.Chrome(options=options)

driver.get('https://www.baidu.com/')
driver.maximize_window()
driver.find_element(By.ID, 'kw').send_keys('柠檬班')
driver.find_element(By.ID, 'su').click()
# 搜索到满足表达式的条件后继续下一步,否者报错
WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH,'//a[contains(text(),"吧 - 百度贴吧")]')))
# step1: 现在获取窗口的总数是1
handles = driver.window_handles  # 获取的句柄总数为1,也即是窗口数
# step2: 获取窗口的总数变成2.因为下面有点击操作
driver.find_element(By.XPATH, '//a[contains(text(),"吧 - 百度贴吧")]').click()
# step3:等待新的窗口出现,满足条件,现在获取的总数:handles窗口的总数<后面新开的句柄窗口数,利用 new_window_is_opened 方法判断
WebDriverWait(driver, 10).until(EC.new_window_is_opened(handles))
# step4:满足step3条件后切换新的窗口操作,需要重新获取窗口
handle = driver.window_handles[-1]  # 获取最新的窗口,即最后打开的窗口
driver.switch_to.window(handle)
print(handle)
time.sleep(0.5)
WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.ID, 'j_head_focus_btn')))
driver.find_element(By.ID, 'j_head_focus_btn').click()

切换三 alert切换(弹出框处理)

确定:弹出框说到底不是html页面元素

1、在pychrm中新建一个html文件。 写入以下代码,然后利用浏览器打开这个html文件,那么就会出现弹出框提示:everything is ready!!


python-20211229


如图:
python之web自动化<一>_第10张图片
2.代码集成处理:

import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.firefox.service import Service as Services
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By  # 八种定位方式
from common.config_reader import ConfigReader
import time


class BaseMethod():
    def __init__(self):
        self.driver = None
        self.driver_file_path = ConfigReader().get_value('file', 'runstatus_file_path')

    def oper_url(self, url):  # 两种方式打开浏览器
        if "chromedriver" in self.driver_file_path:  # 如果是谷歌驱动执行以下程序
            options = webdriver.ChromeOptions()
            options.add_experimental_option("excludeSwitches", ["enable-automation"])
            driver_obj = Service(self.driver_file_path)
            self.driver = webdriver.Chrome(service=driver_obj, options=options)
        elif "geckodriver" in self.driver_file_path:  # 如果是火狐驱动执行以下程序
            driver_obj = Services(self.driver_file_path)
            self.driver = webdriver.Firefox(service=driver_obj)
        self.driver.get(url)
        self.driver.maximize_window()
        self.oper_baidu()
        self.driver_alert()
        
    def oper_baidu(self):
    	self.driver.find_element(By.ID, 'kw').send_keys('柠檬班')
        self.driver.find_element(By.ID, 'su').click()
        # 搜索到满足表达式的条件后继续下一步,否者报错
        WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((By.XPATH,'//a[contains(text(),"吧 - 百度贴吧")]')))
        # step1: 现在获取窗口的总数是1
        handles = self.driver.window_handles  # 获取的句柄总数为1,也即是窗口数
        # step2: 获取窗口的总数变成2.因为下面有点击操作
        self.driver.find_element(By.XPATH, '//a[contains(text(),"吧 - 百度贴吧")]').click()
        # step3:等待新的窗口出现,满足条件,现在获取的总数:handles窗口的总数<后面新开的句柄窗口数,利用 new_window_is_opened 方法判断
        WebDriverWait(self.driver, 10).until(EC.new_window_is_opened(handles))
        # step4:满足step3条件后切换新的窗口操作,需要重新获取窗口
        handle = self.driver.window_handles[-1]
        self.driver.switch_to.window(handle)
        print(handle)
        time.sleep(0.5)
        WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((By.ID, 'j_head_focus_btn')))
        self.driver.find_element(By.ID, 'j_head_focus_btn').click()

    def driver_alert(self): # 可以不要self ,把所有的 self 去掉,但是 self.driver_file_path
        options = webdriver.ChromeOptions()
        options.add_experimental_option("excludeSwitches", ["enable-automation"])
        driver_obj = Service(self.driver_file_path)  # 驱动存在的路径可以改成绝对路径
        self.driver = webdriver.Chrome(service=driver_obj, options=options)
        self.driver.maximize_window()
        self.driver.get(os.getcwd()+r"\7788.html")  # 文件路径和我们是同一级 不是的话可以放绝对路径
        WebDriverWait(self.driver, 10).until(EC.alert_is_present())  # 判断alert弹出框是否出现为条件,等待alert出现
        #  首先对弹框进行处理时候,先要要去访问一个有弹出框的网页 dismiss 拒绝;取消,accept 确定 ,send_keys 输入
        alert = self.driver.switch_to.alert  # 获取弹框对象
        print(alert.text)  # 打印弹框内容
        # 关闭弹出框
        alert.accept()  # 点击确定
        # alert.dismiss()  # 取消
if __name__ == '__main__':
	BaseMethod().driver_alert()

或者代码直接处理:建议直接拿这个调试玩一玩

import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def driver_alert():
    driver_file_path = '..\data\chromedriver.exe'
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    driver_obj = Service(driver_file_path)
    driver = webdriver.Chrome(service=driver_obj, options=options)
    driver.maximize_window()
    driver.get(os.getcwd() + r"\7788.html")  # 文件路径和我们是同一级 不是的话可以放绝对路径
    WebDriverWait(driver, 10).until(EC.alert_is_present())  # 判断alert弹出框是否出现为条件,等待alert出现
    #  首先对弹框进行处理时候,先要要去访问一个有弹出框的网页 dismiss 拒绝;取消,accept 确定 ,send_keys 输入
    alert = driver.switch_to.alert  # 获取弹框对象
    print(alert.text)  # 打印弹框内容
    # 关闭弹出框操作 取消 OR 确定
    alert.accept()  # 点击确定
    # alert.dismiss()  # 取消

if __name__ == '__main__':
    driver_alert()

五、webdriver中常用的操作元素的方法:

clear():清除对象的内容

driver.find_element_by_id(‘kw’).clear()

send_keys():在对象上模拟按键输入

driver.find_element(By.ID,‘kw’).send_keys(“12306”)

click():单击对象,强调对象的独立性

driver.find_element(By.ID,‘su’).click()

submit():提交表单,要求对象必须是表单

driver.find_element(By.ID,‘form’).submit()

size:返回对象的尺寸

driver.find_element_by_css_selector("#J_username").size

text:获取对象的文本

driver.find_element_by_css_selector(“a.sendpwd”).text

get_attribute(“属性名”):获取对象的属性值

driver.find_element_by_css_selector("#J_username").get_attribute(“name”)

is_displayed():用来判断对象是否可见,即css的display属性是否为none

driver.find_element_by_css_selector("#J_username").is_displayed()

is_enabled():判断对象是否被禁用

driver.find_element_by_css_selector("#J_username").is_enabled()

is_selected():判断对象是否被选中

driver.find_element_by_id(“head_checkbox”).is_selected()

tag_name:获取对象标签名称

driver.find_element_by_id(“head_checkbox”).tag_name

location:获取元素坐标

driver.find_element_by_id(“head_checkbox”).location

最后利用JavaScript操作web页面的元素

python之web自动化<一>_第11张图片
python之web自动化<一>_第12张图片
改变属性的value
在这里插入图片描述

你可能感兴趣的:(python,python,前端,自动化)