文章目录

  • 前言
    • selenium (from selenium import webdriver)
      • 1、安装
      • 2、基本使用
      • 3、声明浏览器对象
      • 4、访问页面
      • 5、查找节点
        • 5.1 查找单个节点
        • 5.2 查找多个节点
      • 6、节点交互(操作节点事件)
      • 7、动作链
        • 7.1 鼠标点击
        • 7.2 鼠标移动
        • 7.3 鼠标拖拽
        • 7.4 按键监听
      • 8、执行JavaScript脚本
      • 9、获取节点信息
      • 10、切换iFrame
      • 11、延迟等待(显示等待和隐式等待)
      • 12、前进与后退
      • 13、Cookies使用
      • 14、选项卡管理(切换句柄)
      • 15、异常处理
      • 16、浏览器退出
      • 17、截图操作
      • 18、Selenium项目模板
    • 总结

前言

网络上有着很多这种类型的使用说明以及教程,但终归不是自己的。
遇到不会的时候还得不断的重复去百度,这样导致效率低下。
最终还是想着结合网上的教程,给自己归纳总结一部分库的使用,方便自己回顾。

selenium (from selenium import webdriver)

  • 更详细操作见:Selenium_Python英文版、Selenium中文翻译操作文档
  • Selenium手册
  • Selenium使用
  • Selenium教程
  • 这边推荐一个元素测试网站(动作链部分针对于该网站):元素测试网站

1、安装

  • 安装步骤1:通过pip install selenium安装

  • 安装步骤2:安装与计算机使用浏览器版本相对应的WebDriver

    • Chrome(ChromeDriver与浏览器对应的版本)
    • Firefox(默认下载最新的geckodriver即可)
  • 安装步骤3:下载完成解压后,将文件移动到一个配置了环境变量的文件夹中,例如Python环境的文件夹下。

2、基本使用

  • Selenium是一个用于Web应用程序测试的工具。
  • Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Firefox,Safari,Chrome,Opera等。
  • Selenium 可以根据我们的指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。同时也可以获取页面的源代码,可以获取页面渲染后的元素,做到可见即可爬
'''功能如下:自动弹出一个Chrome浏览器,浏览器首先会跳转至百度,然后输入Python,回车,等待3秒,自动关闭浏览器。
'''
import timefrom selenium import webdriver
from selenium.webdriver.common.by import By  # 显示等待中使用By进行定位元素
from selenium.webdriver.common.keys import Keys  # 可以实现键盘回车的功能
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWaitbrowser = webdriver.Chrome()  # 声明Chrome浏览器对象
try:browser.get('https://www.baidu.com')  # get()方法请求网页input_item = browser.find_element(By.ID, 'kw')  # 定位到百度输入框,find_element()方法获取单个元素节点input_item.send_keys('Python')  # send_keys()方法向input框中填入字符串input_item.send_keys(Keys.ENTER)  # 模拟键盘回车wait = WebDriverWait(browser, 10)  # 显示等待,指定加载的最长时间wait.until(EC.presence_of_element_located((By.ID, "content_left")))  # 等待内容节点,直到出现进行下一步print(browser.current_url)  # 获取当前浏览器中urlprint(browser.page_source)  # 获取当前url的网页源代码
finally:time.sleep(3)  # 等待3sbrowser.quit()  # 退出浏览器

3、声明浏览器对象

  • 在使用Selenium之前肯定要先声明浏览器对象,以下代码完成了浏览器对象的初始化并赋值给browser对象,接下来就是调用browser对象,让其执行一系列的人为操作。
'''功能如下:声明浏览器对象
'''from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.Safari()

4、访问页面

  • get():请求网页,参数:url网址
'''功能如下:输入一个网址,通过selenium进行访问页面
'''from selenium import webdriver
browser = webdriver.Chrome()  # 创建浏览器对象
browser.get("https://www.baidu.com")  # get() 方法访问页面
print(browser.page_source)  # 获取网页源代码
browser.quit()  # 退出浏览器

5、查找节点

更多请查看:英文文档、中文文档

5.1 查找单个节点
  • find_element():返回的是WebElement类型,这个方法需要导入这个包from selenium.webdriver.common.by import By
    find_element_by_XXX:这个方法不需要额外添加依赖包
方法1 方法2
find_element_by_id find_element(By.ID, “”)
find_element_by_name find_element(By.NAME, “”)
find_element_by_xpath find_element(By.XPATH, “”)
find_element_by_link_text find_element(By.LINK_TEXT, “”)
find_element_by_partial_link_text find_element(By.PARTIAL_LINK_TEXT, “”)
find_element_by_tag_name find_element(By.TAG_NAME, “”)
find_element_by_class_name find_element(By.CLASS_NAME, “”)
find_element_by_css_selector find_element(By.CSS_SELECTOR, “”)

单独拿一个id做案例,代码使用参考如下:

