一、简介
Selenium
是一个web
应用程序自动化测试工具,对各种浏览器都能很好地支持,包括Chrome
、Firefox
这些主流浏览器。- 使用它可以模拟浏览器进行各种各样的操作,包括爬取一些网页内容。当看到浏览器自己运行并且在网页上翻页或者跳转的时候,应该会觉得很有趣的。
Selenium
支持有/无
界面浏览器操作,无界面浏览器
执行效率会更高,毕竟右界面浏览器
会需要调用很多资源,都需要等待。Selenium
会直接允许在浏览器中,就像真的用户在操作一样,为什么叫真的用户?
之前通过urllib
之类的方式去模拟浏览器请求获取数据的,或多或少会缺失一些东西,模拟的终究是带假的,在有些防爬比较狠的,模拟的是拿不到有些东西,想拿到得费不少手脚,而Selenium
则能直接驱动真实的浏览器。Selenium 2
又名WebDriver
,它的主要新功能是集成了Selenium 1.0
以及WebDriver
(WebDriver
曾经是Selenium
的竞争对手)。也就是说Selenium 2
是Selenium
和WebDriver
两个项目的合并,即Selenium 2
兼容Selenium
,它既支持Selenium API
也支持WebDriver API
。当这两个框架被合并后,一个框架的缺陷被另一个框架所弥补。- 相比
QTP
有诸多有点:
- 免费,也不用再为破解
QTP
而大伤脑筋。 - 小巧,对于不同的语言它只是一个包而已,而
QTP
需要下载安装1
个多G
的程序。 - 这也是最重要的一点,不管以前更熟悉
C
、java
、ruby
、python
、或C#
,都可以通过Selenium
完成自动化测试,而QTP
只支持VBS
。 - 支持多平台:
windows
、linux
、MAC
,支持多浏览器:ie
、ff
、safari
、opera
、chrome
… - 支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器的执行,相当于分发机的功能。
- 必看 - 下载对应浏览器驱动详细步骤。
- 使用步骤
# 1、导入 from selenium import webdriver # 2、创建浏览器驱动对象(以 Chrome 举例) # 不传驱动路径默认会去 Python 根目录找,所以驱动一般会存放在那里,如果做测试也可以直接放到项目中,配置路径即可 driver = webdriver.Chrome() driver = webdriver.Chrome(驱动路径) # 3、访问网址 driver.get('https://www.baidu.com') # 4、使用结束,关闭浏览器驱动对象,防止资源占用 driver.quit() # 注意:在运行使用驱动启动浏览器时,需要允许防火墙安全访问,mac 得去【隐私与安全性】中允许使用
- 代码跑起后,没有写关闭浏览器的代码,运行几秒后,浏览器自动关闭的问题解决。
- 附:Python Chrome handless(无界面浏览器,add_argument 支持哪些参数,替代 PhantomJS)
二、基本使用(元素定位、信息)
# 【启动浏览器驱动】 # 导入 selenium from selenium import webdriver # 如果需要指定路径,但是路径在新版本中被重构到 Service 函数中了 # from selenium.webdriver.chrome.service import Service # 导入常量对象(可以点进去看看,其实也可以手写) from selenium.webdriver.common.by import By # 1、浏览器驱动路径 # win_path = 'chromedriver.exe' # mac_path = 'chromedriver' # 2、直接传入字符串路径报错:DeprecationWarning: executable_path has been deprecated, please pass in a Service object # 原因是这种写法将放弃使用 # driver = webdriver.Chrome(mac_path) # 2、需要使用 Service 进行包裹一下【推荐】 # options = webdriver.ChromeOptions() # options.add_experimental_option('detach', True) # 不自动关闭浏览器 # service = Service(mac_path) # driver = webdriver.Chrome(service=service, options=options) # 创建浏览器对象 options = webdriver.ChromeOptions() options.add_experimental_option('detach', True) # 不自动关闭浏览 driver = webdriver.Chrome(options=options) # 打开指定网址 driver.get('https://www.baidu.com') # 获取网页源码 # print(driver.page_source) # 【元素定位】8 种,可以点击 By 进入看看支持的类型 # driver.find_element() 返回一个元素,单个对象 # driver.find_elements() 返回多个元素,数组对象 # # 1、通过 ID 定位元素 # e = driver.find_element('id', 'su') # By 是一个常量对象,其实也可以手写 # e = driver.find_element(By.ID, 'su') # 通过 ID 获取对应元素 # # <input type="submit" id="su" value="百度一下" class="bg s_btn"> # # 2、通过 XPATH 定位元素 # e = driver.find_element(By.XPATH, '//input[@id="su"]') # # <input type="submit" id="su" value="百度一下" class="bg s_btn"> # # 3、通过 LINK_TEXT(链接文本) 定位元素(也就是通过 a 标签的文本内容获得到这个 a 标签) # e = driver.find_element(By.LINK_TEXT, '地图') # # <a href="http://map.baidu.com" target="_blank" class="mnav c-font-normal c-color-t">地图</a> # # 4、通过 PARTIAL_LINK_TEXT(链接文本) 定位元素(也就是通过 a 标签的部分文本内容进行模糊匹配(任意部分,模糊匹配 a 标签内容),获得到这个 a 标签) # e = driver.find_element(By.PARTIAL_LINK_TEXT, '地') # # <a href="http://map.baidu.com" target="_blank" class="mnav c-font-normal c-color-t">地图</a> # # 5、通过 NAME(标签属性) 定位元素 # e = driver.find_element(By.NAME, 'wd') # # <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off"> # # 6、通过 TAG_NAME(标签名字) 定位元素 # e = driver.find_element(By.TAG_NAME, 'input') # 获取到第一个 input 标签返回 # es = driver.find_elements(By.TAG_NAME, 'input') # 获取所有 input 标签返回,数组 # # 7、通过 CLASS_NAME 定位元素 # e = driver.find_element(By.CLASS_NAME, 's_ipt') # # <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off"> # # 8、通过 CSS_SELECTOR(选择器) 来定位元素,支持 bs4 的语法 # e = driver.find_element(By.CSS_SELECTOR, '#su') # # <input type="submit" id="su" value="百度一下" class="bg s_btn"> # 【访问元素信息】 # 通过 ID 获取元素 e = driver.find_element(By.ID, 'su') # <input type="submit" id="su" value="百度一下" class="bg s_btn"> # 获取 class 属性值 print(e.get_attribute('class')) # bg s_btn # 获取 id 属性值 print(e.get_attribute('id')) # su # 获取标签名称 print(e.tag_name) # input # 获取标签内容(这里的内容指的是标签元素中间的内容,而不是 value 值) e = driver.find_element(By.LINK_TEXT, '新闻') print(e.text) # 关闭浏览器驱动对象 # driver.quit()
三、交互案例
自动百度搜索 周杰伦
,然后滚到到底部切换下一页,在来回切换。
# 【启动浏览器驱动】 # 导入 selenium from selenium import webdriver # 如果需要指定路径,但是路径在新版本中被重构到 Service 函数中了 # from selenium.webdriver.chrome.service import Service # 导入常量对象(可以点进去看看,其实也可以手写) from selenium.webdriver.common.by import By # 导入 定时器 from time import sleep # 1、浏览器驱动路径 # win_path = 'chromedriver.exe' # mac_path = 'chromedriver' # 2、直接传入字符串路径报错:DeprecationWarning: executable_path has been deprecated, please pass in a Service object # 原因是这种写法将放弃使用 # driver = webdriver.Chrome(mac_path) # 2、需要使用 Service 进行包裹一下【推荐】 # options = webdriver.ChromeOptions() # options.add_experimental_option('detach', True) # 不自动关闭浏览器 # service = Service(mac_path) # driver = webdriver.Chrome(service=service, options=options) # 创建浏览器对象 options = webdriver.ChromeOptions() options.add_experimental_option('detach', True) # 不自动关闭浏览 driver = webdriver.Chrome(options=options) # 打开指定网址 driver.get('https://www.baidu.com') # 【交互】 # 睡眠(注意:这个延迟主要是用来模拟人的行为,还有个就是操作之间需要一点延迟,比如加载完马上就去干什么,可能代码刚好浏览器没反应过来,所以给它缓口气,这样保障执行结果) # 打开/访问/点击....这些调用方法都是同步,也就是并不需要使用睡眠去估算加载完成时间,每个方法都是完成之后才会走下一行代码,除非写了异步,所以只是单纯的为了要浏览器缓一下能准确的识别命令 sleep(1) # 找到输入框 input = driver.find_element(By.ID, 'kw') # 在文本框中输入周杰伦 input.send_keys('周杰伦') # 睡眠 sleep(1) # 找到百度一下 button = driver.find_element(By.ID, 'su') # 点击按钮 button.click() # 睡眠 sleep(1) # 滑到底部 js_bottom = 'document.documentElement.scrollTop = 100000' # 导入 js driver.execute_script(js_bottom) # 睡眠 sleep(1) # 找到下一页按钮 nextButton = driver.find_element(By.XPATH, '//a[@class="n"]') # 点击下一页 nextButton.click() # 睡眠 sleep(1) # 滚到底部 driver.execute_script(js_bottom) # 睡眠 sleep(1) # 回到上一页(浏览器上的方向键 左) driver.back() # 睡眠 sleep(1) # 回到上一页(这里是回到上一页,不是上上页,浏览器上的方向键 右) driver.forward() # 睡眠 sleep(1) # 滚到底部 driver.execute_script(js_bottom) # 睡眠 sleep(1) # 退出 driver.quit()