赞
踩
Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。这个工具的主要功能包括:测试与浏览器的兼容性——测试应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成.Net、Java、Perl等不同语言的测试脚本。
框架底层使用JavaScript模拟真实用户对浏览器进行操作。测试脚本执行时,浏览器自动按照脚本代码做出点击,输入,打开,验证等操作,就像真实用户所做的一样,从终端用户的角度测试应用程序。
使浏览器兼容性测试自动化成为可能,尽管在不同的浏览器上依然有细微的差别。
使用简单,可使用Java,Python等多种语言编写用例脚本。
Selenium的作用:利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)
Selenium的工作原理:
python/python3 -m pip install selenium
webdriver区分不同os环境和版本,安装webdriver需要对应浏览器的版本。
这上面的界面下载对应os版本的chromedriver。我这里使用win10做演示,所以下载“chromedriver_win32.zip”。
解压此压缩包后双击chromedriver.exe运行
先设置chromedriver的环境变量
调用演示
import time
from selenium import webdriver
options = webdriver.ChromeOptions()
# 这个是绝对路径
driver = webdriver.Chrome(executable_path="C:\chromedriver\chromedriver.exe",options=options)
# driver = webdriver.Chrome() # 这是已配置环境变量版的,但经测试效果不好,后面就使用绝对路径版的。
driver.get("https://blog.csdn.net/")
# 最大化浏览器
driver.maximize_window()
time.sleep(3)
driver.close()
访问https://registry.npmmirror.com/binary.html?path=chromedriver/,点击进入下载mac版本的chromedriver。或者这个页面:http://chromedriver.storage.googleapis.com/index.html
下载好后配置环境变量:
进入/usr/local/bin目录(由于Mac该目录是隐藏的,所以可通过快捷键command+shift+g打开)
代码实例:
from selenium import webdriver
import time
wd = webdriver.Chrome()
wd.get("https://www.baidu.com") # 打开百度浏览器
time.sleep(3) #等待3秒
wd.quit() #关闭浏览器
我们在用Python做爬虫的时候,会经常用到无页面浏览器phantomjs。 但是我们一般用chrome/firefox查看效果,再转成phantomjs。这样比较费时间,另一方面phantomjs不太稳定,而且官方已经停止维护了。所以我们再linux系统安装各个浏览器。 安装方法1:yum install google-chrome -y 不能装上的话就尝试直接下载后安装 安装方法2: 下载chrome:wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 可能会遇到网路问题,你可以先下载到本地再上传 安装chrome浏览器 yum install ./google-chrome-stable_current_x86_64.rpm -y google-chrome --version 查看版本 安装配置chromedriver 注意chromedriver的版本,要与你安装的chrome版本对应上,这里的版本已经不是最新的。 版本列表:访问https://registry.npmmirror.com/binary.html?path=chromedriver/,或者这个页面:http://chromedriver.storage.googleapis.com/index.html 下载chromedriver_linux64.zip wget wget https://registry.npmmirror.com/-/binary/chromedriver/89.0.4389.23/chromedriver_linux64.zip 解压chromedriver_linux64.zip unzip chromedriver_linux64.zip 为chromedriver授权 chmod 755 chromedriver 拷贝至可执行目录 cp ./chromedriver /usr/bin/ Python代码测试
import time from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--headless") # 开启无界面模式 options.add_argument('--no-sandbox') options.add_argument("--disable-gpu") options.add_argument('--disable-dev-shm-usage') # linux上需要设置上面四项内容。 driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver') driver.get("http://www.itcast.cn/") # 把网页保存为图片,69版本以上的谷歌浏览器将无法使用截图功能 driver.save_screenshot("itcast.png") time.sleep(3) print(driver.title) # 打印页面的标题 # 退出模拟浏览器 driver.quit() # 一定要退出!不退出会有残留进程!
import time from selenium import webdriver options = webdriver.ChromeOptions() # 这个是绝对路径 driver = webdriver.Chrome(executable_path="C:\chromedriver\chromedriver.exe",options=options) # driver = webdriver.Chrome() # 这是已配置环境变量版的,但经测试效果不好,后面就使用绝对路径版的。 driver.get("https://www.baidu.com") # 访问指定网页 driver.maximize_window() # 最大化浏览器 driver.page_source # 当前标签页浏览器渲染之后的网页源代码 driver.current_url # 当前标签页的url driver.quit() # 关闭浏览器 time.sleep(2) driver.get("https://www.csdn.net/") # 页面转到csdn time.sleep(2) driver.back() # 页面后退回baidu time.sleep(2) driver.forward() # 页面前进到csdn driver.save_screenshot("baidu.png") # 页面截图 time.sleep(3) driver.title # 获取页面标题 driver.desired_capabilities # 获取浏览器信息 driver.get_cookies() # 获取页面的cookies信息 driver.fullscreen_window() # 全屏 driver.session_id driver.close() # 关闭当前标签页,如果只有一个标签页则关闭整个浏览器
显示结果如下:
显示结果如下:
显示结果如下:
结果如下:
find_element_by_id (返回一个元素) find_element(s)_by_class_name (根据类名获取元素列表) find_element(s)_by_name (根据标签的name属性值返回包含标签对象元素的列表) find_element(s)_by_xpath (返回一个包含元素的列表) find_element(s)_by_link_text (根据连接文本获取元素列表) find_element(s)_by_partial_link_text (根据链接包含的文本获取元素列表) find_element(s)_by_tag_name (根据标签名获取元素列表) find_element(s)_by_css_selector (根据css选择器来获取元素列表) 注意: - find_element和find_elements的区别: - 多了个s就返回列表,没有s就返回匹配到的第一个标签对象; - find_element匹配不到就抛出异常,find_elements匹配不到就返回空列表; - by_link_text和by_partial_link_tex的区别:全部文本和包含某个文本 - 以上函数的使用方法 - driver.find_element_by_id('id_str')
from selenium import webdriver import time url = "https://www.baidu.com" options = webdriver.ChromeOptions() driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) # 请求Url # 第一步:再百度上查找“翡翠鉴定”的关键词。这里是通过xpath获取input的输入框标签 driver.find_element_by_xpath('//*[@id="kw"]').send_keys("翡翠鉴定") # 通过css_selector获取input的输入框标签,再选取css选择器时右键“Copy selector”就可获取 driver.find_element_by_css_selector('#kw').send_keys("和田玉") # 通过class_name获取input的输入框标签,class_name使用时可能会出现多个相同的class_name的名字 driver.find_element_by_class_name('s_ipt').send_keys("今天是否下雨") # 通过name属性获取input的输入框标签 driver.find_element_by_name('wd').send_keys("python3") # 通过link_text获取input的输入框标签 driver.find_element_by_link_text('新闻').click() # 通过_partial_link_text获取input的输入框标签 driver.find_element_by_partial_link_text('hao').click() # 通过tag_name获取input的输入框标签,目标元素再当前html中是唯一元素或是众多标签的第一个才能显示。 print(driver.find_element_by_tag_name('title')) # 第二步:找到百度一下的标签后执行点击的动作click(),这里是通过id来获取“百度一下的输入框标签” driver.find_element_by_id('su').click()
结果显示:
find_element仅仅能够获取元素,不能够直接获取其中的数据,如果需要获取数据需要使用以下方法:
- 对元素执行点击操作element.click()
对定位到的标签对象进行点击操作
- 向输入框输入数据element.send_keys(data)
对定位到的标签对象输入数据
- 获取文本element.text
通过定位获取的标签对象的text属性,获取文本内容
- 获取属性值element.get_attribute("属性名")
通过定位获取的标签对象的get_attribute函数,传入属性名,来获取属性的值
from selenium import webdriver import time url = "https://58.com/zufang/" # options = webdriver.ChromeOptions() # options.add_argument("--headless") # 开启无界面模式 # options.add_argument('--no-sandbox') # options.add_argument("--disable-gpu") # options.add_argument('--disable-dev-shm-usage') # linux上需要设置上面四项内容。 # driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver') options = webdriver.ChromeOptions() driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) # 请求Url el_list = driver.find_elements_by_xpath('//*[@id="global"]/table/tbody/tr/td[2]/a') for el in el_list: print(el.text) # 打印文本信息 print(el.get_attribute('href')) # 打印链接信息
运行结果:
from selenium import webdriver import time url = "https://gitee.com/login" # options = webdriver.ChromeOptions() # options.add_argument("--headless") # 开启无界面模式 # options.add_argument('--no-sandbox') # options.add_argument("--disable-gpu") # options.add_argument('--disable-dev-shm-usage') # linux上需要设置上面四项内容。 # driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver') options = webdriver.ChromeOptions() driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) # 请求Url driver.find_element_by_xpath('//*[@id="user_login"]').clear() # 先清空输入框中的文字 time.sleep(2) driver.find_element_by_xpath('//*[@id="user_login"]').send_keys('用户名') # 发送登录账号 time.sleep(2) driver.find_element_by_xpath('//*[@id="user_password"]').clear() # 先清空输入框中的文字 time.sleep(2) driver.find_element_by_xpath('//*[@id="user_password"]').send_keys('密码') # 发送登录密码 driver.find_element_by_xpath('//*[@id="new_user"]/div/div/div/div[4]/input').click() # 点击登录操作
当selenium控制浏览器打开多个标签页时,如何控制浏览器在不同的标签页中进行切换呢?需要我们做以下两步:
- 获取所有标签页的窗口句柄
- 利用窗口句柄字切换到句柄指向的标签页
- 这里的窗口句柄是指:指向标签页对象的标识
具体的方法:
第一步: 获取当前所有的标签页的句柄构成的列表
current_windows = driver.window_handles
第二步: 根据标签页句柄列表索引下标进行切换
driver.switch_to.window(current_windows[0])
from selenium import webdriver import time url = "https://cn.58.com/" # options = webdriver.ChromeOptions() # options.add_argument("--headless") # 开启无界面模式 # options.add_argument('--no-sandbox') # options.add_argument("--disable-gpu") # options.add_argument('--disable-dev-shm-usage') # linux上需要设置上面四项内容。 # driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver') options = webdriver.ChromeOptions() driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) # 请求Url print(driver.current_url) # 打印当前请求的Url print(driver.window_handles) # 查看当前页面句柄 ele = driver.find_element_by_xpath('/html/body/div[3]/div[1]/div[1]/div/div[1]/div[1]/span[7]/a') # 定位到二手房的标签 ele.click() # 点击进入此页面 driver.switch_to_window(driver.window_handles[-1]) # 跳转到二手房的页面 print(driver.current_url) # 打印此时请求的url print(driver.window_handles) # 查看二手房页面的句柄 ,应该有两个 xiangxi = driver.find_element_by_xpath('//*[@id="esfMain"]/section/section[3]/section[1]/section[2]/div[1]/a/div[2]/div[1]/div[1]/h3') # 定位到二手房第一个房源的标签 print(xiangxi.text) # 查看是否获取其标签的文本内容 xiangxi.click() # 点击进入此房源的页面 driver.switch_to_window(driver.window_handles[-1]) # 跳转到此房的详细页面 print(driver.current_url) # 查看此时访问的页面url print(driver.window_handles) # 查看详细页面的句柄 neixiang = driver.find_element_by_xpath('//*[@id="__layout"]/div/div[2]/div[2]/div[2]/div[1]/div[2]/div[1]/span[1]').text # 获取价格标签的文本信息 print(neixiang)
iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是driver.switch_to.frame(frame_element)。
from selenium import webdriver import time # url = "https://wx.mail.qq.com/" url = "https://mail.qq.com/" # options = webdriver.ChromeOptions() # options.add_argument("--headless") # 开启无界面模式 # options.add_argument('--no-sandbox') # options.add_argument("--disable-gpu") # options.add_argument('--disable-dev-shm-usage') # linux上需要设置上面四项内容。 # driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver') options = webdriver.ChromeOptions() driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) # 请求Url driver.maximize_window() # 大界面显示 login_qq = driver.find_element_by_id('login_frame') # 根据id定位 frame元素 driver.switch_to_frame(login_qq) # 跳转到frame上 # driver.find_element_by_xpath('//*[@id="u"]').send_keys('用户名') # 发送登录用户名 driver.find_element_by_xpath('//*[@id="p"]').send_keys('密码') # 发送登录密码 time.sleep(3) driver.find_element_by_xpath('//*[@id="login_button"]').click() # 点击登录
driver.get_cookies()返回列表,其中包含的是完整的cookie信息!不光有name、value,还有domain等cookie其他维度的信息。
所以如果想要把获取的cookie信息和requests模块配合使用的话,需要转换为name、value作为键值对的cookie字典.
示例:
获取当前标签页的全部cookie信息
print(driver.get_cookies())
把cookie转化为字典
cookies_dict = {cookie[‘name’]: cookie[‘value’] for cookie in driver.get_cookies()}
删除一条cookie
driver.delete_cookie("CookieName")
删除所有的cookie
driver.delete_all_cookies()
from selenium import webdriver import time url = "https://mail.163.com/" # options = webdriver.ChromeOptions() # options.add_argument("--headless") # 开启无界面模式 # options.add_argument('--no-sandbox') # options.add_argument("--disable-gpu") # options.add_argument('--disable-dev-shm-usage') # linux上需要设置上面四项内容。 # driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver') options = webdriver.ChromeOptions() driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) # 请求Url driver.maximize_window() # 大界面显示 cookie_list = driver.get_cookies() print(cookie_list) cookies_dict = {cookie['name']: cookie['value'] for cookie in cookie_list} print(cookies_dict)
执行js的方法:driver.execute_script(js)
import time
from selenium import webdriver
url = "http://www.taobao.com/"
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象
driver.get(url) # 请求Url
time.sleep(1)
js = 'window.scrollTo(0,document.body.scrollHeight)' # js语句 向下拉滑动条
driver.execute_script(js) # 执行js的方法
time.sleep(5)
driver.quit()
页面在加载的过程中需要花费时间等待网站服务器的响应,在这个过程中标签元素有可能还没有加载出来,是不可见的,如何处理这种情况呢?接下来就简单介绍一下。
强制等待
隐式等待
显式等待
其实就是time.sleep()
缺点是不智能,设置的时间太短,元素还没有加载出来;设置的时间太长,则会浪费时间
隐式等待针对的是元素定位,隐式等待设置了一个时间,在一段时间内判断元素是否定位成功,如果完成了,就进行下一步
在设置的时间内没有定位成功,则会报超时加载
from selenium import webdriver
url = "http://www.taobao.com/"
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象
driver.implicitly_wait(10) # 隐式等待,最长等20秒
driver.get(url)
driver.implicitly_wait(3)
driver.find_element_by_xpath('/html/body/div[3]/div[2]/div[1]/div/ul[1]/li[5]/a').click()
每经过多少秒就查看一次等待条件是否达成,如果达成就停止等待,继续执行后续代码
如果没有达成就继续等待直到超过规定的时间后,报超时异常
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 options = webdriver.ChromeOptions() driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) # 请求Url driver.maximize_window() # 大界面显 # 显式等待 WebDriverWait(driver, 20, 0.5).until( EC.presence_of_element_located((By.LINK_TEXT, '好123'))) # 参数20表示最长等待20秒 # 参数0.5表示0.5秒检查一次规定的标签是否存在 # EC.presence_of_element_located((By.LINK_TEXT, '好123')) 表示通过链接文本内容定位标签 # 每0.5秒一次检查,通过链接文本内容定位标签是否存在,如果存在就向下继续执行;如果不存在,直到20秒上限就抛出异常 print(driver.find_element_by_link_text('好123').get_attribute('href')) driver.quit()
在了解了隐式等待和显式等待以及强制等待后,我们发现并没有一种通用的方法来解决页面等待的问题,比如“页面需要滑动才能触发ajax异步加载”的场景,那么接下来我们就以淘宝网首页为例,手动实现页面等待。
原理:
利用强制等待和显式等待的思路来手动实现。
不停的判断或有次数限制的判断某一个标签对象是否加载完毕(是否存在)。
import time from selenium import webdriver url = "http://www.taobao.com/" options = webdriver.ChromeOptions() driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) time.sleep(1) # i = 0 # while True: for i in range(10): i += 1 try: time.sleep(3) element = driver.find_element_by_xpath('/html/body/div[3]/div[2]/div[1]/div/ul[1]/li[5]/a') print(element.get_attribute('href')) break except: js = 'window.scrollTo(0, {})'.format(i*500) # js语句 driver.execute_script(js) # 执行js的方法 driver.quit()
绝大多数服务器是没有界面的,selenium控制谷歌浏览器也是存在无界面模式的,这一小节我们就来学习如何开启无界面模式(又称之为无头模式)
开启无界面模式的方法
实例化配置对象
options = webdriver.ChromeOptions()
配置对象添加开启无界面模式的命令
options.add_argument("--headless")
options.add_argument('--no-sandbox')
配置对象添加禁用gpu的命令
options.add_argument("--disable-gpu")
options.add_argument('--disable-dev-shm-usage')
实例化带有配置对象的driver对象
driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver')
options = webdriver.ChromeOptions()
options.add_argument("--headless") # 开启无界面模式
options.add_argument('--no-sandbox')
options.add_argument("--disable-gpu")
# linux上需要设置上面三项内容。
driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver')
from selenium import webdriver
import time
url = "https://mail.163.com/"
options = webdriver.ChromeOptions()
options.add_argument("--headless") # 开启无界面模式
options.add_argument("--disable-gpu")
driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象
driver.get(url) # 请求Url
print(driver.title)
driver.quit()
options = webdriver.ChromeOptions()
options.add_argument("--headless") # 开启无界面模式
options.add_argument('--no-sandbox')
options.add_argument("--disable-gpu")
# linux上需要设置上面三项内容。
driver = webdriver.Chrome(chrome_options=options,executable_path='/usr/bin/chromedriver')
注意:macos中chrome浏览器59+版本,Linux中57+版本才能使用无界面模式
使用代理ip的方法:
实例化配置对象
options = webdriver.ChromeOptions()
配置对象添加使用代理ip的命令
options.add_argument('--proxy-server=http://IP:port')
实例化带有配置对象的driver对象
driver = webdriver.Chrome('./chromedriver', chrome_options=options)
import time
from selenium import webdriver
url = "https://www.baidu.com/"
options = webdriver.ChromeOptions()
options.add_argument('--proxy-server=http://101.200.127.149:3129')
driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象
driver.get(url) # 请求Url
element = driver.find_element_by_xpath('//*[@id="s-top-left"]/a[2]')
print(element.get_attribute('href'))
driver.quit()
import time import random from selenium import webdriver url = "https://www.baidu.com/" ip_list = [ "http://58.220.95.34:10174", "http://112.6.117.178:8085", "http://58.220.95.8:10174", "http://58.246.58.150:9002", "http://36.134.91.82:8888", "http://219.246.65.55:80", "http://218.59.139.238:80", "http://120.220.220.95:8085", "http://120.42.46.226:6666", "http://58.220.95.42:10174", "http://101.200.127.149:3129", ] random_ip = random.choice(ip_list) proxy_IP = '--proxy-server=' + random_ip print(proxy_IP) options = webdriver.ChromeOptions() options.add_argument(proxy_IP) driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象 driver.get(url) # 请求Url element = driver.find_element_by_xpath('//*[@id="s-top-left"]/a[2]') print(element.get_attribute('href')) driver.quit()
替换user-agent的方法:
实例化配置对象
options = webdriver.ChromeOptions()
配置对象添加替换UA的命令
options.add_argument('--user-agent=Mozilla/5.0 HAHA')
实例化带有配置对象的driver对象
driver = webdriver.Chrome('./chromedriver', chrome_options=options)
import time
from selenium import webdriver
url = "https://www.baidu.com/"
options = webdriver.ChromeOptions()
options.add_argument('--proxy-server=http://101.200.127.149:3129')
options.add_argument('--user-agent=Mozilla/5.0 HAHA')
driver = webdriver.Chrome(executable_path='C:\chromedriver\chromedriver.exe',options=options) # 对象
driver.get(url) # 请求Url
element = driver.find_element_by_xpath('//*[@id="s-top-left"]/a[2]')
print(element.get_attribute('href'))
driver.quit()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。