'''功能如下:实现查找节点中id方法的案例案例网站:【豆瓣电影排行榜】https://movie.douban.com/chart'''
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 ECdef fun_one():'''使用 find_element_by_xxx类型:return:'''icp1 = browser.find_element_by_id('icp')icp2 = browser.find_element_by_xpath('//span[@id="icp"]')icp3 = browser.find_element_by_css_selector('#icp')print("方法一:")print(icp1)print(icp2)print(icp3)def fun_two():'''使用 find_element()类型:return:'''icp1 = browser.find_element(By.ID, 'icp')icp2 = browser.find_element(By.XPATH, '//span[@id="icp"]')icp3 = browser.find_element(By.CSS_SELECTOR, '#icp')print("方法二:")print(icp1)print(icp2)print(icp3)if __name__ == '__main__':browser = webdriver.Chrome()browser.get('https://movie.douban.com/chart')wait = WebDriverWait(browser, 15)wait.until(EC.presence_of_element_located((By.ID, "content")))fun_one()  # 方法一:find_element_by_xxx类型fun_two()  # 方法二:find_element()类型browser.quit()# 最后运行的结果如下
#方法一:
#<selenium.webdriver.remote.webelement.WebElement (session="65c0086ed6faf3c3c2b63e349de342d0", element="c62310d9-a5aa-4b66-9ed0-fd9ea0a178c0")>
#<selenium.webdriver.remote.webelement.WebElement (session="65c0086ed6faf3c3c2b63e349de342d0", element="c62310d9-a5aa-4b66-9ed0-fd9ea0a178c0")>
#<selenium.webdriver.remote.webelement.WebElement (session="65c0086ed6faf3c3c2b63e349de342d0", element="c62310d9-a5aa-4b66-9ed0-fd9ea0a178c0")>
#方法二:
#<selenium.webdriver.remote.webelement.WebElement (session="65c0086ed6faf3c3c2b63e349de342d0", element="c62310d9-a5aa-4b66-9ed0-fd9ea0a178c0")>
#<selenium.webdriver.remote.webelement.WebElement (session="65c0086ed6faf3c3c2b63e349de342d0", element="c62310d9-a5aa-4b66-9ed0-fd9ea0a178c0")>
#<selenium.webdriver.remote.webelement.WebElement (session="65c0086ed6faf3c3c2b63e349de342d0", element="c62310d9-a5aa-4b66-9ed0-fd9ea0a178c0")>
5.2 查找多个节点
  • find_elements():返回的是列表类型,列表里面每一个都是WebElement类型。
    find_elements_by_XXX:这个方法不需要额外添加依赖包
方法1 方法2
find_elements_by_id find_elements(By.ID, “”)
find_elements_by_name find_elements(By.NAME, “”)
find_elements_by_xpath find_elements(By.XPATH, “”)
find_elements_by_link_text find_elements(By.LINK_TEXT, “”)
find_elements_by_partial_link_text find_elements(By.PARTIAL_LINK_TEXT, “”)
find_elements_by_tag_name find_elements(By.TAG_NAME, “”)
find_elements_by_class_name find_elements(By.CLASS_NAME, “”)
find_elements_by_css_selector find_elements(By.CSS_SELECTOR, “”)
'''功能如下:实现查找节点中id方法的案例案例网站:【豆瓣电影排行榜】https://movie.douban.com/chart'''
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 ECdef fun_one():'''使用 find_elements_by_xxx类型:return:'''items1 = browser.find_elements_by_css_selector('div.indent .item')items2 = browser.find_elements_by_xpath('//div[@class="indent"]//tr[@class="item"]')print("方法一:")print(items1)print(items2)def fun_two():'''使用 find_elements()类型:return:'''items1 = browser.find_elements(By.CSS_SELECTOR, 'div.indent .item')items2 = browser.find_elements(By.XPATH, '//div[@class="indent"]//tr[@class="item"]')print("方法二:")print(items1)print(items2)if __name__ == '__main__':browser = webdriver.Chrome()browser.get('https://movie.douban.com/chart')wait = WebDriverWait(browser, 15)wait.until(EC.presence_of_element_located((By.ID, "content")))fun_one()  # 方法一:find_elements_by_xxx类型fun_two()  # 方法二:find_elements()类型browser.quit()

6、节点交互(操作节点事件)

  • Selenium驱动浏览器执行一些动作,比较常见的方法有:
  • send_keys():输入文字方法
  • clear():清空文字
  • click():点击按钮
  • submit():回车
  • 更多操作见:文档
'''功能如下:实现input框的输入实现input框的清空实现元素的点击操作
'''import timefrom selenium import webdriver
from selenium.webdriver.common.by import By  # 显示等待中使用By进行定位元素
from selenium.webdriver.common.keys import Keys  # 可以实现键盘回车的功能
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWaitbrowser = webdriver.Chrome()  # 声明Chrome浏览器对象
try:browser.get('https://cn.bing.com/')  # get()方法请求网页input_item = browser.find_element(By.ID, 'sb_form_q')  # 定位到百度输入框,find_element()方法获取单个元素节点input_item.send_keys('Python')  # send_keys()方法:向input框中填入字符串input_item.submit()  # 模拟键盘回车# input_item.send_keys(Keys.ENTER)  # 模拟键盘回车wait = WebDriverWait(browser, 10)  # 显示等待,指定加载的最长时间wait.until(EC.presence_of_element_located((By.ID, "b_results")))  # 等待内容节点,直到出现进行下一步time.sleep(1)input_item2 = browser.find_element(By.ID, 'sb_form_q')input_item2.clear()  # clear()方法:清空input框内容time.sleep(0.2)input_item2.send_keys("阿尔法")  # send_keys()方法:输入字符串browser.find_element(By.ID, "sb_form_go").click()  # click()方法:进行点击操作
finally:time.sleep(3)  # 等待3sbrowser.quit()  # 退出浏览器

7、动作链

  • 用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击、双击、点击鼠标右键、拖拽等等。而selenium给我们提供了一个类来处理这类事件——ActionChains
  • 更多操作见:文档

使用动作链常用的几个场景,如下:

  • 鼠标点击(单击、双击、右键)
  • 鼠标移动(解决hover的某些问题)
  • 鼠标拖拽(实现节点拖拽操作,将某个节点从一处拖拽到另一处。)
  • 按键监听(监听按键的状态)

ActionChains方法列表

