selenium自动化架构

selenium post请求python selenium获取请求响应_字符串

如何构建http消息发送给浏览器?

如何从http响应消息中提取呢?

selenium 客户端库--->支持多种语言:python、java

一、安装:

客户端库+浏览器驱动

1、安装客户端库

selenium post请求python selenium获取请求响应_chrome_02

 

2、安装浏览器驱动

建议:chrome

下载驱动地址,并根据版本号对应:http://chromedriver.storage.googleapis.com/index.html

 

3、打开浏览器,打开网址

selenium post请求python selenium获取请求响应_chrome_03

 

二、选择元素的基本方法

1、选择元素的特征:F12

selenium post请求python selenium获取请求响应_selenium_04

 

2、确定唯一性:

1)根据id确定元素(常用)

selenium post请求python selenium获取请求响应_chrome_05

 

运行原理:浏览器,找到id为kw的元素后,将结果通过浏览器驱动返回给自动化程序,所以find_element_by_id方法会返回一个WebElement类型的对象,通过这个对象操控对应的界面元素(调用对象的send_keys、click方法等)

 

2)根据class属性、tag名选择元素

 

eg:对应html内容有如下的部分

selenium post请求python selenium获取请求响应_字符串_06

根据class名确定元素

eg:如果我们要选择所有的动物,就可以使用方法 find_elements_by_class_name

注意 elements是获取所有的,element获取的是第一个

from selenium import webdriver
# webdriver 对象,操控浏览器
wd = webdriver.Chrome(r'D:\chromedriver.exe')
# wd.get("https://www.baidu.com")
wd.get('http://cdn1.python3.vip/files/selenium/sample1.html')
# 根据 class name 选择元素,返回的是 一个列表
# 里面 都是class 属性值为 animal的元素对应的 WebElement对象
elements = wd.find_elements_by_class_name('animal')


# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容
for element in elements:
    print(element.text)

运行结果:

selenium post请求python selenium获取请求响应_selenium_07

根据tag名选择元素

 

eg:我们选择所有的tag名为div的元素

# 根据 tag name 选择元素,返回的是 一个列表

# 里面 都是 tag 名为 div 的元素对应的 WebElement对象

elements = wd.find_elements_by_tag_name('div')

# 取出列表中的每个 WebElement对象,打印出其text属性的值

# text属性就是该 WebElement对象对应的元素在网页中的文本内容

for element in elements:

print(element.text)

小结:find_element和find_elements区别:使用 find_elements 选择的是符合条件的 所有 元素, 如果没有符合条件的元素, 返回空列表

使用 find_element 选择的是符合条件的 第一个 元素, 如果没有符合条件的元素, 抛出 NoSuchElementException 异常

 

3)通过WebElement对象选择元素

注意:WebDriver对象选择元素的范围是整个Web页面,而WebElement对象选择元素的范围是该元素的内部

 

eg:有这样一段代码、获取元素id为container元素的内部,并打印网页元素文本

 

selenium post请求python selenium获取请求响应_字符串_08

 

selenium post请求python selenium获取请求响应_字符串_09

 

运行结果:

selenium post请求python selenium获取请求响应_css_10

 

4)等待页面元素出现:当代码执行速度比服务器响应速度快,服务器还没来得及返回搜索结果,我们就继续运行程序,容易出现异常:NoSuchElementException

 

两种方法:sleep and implicitly_wait

 

eg1:

from selenium import webdriver
wd = webdriver.Chrome(r'D:\chromedriver.exe')
wd.get('https://www.baidu.com')
element = wd.find_element_by_id('kw')
element.send_keys('黑羽魔巫宗\n')
# 等待 2 秒
from time import sleep
sleep(2)


# 2 秒 过后,再去搜索
element = wd.find_element_by_id('1')


# 打印出 第一个搜索结果的文本字符串
print (element.text)

 

eg2:

from selenium import webdriver
wd = webdriver.Chrome(r'D:\chromedriver.exe')
wd.implicitly_wait(10)


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


element = wd.find_element_by_id('kw')


element.send_keys('黑羽魔巫宗\n')


element = wd.find_element_by_id('1')


print (element.text)

 

利弊分析: 第一种方法,无法准确确定休眠时间,时间设置过长容易造成时间浪费,时间设置过短达不到效果,第二种方法的解决原理是:当发现找不到元素时,并不立即返回找不到元素的错误,而是周期性重新寻找该元素,直到元素找到,或者超过指定最大等待时长,就会抛出异常

三、操控元素的基本方法

1、点击元素

element.click()

2、输入框

element.send_keys()

3、清除内容

element.clear()

4、获取元素信息

print(element.text)

5、获取元素属性

element.get_attribute('class')

6、获取整个元素对应的html

element.get_attribute('outerHTML')

7、获取某个元素内部的HTML文本内容

element.get_attribute('innerHTML')

8、获取输入框里面的文字

element.get_attribute('value')

9、获取元素文本内容

element.get_attribute('innerText')

element.get_attribute('textContent')

四、CSS元素定位

1、CSS Selector 语法选择元素