click(on_element=None)                                        # 单击鼠标左键
click_and_hold(on_element=None)                            # 点击鼠标左键,不松开
context_click(on_element=None)                             # 单击鼠标右键
double_click(on_element=None)                              # 双击鼠标左键
drag_and_drop(source, target)                              # 按住鼠标左键拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset)           # 拖拽到某个坐标(偏移量)然后松开
key_down(value, element=None)                               # 按下某个键盘上的键,不释放
key_up(value, element=None)                                 # 松开某个键
move_by_offset(xoffset, yoffset)                           # 鼠标从当前位置移动到某个坐标
move_to_element(to_element)                               # 鼠标移动到某个元素的中间
move_to_element_with_offset(to_element, xoffset, yoffset)   # 移动到距某个元素(左上角坐标)多少距离的位置
perform()                                                     # 执行链中的所有动作
release(on_element=None)                                   # 在某个元素位置松开鼠标左键
reset_actions()                                               # 清除链中的所有操作
send_keys(*keys_to_send)                                  # 发送某个键到当前焦点的元素
send_keys_to_element(element, *keys_to_send)               # 发送某个键到指定元素
7.1 鼠标点击

示例网址:https://sahitest.com/demo/clicks.htm

'''功能如下:1. 实现左键单击操作2. 实现左键双击操作3. 实现右键单击操作
'''from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import timebrowser = webdriver.Chrome()  # 初始化浏览器对象try:browser.maximize_window()  # 窗口最大化browser.get('http://sahitest.com/demo/clicks.htm')time.sleep(0.5)click_btn = browser.find_element(By.XPATH, '//input[@value="click me"]')  # 单击按钮doubleclick_btn = browser.find_element(By.XPATH, '//input[@value="dbl click me"]')  # 双击按钮rightclick_btn = browser.find_element(By.XPATH, '//input[@value="right click me"]')  # 右键单击按钮ActionChains(browser).click(click_btn).double_click(doubleclick_btn).context_click(rightclick_btn).perform()  # 链式用法,执行动作链time.sleep(0.5)textarea = browser.find_element(By.XPATH, '//textarea[@name="t2"]').get_attribute('value')  # 获取textarea文本域中的值print(textarea)
finally:time.sleep(3)browser.quit()
7.2 鼠标移动

示例网址:https://sahitest.com/demo/mouseover.htm

'''功能如下:解决某些hover的问题
'''from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import timebrowser = webdriver.Chrome()  # 初始化浏览器对象try:browser.maximize_window()  # 窗口最大化browser.get('https://sahitest.com/demo/mouseover.htm')time.sleep(0.5)write = browser.find_element(By.XPATH, '//input[@value="Write on hover"]')  # Writer on hoverblack = browser.find_element(By.XPATH, '//input[@value="Blank on hover"]')  # Blank on hoveraction = ActionChains(browser)action.move_to_element(write).perform()  # 将鼠标移动到Writer on hovertime.sleep(2)action.move_to_element(black).perform()  # 将鼠标移动到Blank on hover
finally:time.sleep(3)browser.quit()
7.3 鼠标拖拽

示例网址:https://sahitest.com/demo/dragDropMooTools.htm

'''功能如下:实现鼠标将某一个元素拖拽到另一个元素中
'''from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import timebrowser = webdriver.Chrome()  # 初始化浏览器对象try:browser.maximize_window()  # 窗口最大化browser.get('https://sahitest.com/demo/dragDropMooTools.htm')time.sleep(0.5)dragger = browser.find_element(By.ID, 'dragger')  # draggeritems = browser.find_elements(By.XPATH, '//div[@class="item"]')  # itemsaction = ActionChains(browser)action.drag_and_drop(dragger, items[0]).perform()  # 将drop拖拽到第一个item中time.sleep(2)action.drag_and_drop(dragger, items[2]).perform()  # 将drop拖拽到第三个item中time.sleep(2)action.drag_and_drop(dragger, items[-1]).perform()  # 将drop拖拽到第四个item中
finally:time.sleep(3)browser.quit()
7.4 按键监听

示例网址:http://sahitest.com/demo/keypress.htm

'''功能如下:在selenium中实现键盘的简易操作
'''import timefrom selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.common.action_chains import ActionChainsfrom selenium.webdriver.common.by import Bybrowser = webdriver.Chrome()
browser.maximize_window()
browser.get('http://sahitest.com/demo/keypress.htm')key_up_radio = browser.find_element(By.ID, 'r1')  # 监测按键升起
key_down_radio = browser.find_element(By.ID, 'r2')  # 监测按键按下
key_press_radio = browser.find_element(By.ID, 'r3')  # 监测按键按下升起enter = browser.find_elements(By.XPATH, '//form[@name="f1"]/input')[1]  # 输入框
result = browser.find_elements(By.XPATH, '//form[@name="f1"]/input')[0]  # 监测结果# 监测key_down
key_down_radio.click()
ActionChains(browser).key_down(Keys.CONTROL, enter).key_up(Keys.CONTROL).perform()  # 在输入框中按下ctrl建
print(result.get_attribute('value'))
time.sleep(5)# 监测key_up
key_up_radio.click()
enter.click()
ActionChains(browser).key_down(Keys.SHIFT).key_up(Keys.SHIFT).perform()  # 在输入框中按下shift建,松开
print(result.get_attribute('value'))
time.sleep(5)# 监测key_press
key_press_radio.click()
enter.click()
ActionChains(browser).send_keys('a').perform()
print(result.get_attribute('value'))
time.sleep(5)
browser.quit()

8、执行JavaScript脚本

  • execute_script():可以直接模拟运行JavaScript,常见的几种执行场景如下:

    • 将滚动条拉至顶部
    • 将滚动条拉至底部
    • 直接使用js操作页面,能解决很多click()不生效的问题
    • 处理富文本,时间控件的输入

代码如下:

'''功能如下:- 将滚动条拉至顶部- 将滚动条拉至底部- JS执行元素操作(点击、输入文本、等)
'''
from selenium import webdriver
import timefrom selenium.webdriver.common.by import Bybrowser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://movie.douban.com/chart')
time.sleep(2)# driver.execute_script("arguments[0].click();", element),点击操作
# driver.execute_script("arguments[0].scrollIntoView();", element),移动到目标元素,类似于滑动查找# 滚动条拉到底部
js = 'window.scrollTo(0, document.body.scrollHeight)'
browser.execute_script(js)
print(f'''滚动条滑动到底部''')
time.sleep(2)# 滚动条拉到顶部
js = 'window.scrollTo(0, 0)'
browser.execute_script(js)
print(f'''滚动条滑动到顶部''')
time.sleep(2)# 输入文本操作
msg = '悬疑'
send_js = f"text_input = document.getElementById('inp-query'); " \f"text_input.value = '{msg}'"
browser.execute_script(send_js)
print(f'''{msg}文本输入成功。。。''')
time.sleep(2)# 点击操作
input_btn = browser.find_element(By.CSS_SELECTOR, ".inp-btn input")
click_js = 'arguments[0].click();'
browser.execute_script(click_js, input_btn)
print(f'''搜索按钮点击成功''')# 创建一个新的选项卡
browser.execute_script('window.open()')
handles = browser.window_handles  # 获取当前浏览器对象中有多少选项卡
print(handles)
browser.switch_to.window(handles[-1])  # 跳转到最后一个选项卡中
browser.get('https://www.taobao.com')  # 跳转至淘宝中time.sleep(3)
browser.quit()

9、获取节点信息

  • page_source属性可以获取网页的源代码,也可以使用解析库(如正则表达式、BeautifulSoup、pyquery、parsel等)来提取信息

  • Selenium已经提供了选择节点的方法,返回的是WebElement类型,那么它也有相关的方法和属性来直接提取节点信息,如属性、文本等。这样的话,我们就可以不用通过解析源代码来提取信息了,非常方便。

    get_attribute():获取节点的属性,但是其前提是先选中这个节点,示例如下:

    from selenium import webdriver
    import timefrom selenium.webdriver.common.by import Bybrowser = webdriver.Chrome()
    browser.maximize_window()
    browser.get('https://movie.douban.com/chart')
    time.sleep(2)items = browser.find_elements(By.XPATH, '//div[@class="pl2"]/a[1]')
    for item in items:print(item.get_attribute('href'))  # 获取节点属性hreftime.sleep(2)
    browser.quit()# 运行效果
    # https://movie.douban.com/subject/30314848/
    # https://movie.douban.com/subject/27199850/
    # https://movie.douban.com/subject/35874097/
    # https://movie.douban.com/subject/35008440/
    # https://movie.douban.com/subject/34861178/
    # https://movie.douban.com/subject/30165311/
    # https://movie.douban.com/subject/35769174/
    # https://movie.douban.com/subject/35307624/
    # https://movie.douban.com/subject/35303842/
    # https://movie.douban.com/subject/35441573/
    

    text:获取文本值,每个WebElement节点都有text属性,直接调用这个属性就可以得到节点内部的信息,示例如下:

    from selenium import webdriver
    import timefrom selenium.webdriver.common.by import Bybrowser = webdriver.Chrome()
    browser.maximize_window()
    browser.get('https://movie.douban.com/chart')
    time.sleep(2)items = browser.find_elements(By.XPATH, '//div[@class="pl2"]/a[1]')
    for item in items:print(item.text)  # 获取文本数据time.sleep(2)
    browser.quit()# 运行结果
    # 瞬息全宇宙 / 妈的多重宇宙(台) / 奇异女侠玩救宇宙(港)
    # 暗夜博士:莫比亚斯 / 莫比亚斯 / 魔比煞(港)
    # 网络炼狱:揭发N号房 / 网路炼狱:揭发N号房(台) / 网络地狱:N号房现形记
    # 唐顿庄园2 / 唐顿庄园电影版2 / 唐顿庄园:全新世代(港/台)
    # 北欧人 / 北方人(台)
    # 坏蛋联盟 / 大坏蛋 / 坏家伙
    # 万湖会议 / The Conference
    # 渔港的肉子酱 / 渔港的肉子 / Fortune Favors Lady Nikuko
    # 迷失之城 / 迷失D城 / Lost City of D
    # 首尔怪谈 / Urban Myths / Urban Myths: Tooth Worms
    

    id属性:selenium 使用的内部 ID。
    location属性:获取节点在页面中的相对位置
    tag_name属性:可以获取标签名称
    size属性:可以获取节点元素大小

    '''功能如下:id属性:selenium 使用的内部 ID。location属性:获取节点在页面中的相对位置tag_name属性:可以获取标签名称size属性:可以获取节点元素大小
    '''from selenium import webdriver
    import timefrom selenium.webdriver.common.by import Bybrowser = webdriver.Chrome()
    browser.maximize_window()
    browser.get('https://movie.douban.com/chart')
    time.sleep(2)item = browser.find_elements(By.XPATH, '//div[@class="pl2"]/a[1]')[0]
    print(item.id)  # 获取节点在selenium中的id
    print(item.location)  # 获取节点在页面中的位置
    print(item.size)  # 获取节点的大小
    print(item.tag_name)  # 获取节点的标签名称time.sleep(2)
    browser.quit()# 执行效果
    # 8c32db1c-1321-4674-9aee-92abad562603
    # {'x': 534, 'y': 281}
    # {'height': 16, 'width': 318}
    # a
    

10、切换iFrame