1)find_element_by_css_selector(CSS Selector参数)

2)find_elements_by_css_selector(CSS Selector参数)

2、根据tag名、id、class选择元素

1)根据tag名


elements = wd.find_elements_by_css_selector('div')


等价于


elements = wd.find_elements_by_tag_name('div')


2)根据id,选择语法是


element = wd.find_element_by_css_selector('#searchtext')


3)根据class名,语法是.class


elements = wd.find_elements_by_css_selector('.animal')


3、选择子元素和后代

eg:


<div id='container'> <div id='layer1'> <div id='inner11'> <span>内层11</span> </div> <div id='inner12'> <span>内层12</span> </div> </div> <div id='layer2'> <div id='inner21'> <span>内层21</span> </div> </div> </div>


解析:1)id=container直接包含id为layer1和layer2,后者是前者的直接子元素

2) id 为 container 的div元素来说, id 为 inner11 、inner12 、inner22 的元素 和 两个 span类型的元素 都不是 它的直接子元素, 因为中间隔了 几层。虽然不是直接子元素, 但是 它们还是在 container 的内部, 可以称之为它 的 后代元素

语法:

1)如果元素2是元素1的直接子元素,语法:元素1>元素2

2)如果元素2是元素1的后代元素,语法:元素1 元素2

4、根据属性选择

1)选择 属性href值为 http://www.miitbeian.gov.cn 的元素


element = wd.find_element_by_css_selector('[href="http://www.miitbeian.gov.cn"]')


2)限制标签名:比如 div[class='SKnet'] 表示 选择所有 标签名为div,且class属性值为SKnet的元素。其中单引号、双引号均可以

3)包含:要选择a节点,里面的href属性包含了 miitbeian 字符串


a[href*="miitbeian"]


4)选择以某个字符串开头


a[href^="http"]


5)选择以某个字符串结尾


a[href$="gov.cn"]


6)多个属性限制:div[class=misc][ctype=gun]

 

5、验证唯一性

selenium post请求python selenium获取请求响应_css_11

 

其中第几个元素of总共选择几个元素

 

6、选择语法联合使用

eg:

selenium post请求python selenium获取请求响应_css_12

选择<span class='copyright'>版权</span>


div.footer1 > span.copyright


7、组选择

eg:同时选择所有class为plant和class为animal的元素


.plant , .animal


8、按次序选择节点

1)我们可以指定选择的元素 是父元素的第几个子节点,使用 nth-child

2)选择的是父元素的 倒数第几个子节点 ,使用 nth-last-child


p:nth-last-child(1)


3)选择父元素第几个某类型的子节点:nth-of-type

4)选择父元素的 倒数第几个某类型 的子节点,使用 nth-last-of-type

5)如果要选择的是父元素的 某类型偶数节点,使用 nth-of-type(even)

6)如果要选择的是父元素的 某类型奇数节点,使用 nth-of-type(odd)

7)如果要选择是 选择 h3 后面所有的兄弟节点 span,可以这样写 h3 ~ span

五、frame窗口切换

1、嵌入iframe里的元素定位需要切换到可操作范围内,使用swtich_to,其中frame_reference是frame元素的name或者id


wd.switch_to.frame(frame_reference)


2、切出iframe


wd.switch_to.default_content()


3、切换到新的窗口

for handle in wd.window_handles:
    # 先切换到该窗口
    wd.switch_to.window(handle)
    # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口
    if 'Bing' in wd.title:
        # 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,
        break

4、进入新窗口操作后需回到原窗口,可以事先保留老窗口的句柄

# mainWindow变量保存当前窗口的句柄
mainWindow = wd.current_window_handle

5、切换到新窗口操作后,返回原来窗口

#通过前面保存的老窗口的句柄,自己切换到老窗口
wd.switch_to.window(mainWindow)

六、选择框

1、radio

# 获取当前选中的元素
element = wd.find_element_by_css_selector(
  '#s_radio input[checked=checked]')
print('当前选中的是: ' + element.get_attribute('value'))
# 点选 小雷老师
wd.find_element_by_css_selector(
  '#s_radio input[value="小雷老师"]').click()

2、checkbox框

# 先把 已经选中的选项全部点击一下
elements = wd.find_elements_by_css_selector(
  '#s_checkbox input[checked="checked"]')


for element in elements:
    element.click()


# 再点击 小雷老师
wd.find_element_by_css_selector(
  "#s_checkbox input[value='小雷老师']").click()

3、select单选框

# 导入Select类
from selenium.webdriver.support.ui import Select


# 创建Select对象
select = Select(wd.find_element_by_id("ss_single"))


# 通过 Select 对象选中小雷老师
select.select_by_visible_text("小雷老师")

4、select多选框

# 导入Select类
from selenium.webdriver.support.ui import Select


# 创建Select对象
select = Select(wd.find_element_by_id("ss_multi"))


# 清除所有 已经选中 的选项
select.deselect_all()


# 选择小雷老师 和 小凯老师
select.select_by_visible_text("小雷老师")
select.select_by_visible_text("小凯老师")