示例网址:https://sahitest.com/demo/iframesTest.htm
selenium中处理iFrame有三种方式

  • 1、如果iframe有id或name,则可根据iframe的id或name切换。

    <iframe name="aa"id="x-URS-iframe1610006384373.8518"></iframe>
    browser.switch_to.frame('x-URS-iframe1610006384373.8518')  # id定位
    browser.switch_to.frame('aa')  # name定位
    
  • 2、把iframe当作页面元素,通过元素定位表达式进行切换。

    <iframe name="aa"id="x-URS-iframe1610006384373.8518"></iframe>
    frame = browser.find_element_by_xpath('//iframe[@id="x-URS-iframe"]')  # 先定位元素
    browser.switch_to.frame(frame)  # 在切换iframe
    
  • 3、将iframe存储到list中,然后根据ifrane的索引定位 (适合页面有多个iframe,且前两种方法无法使用)。

    browser.switch_to.frame(0)
    
  • 返回上一级

    browser.switch_to.parent_frame()  # 返回上一级
    
  • 跳出iframe窗口并返回到Top Window 上

    browser.switch_to_default_conten()  # 跳出iframe窗口并返回Window主窗体
    
  • 这里案例只用将元素作为参数传递,进入iframe中。

    from selenium import webdriver
    import timefrom selenium.webdriver.common.by import Bybrowser = webdriver.Chrome()
    browser.maximize_window()
    browser.get('https://sahitest.com/demo/iframesTest.htm')
    time.sleep(2)item = browser.find_element(By.ID, 'checkRecord').get_attribute('value')
    h2_out = browser.find_element(By.TAG_NAME, 'h2').text
    print(f'''外层的主体输出:{item},{h2_out}''')time.sleep(2)
    # 第一层iframe
    iframe = browser.find_element(By.TAG_NAME, 'iframe')
    browser.switch_to.frame(iframe)
    h2_in = browser.find_element(By.TAG_NAME, 'h2').text
    print(f'''内层iframe的输出:{h2_in}''')time.sleep(2)
    browser.quit()
    

11、延迟等待(显示等待和隐式等待)

  • 在selenium中,get()方法会在网页框架加载完之后结束,但是在这时候获取网页源代码page_source,可能并不是浏览器加载完之后的数据,如果某些页面有额外的Ajax请求,我们在网页源代码中也不一定能成功获取到。所以,这里需要延时等待一定时间,确保节点已经加载出来。

  • 等待的方式有两种:一种是显示等待,一种是隐式等待

  • 隐式等待implicily_wait():当使用隐式执行测试时,如果selenium没有在DOM中找到节点,将继续等待,超出设定时间后则抛出找不到节点的异常。【换句话说,当前查找节点的节点没有立即出现,则进行等待隐式等待设定的时候,再查找DOM节点,默认的隐式等待时间为0】

    from selenium import webdriver
    from selenium.webdriver.common.by import Bybrowser = webdriver.Chrome()
    browser.implicitly_wait(10)  # 隐式等待10s
    browser.maximize_window()
    browser.get('https://movie.douban.com/chart')items = browser.find_elements(By.XPATH, '//div[@class="pl2"]/a[1]')
    for item in items:print(item.get_attribute('href'))  # 获取节点属性href
    browser.quit()
    
  • 显式等待wait = WebDriverWait(browser,10):隐式等待的效果其实没有这么好,隐式等待只是设置固定等待一段时间,而页面会收到网络的影响。有一中更适合的显示等待方法,去处理上述问题,【简单的说,显示等待就是在查找节点时,设置一个最长等待时间,在这个规定的时间内,不断的间隔查找节点是否加载出来,如果加载出来,则返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出找不到节点的异常】

    import timefrom 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 ECbrowser = webdriver.Chrome()
    browser.implicitly_wait(10)  # 隐式等待10s
    browser.maximize_window()
    browser.get('https://movie.douban.com/chart')item = WebDriverWait(browser, 10).\until(EC.presence_of_element_located((By.XPATH, '//div[@class="pl2"]')))
    print(item)
    time.sleep(2)
    browser.quit()
    # 运行结果
    <selenium.webdriver.remote.webelement.\
    WebElement (session="21cb0b79ea3b60b9711ae9bb7aab33a5", element="0d6c5acb-9eba-40eb-8075-3655d02b336a")>
    
  • 详细操作:文档

等待条件 含义
title_is 标题是某内容
title_contains 标题包含某内容
presence_of_element_located 节点加载出来,传入定位元组,如(By.ID,‘p’)
visibility_of_element_located 节点可见,传入定位元组
visibility_of 可见,传入节点对象
presence_of_all_elements_located 所有节点加载出来
text_to_be_present_in_element 某个节点文本包含某文字
text_to_be_present_in_element_value 某个节点值包含某文字
frame_to_be_available_and_switch_to_it 加载并切换
invisibility_of_element_located 节点不可见
element_to_be_clickable 节点可点击
staleness_of 判断一个节点是否仍在DOM,可判断页面是否已经刷新
element_to_be_selected 节点可选择,传节点对象
element_located_to_be_selected 节点可选择,传入定位元组
element_selection_state_to_be 传入节点对象以及状态,相等返回true,否则返回False
element_located_selection_state_to_be 传入定位元组以及状态,相等返回True,否则返回False
alert_is_present 是否出现警告

12、前进与后退

  • back():后退
  • forward():前进
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com/')
browser.get('https://www.taobao.com/')
browser.get('https://www.zhihu.com/')
browser.back()
time.sleep(1)
browser.forward()
browser.close()

13、Cookies使用

  • get_cookies():获取cookies 【列表格式】
  • add_cookie(dict):添加cookie【字典格式】
  • delete_cookie(name=“”):删除某一个cookie
  • delete_all_cookies():删除所有的cookies
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com/')
cookies = browser.get_cookies()  # 获取页面的cookie【列表格式】
print(cookies)
time.sleep(1)
browser.add_cookie({'name': 'name', 'domain': '.baidu.com', 'value': 'xuan'})  # 添加cookie
time.sleep(0.5)
print(browser.get_cookies())
time.sleep(0.5)
browser.delete_all_cookies()  # 删除所有的cookies
time.sleep(0.5)
print(browser.get_cookies())
browser.close()# 运行结果
# [{'domain': '.baidu.com', 'expiry': 1685068239, 'httpOnly': False, 'name': 'ZFY', 'path': '/', 'sameSite': 'None', 'secure': True, 'value': '6L4XyME:AUQ:AgwiMtufstx4tSWgLYItHOAIkkYt6HSMo:C'}, {'domain': '.baidu.com', 'expiry': 1653618639, 'httpOnly': False, 'name': 'BA_HECTOR', 'path': '/', 'secure': False, 'value': '8cak8121ah252lela01h8tpif15'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '36454_31253_36452_36421_36165_36488_36055_26350_36301_36469_36311_36447'}, {'domain': '.baidu.com', 'expiry': 1685068238, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': 'C0B5A9B5DBE343265E238C99CE101CAC:FG=1'}, {'domain': '.baidu.com', 'expiry': 3801015885, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'C0B5A9B5DBE3432620590E72CBC92B05'}, {'domain': '.baidu.com', 'expiry': 3801015885, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1653532239'}, {'domain': 'www.baidu.com', 'expiry': 1654396239, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'}]
# [{'domain': '.baidu.com', 'expiry': 1685068239, 'httpOnly': False, 'name': 'ZFY', 'path': '/', 'sameSite': 'None', 'secure': True, 'value': '6L4XyME:AUQ:AgwiMtufstx4tSWgLYItHOAIkkYt6HSMo:C'}, {'domain': '.baidu.com', 'expiry': 1653618639, 'httpOnly': False, 'name': 'BA_HECTOR', 'path': '/', 'secure': False, 'value': '8cak8121ah252lela01h8tpif15'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '36454_31253_36452_36421_36165_36488_36055_26350_36301_36469_36311_36447'}, {'domain': '.baidu.com', 'expiry': 1685068238, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': 'C0B5A9B5DBE343265E238C99CE101CAC:FG=1'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'name', 'path': '/', 'secure': True, 'value': 'xuan'}, {'domain': '.baidu.com', 'expiry': 3801015885, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'C0B5A9B5DBE3432620590E72CBC92B05'}, {'domain': '.baidu.com', 'expiry': 3801015885, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1653532239'}, {'domain': 'www.baidu.com', 'expiry': 1654396239, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'}]
# []
  • 这里增加一个扩展功能,比如selenium的Cookies转换成字符串Cookie可以给requests使用,又或者requests的Cookie字符串转换成selenium可使用的list格式Cookies。
# 网页中的cookie转换成selenium使用的cookie
def cookie_seleinium(cookieStr, domain):'''将requests拿到的cookie转换成selenium使用的cookie:param cookieStr: cookie:param domain: 填入统一的domin域名:return:'''cookie_list = cookieStr.split(';')selenium_cookie_list = []for cookie in cookie_list:# print(cookie)# print(cookie.split('=', 1))cookie = cookie.strip()name = cookie.split('=', 1)[0]value = cookie.split('=', 1)[-1]cookie_dict = {"domain": domain,"name": name,"value": value,"path": "/"}selenium_cookie_list.append(cookie_dict)return selenium_cookie_list# selenium获取cookie可转成requests使用的cookie
def selenium_requests_cookie(selenium_list):#获取cookiescookie_list = [item["name"] + "=" + item["value"] for item in selenium_list]cookieStr = ';'.join(item for item in cookie_list)return cookieStr

14、选项卡管理(切换句柄)

  • 获取当前句柄:browser.current_window_handle
  • 获取所有句柄:hanles = browser.window_handles
  • 切换指定句柄:handle = handles[-1] # 取最新窗口的id browser.switch_to.window(handle) # 切换窗口
  • 访问网页的时候,很多时候我们点击一个链接时,会新建一个选项卡,那么如何跳转至新打开的选项卡呢?就需要用到switch_to.window(handle)方法去跳转,以下代码会做一个小案例。
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
# 调用execute_script()方法,传入window.open()这个javascript语句新开启一个选项卡
browser.execute_script('window.open()')
# 获取当前开启的所有选项卡,返回的是选项卡的代号列表
print(browser.window_handles)
# 调用switch_to.window()方法切换选项卡,参数是选项卡代号,跳转到最后一个,选项卡中序号默认从0开始
browser.switch_to.window(browser.window_handles[-1])
browser.get('https://www.taobao.com')#打开淘宝页面
time.sleep(1)
browser.switch_to.window(browser.window_handles[0])#跳转到第一个选项卡
browser.get('https://douban.com')time.sleep(1)
browser.quit()
# 运行结果:
# ['CDwindow-AD42B99E578AAAFBD39CE0B27261CEFB', 'CDwindow-A06ACF8B3CABE2F92782552A95C36071']

15、异常处理

  • 在使用selenium时,会经常遇到一些报错哦异常。例如:超时异常、节点未找到等报错异常,一旦出现这种异常,程序就会停止执行,这时我们可以使用try···except语句来实现捕获异常进行处理。
  • 更多异常类:文档
from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException
browser = webdriver.Chrome()
try:browser.get('https://www.baidu.com')
except TimeoutException:print('Time Out')
try:browser.find_element_by_id('hello')
except NoSuchElementException:print('No Element')
finally:browser.close()
# 运行结果
# No Element

16、浏览器退出

  • browser.close():关闭浏览器的一个标签页
  • browser.quit():关闭浏览器

17、截图操作

  • 在linux中,使用selenium进行截图,需要安装中文库,否则中文会变成方框。

  • Selenium截图有大的两个方式,一个是针对于浏览器而言,另一种是针对与元素而言

  • 针对于浏览器对象browser而言,有四种截图方式

    • driver.get_screenshot_as_base64():以 base64 编码字符串形式获取当前窗口的屏幕截图,在HTML界面输出截图时使用。
    • driver.get_screenshot_as_png():以二进制数据形式获取当前窗口的屏幕截图。
    • driver.save_screenshot(filename/full_path):获取截屏png图片,参数是文件名称,截屏必须是.png图片, 如果只给文件名,截图会保存在项目的根目录下面。
    • driver.get_screenshot_as_file(filename/full_path):获取截屏png图片,参数是文件的绝对路径,截屏必须是.png图片。如果只给文件名,截屏会存在项目的根目录下。
    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import Bydef save_screenshot_demo():'''获取截屏png图片,参数是文件名称,截屏必须是.png图片, 如果只给文件名,截图会保存在项目的根目录下面。:return:'''try:browser.get('https://www.baidu.com')browser.find_element(By.LINK_TEXT, '新闻').click()time.sleep(3)browser.switch_to.window(browser.window_handles[-1])browser.save_screenshot('save_screenshot_demo.png')  # save_screenshot的图片数据必须以png结尾finally:time.sleep(3)browser.quit()def get_screenshot_as_file_demo():'''获取截屏png图片,参数是文件的绝对路径,截屏必须是.png图片。如果只给文件名,截屏会存在项目的根目录下。:return:'''try:browser.get('https://www.baidu.com')browser.find_element(By.LINK_TEXT, '新闻').click()time.sleep(3)browser.switch_to.window(browser.window_handles[-1])browser.get_screenshot_as_file('get_screenshot_as_file_demo.png')  # get_screenshot_as_file的图片数据必须以png结尾finally:time.sleep(3)browser.quit()def get_screenshot_as_base64_demo():'''以 base64 编码字符串形式获取当前窗口的屏幕截图,在HTML界面输出截图时使用。:return:'''try:browser.get('https://www.baidu.com')browser.find_element(By.LINK_TEXT, '新闻').click()time.sleep(3)browser.switch_to.window(browser.window_handles[-1])b64 = browser.get_screenshot_as_base64()print(b64)finally:time.sleep(3)browser.quit()def get_screenshot_as_png_demo():'''以二进制数据形式获取当前窗口的屏幕截图。:return:'''try:browser.get('https://www.baidu.com')browser.find_element(By.LINK_TEXT, '新闻').click()time.sleep(3)browser.switch_to.window(browser.window_handles[-1])b_data = browser.get_screenshot_as_png()print(b_data)finally:time.sleep(3)browser.quit()
    
  • 针对于元素而言

    • element.screenshot(save_file_path):针对某一个元素进行截图,并报错到相对的路径文件
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as ec
    from selenium.webdriver.support.wait import WebDriverWait
    import randomdef selenium_screenshot(url, css_element: str, width=None, height=None, file_name=None):"""快照截图(截图某个元素):param url: url:param width:  窗口宽度:param height::param css_element: css定位:return:"""ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"driver = ""ip = ''# ip = "xxx.xxx.xxx.xxx"try:chrome_options = Options()chrome_options.add_argument('--headless')  # 无头模式chrome_options.add_argument('--disable-gpu')  # 禁用gpuchrome_options.add_argument('--no-sandbox')chrome_options.add_argument(f'user-agent={ua}')  # 添加UAif ip:chrome_options.add_argument(f'--proxy-server=http://{ip}:port"')driver = webdriver.Chrome(options=chrome_options)driver.maximize_window()if width:driver.set_window_size(width, height)driver.get(url)wait = WebDriverWait(driver, 10)wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, css_element)))ele = driver.find_element(By.CSS_SELECTOR, css_element)except Exception as err:print(f"{url}selenium_screenshot false:{err}")returnelse:if not file_name:file_name = random.random()save_file_path = f"{file_name}.png"ele.screenshot(save_file_path)print(f"selenium_screenshot success{url}")return save_file_pathfinally:if driver:driver.quit()
    

18、Selenium项目模板

这里给大家分享一个我自己常用的Selenium脚本执行的模板。

import timefrom selenium.webdriver import Chrome, ChromeOptions
from selenium.webdriver.support.wait import WebDriverWait
from tenacity import retry, stop_after_attemptTIME_OUT = 15  # wait最长等待时间class Selenium_Chrome(object):def __init__(self):# 参数初始化self.chrome_path = r''  # 指定chrome版本浏览器存放的路径self.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36'@retry(stop=stop_after_attempt(3)  # 重启三次)def start_chrome(self):'''Chrome初始化配置对象:return:'''chrome_options = ChromeOptions()if self.chrome_path:  # 如果指定Chrome的版本,就设置这个chrome_options.binary_location = self.chrome_path# chrome_options.add_argument("--headless")  # 无界面运行chrome_options.add_argument('accept-language="zh-CN,en-US;q=0.8"')chrome_options.add_argument(f'''user-agent={self.user_agent}''')chrome_options.add_experimental_option('useAutomationExtension', False)chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])chrome_options.add_argument("--disable-blink-features=AutomationControlled")chrome_options.add_argument('--disable-gpu')  # 爬虫的时候,我们一般会选择禁用GPU,如果不禁用,访客GPU都相同,太容易判断了chrome_options.add_argument('--no-sandbox')chrome_options.add_argument("-incognito")  # 设置无痕模式# 创建Chrome对象self.browser = Chrome(options=chrome_options)# 进行简单的规避操作self.browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})self.browser.maximize_window()  # 将窗口最大化self.wait = WebDriverWait(self.browser, TIME_OUT)def end_chrome(self):"""清除缓存并关闭chrome"""time.sleep(3)self.browser.delete_all_cookies()self.browser.quit()def start(self):try:self.start_chrome()'''这里存放主程序的各种执行函数'''self.browser.get('https://www.baidu.com')finally:self.end_chrome()if __name__ == '__main__':test = Selenium_Chrome()test.start()

总结

以上便是目前我在selenium中常用的方法以及知识汇总,其中可能还会有欠缺,如果实际操作中,有用到其他的案例,也会继续在这里进行添加。当然如果文章中有不对的地方,欢迎评论区留言进行指导,我会及时更改。在这里非常感谢开头的几篇优质文章作为参考。

Python_Selenium使用相关推荐

  1. python_selenium之第一个自动化脚本

    python_selenium之第一个自动化脚本 上一节介绍了xpath的使用,接下来完成第一个自动化脚本 一.步骤: 1. 这里使用火狐浏览器,首先打开火狐浏览器 2. 使浏览器窗口最大化 3.输入 ...

  2. 自动化测试工具selenium python_Selenium自动化测试工具使用方法汇总

    1.设置无头浏览器模式 from selenium import webdriver from selenium.webdriver.chrome.options import Options chr ...

  3. selenium录屏python_Selenium实现录屏的一种方法

    由于UI层自动化的不稳定性,经常会遇到执行中断或用例失败的问题,以下是一些常见的措施. 详细的日志 定位出错时截图 Pytest的缓存机制(可以记录成功了哪些失败了哪些) 自动重试机制(如pytest ...

  4. python_selenium项目_批量获取企业信用代码

    文章目录 PART1 前言 PART2 正文 一. 获取查询名单 [代码] [代码说明] 二.进入企查查开始查询 [代码] [代码说明] 三.存储数据并结束语句 [代码] [代码说明] PART3 结 ...

  5. python_selenium(五)

    警告弹窗处理 案例:点击百度首页设置按钮,然后进入搜索设置页面,点击"保存设置"或"恢复默认"按钮,处理警告弹窗窗口 from selenium import ...

  6. selenium定位a标签python_selenium自动化,已经定位到A标签的位置,但是点击A标签时不执行后台的js方法。...

    展开全部 在定位第一个栏目并模拟点击时,无法使用click方法,原来是左边的图标遮挡了a标签,32313133353236313431303231363533e4b893e5b19e313334336 ...

  7. selenium原理python_selenium + python自动化测试unittest框架学习(一)selenium原理及应用...

    unittest框架的学习得益于虫师的<selenium+python自动化实践>这一书,该书讲得很详细,大家可以去看下,我也只学到一点点用于工作中,闲暇时记录下自己所学才能更加印象深刻. ...

  8. 火狐浏览器驱动 python_Selenium环境变量配置(火狐浏览器)及验证实现

    前言 配置火狐浏览器对应的selenium驱动 一.火狐浏览器驱动下载 下载地址 根据对应的系统环境下载相应的压缩包(这里下载的是Windows系统64位安装包) 安装包下载成功后将压缩包解压 二.配 ...

  9. selenium原理python_selenium+python(之一)

    各位好,今天是我第一次写博客,工作了也有一段时间了,今天想分享一些学习到的内容,大家共同学习,共同进步,写的不好的地方,多多待见,比较功底有限. 今天想写一些自动化相关的东西,也算是记录一下学习的历程 ...

最新文章

  1. Battery electric vehicles (BEVs) 快充技术
  2. dis的前缀单词有哪些_英语单词词根.词缀II 5个最高频英语前缀 必背
  3. rsync 模块同步失败
  4. 在Cacti上实现MSN报警机制
  5. linux shell 编码规范
  6. PHP调用JS/CSS方法
  7. 《训练指南》——8.5
  8. Java excel 比较_java 实现两excel(或csv)文件的比对(以某几列作为键值,比对指定列的值差异)...
  9. asp.net core利用DI实现自定义用户系统,脱离ControllerBase.User
  10. 怎么判断一个字符串的最长回文子串是否在头尾_每日一道算法题,让你的头脑更活跃(寻找最长回文子串)...
  11. 掰一掰GitHub上优秀的大数据项目
  12. 搭建本地LNMP开发环境(2.5)-安装vim
  13. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_18-页面静态化-模板管理-GridFS研究-取文件...
  14. IDEA格式化SQL代码
  15. 地图投影——高斯-克吕格投影、墨卡托投影和UTM投影
  16. 4核处理器_最便宜的16核洋垃圾怎么样?建议别买
  17. 【一文带你读懂机器学习】xgboost原理
  18. 2016NOIP信息学竞赛提高组(北京)一等奖名单
  19. [语义分割]SPP、空洞卷积与ASPP总结
  20. 心电 基线漂移的处理研究论文

热门文章

  1. playbook 变量
  2. ThinkPHP5.0完全开发手册——调试模式
  3. 【经验分享】宝塔7.7.0解锁教程
  4. 双星无源定位之轨道模型
  5. Xshell Plus 6标准版详细安装破解教程,解决评估过期问题(附注册机,全网独家可用),非学校/家庭免费版
  6. 基于8086步进电机定时启动设计-基于8086八路智能抢答器系统控制设计-基于8086八路PT100热敏电阻温度采集-基于8086 8253定时计数器方波发生器仿真-基于8086的1602动态显示仿真
  7. 满心萧然最近及其颓废
  8. 美国香蒜牛小排(牛仔骨)[韩式做法]
  9. c语言中1. qnb,输出总是有1.#QNB和1.$,请问这是什么原因呀?
  10. 钱伟刚 计算机系,钱伟刚