自动化工具selenium的使用
一.selenium+Python环境配置
1.安装Python3.5及以上版本,这里我安装的是Python3.7.4
2.安装selenium:pip install selenium
3.安装对应浏览器版本的驱动webdriver,查找对应版本如下
- chromedriver:http://npm.taobao.org/mirrors/chromedriver/
- geckodriver:https://github.com/mozilla/geckodriver/releases/
- IE:http://selenium-release.storage.googleapis.com/index.html
4.将下载的webdriver(例如chromedriver.exe)文件放置在python环境变量目录的文件夹里
二.元素定位及浏览器基本操作
1.启动浏览器,前提是已经配置好环境
启动谷歌浏览器
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
启动火狐浏览器
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('https://www.baidu.com/')
启动ie浏览器
from selenium import webdriver
driver = webdriver.Ie()
driver.get('https://www.baidu.com/')
2.无头(无界面)启动浏览器
浏览器在后台静默运行,无需打开浏览器窗口,大大提升了selenium的运行效率
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--headless') # 无界面
options.add_argument('--disable-gpu') # 禁用GPU
driver = webdriver.Chrome(options=options)
driver.get('https://www.taobao.com/')
print(driver.page_source)
driver.quit() # 关闭浏览器
3.加载配置启动浏览器
selenium操作浏览器默认是不加载任何配置,如果需要加载用户的配置,可以使用如下方式
注意:
- 在加载用户配置时,如果你事先打开了浏览器占用了用户配置,会导致报错
- 用户配置路径使用双斜杠,或者像我一样在前面加r
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument(r'--user-data-dir=C:UsersAdministratorAppDataLocalGoogleChromeUser Data')
driver=webdriver.Chrome(options=options)
driver.get('https://www.taobao.com/')
4.元素定位
- id定位:find_element_by_id()
- name定位:find_element_by_name()
- class定位:find_element_by_class_name()
- link定位:find_element_by_link_text()
- partial_link定位:find_element_by_partial_link_text()
- tag定位:find_element_by_tag_name()
- xpath定位:find_element_by_xpath()
- css定位:find_element_by_css_selector()
- find_element配合By定位:find_element(By.XPATH, '//*[@id="q"]')
By类的一些属性如下:
- ID = "id"
- XPATH = "xpath"
- LINK_TEXT = "link text"
- PARTIAL_LINK_TEXT = "partial link text"
- NAME = "name"
- TAG_NAME = "tag name"
- CLASS_NAME = "class name"
- CSS_SELECTOR = "css selector"
定位多个元素:在element后加个s(写的时候注意看清楚)
- id定位:find_elements_by_id()
- name定位:find_elements_by_name()
- class定位:find_elements_by_class_name()
- link定位:find_elements_by_link_text()
- partial_link定位:find_elements_by_partial_link_text()
- tag定位:find_elements_by_tag_name()
- xpath定位:find_elements_by_xpath()
- css定位:find_elements_by_css_selector()
- find_element配合By定位:find_elements(By.XPATH, '//*[@id="q"]')
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.taobao.com")
driver.page_source
input_second = driver.find_element(By.ID,"q")
input_third = driver.find_element_by_xpath('//*[@id="q"]')
input_first = driver.find_elements_by_css_selector("li")
input_second = driver.find_element(By.CSS_SELECTOR,"li")
driver.quit()
5.执行JS操作
import time
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://www.zhihu.com/explore")
# 向上滑动进度条到顶部,并弹出‘To Button’文字
driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
driver.execute_script("alert('To Button')")
time.sleep(2)
driver.quit()
6.获取元素的属性
- current_url 获取当前的url
- page_source 获取渲染后的网页源代码
- get_attribute('href') 获取元素的href属性
- text 获取元素的文本
- location 获取元素在浏览器中的位置
- size 获取元素的尺寸大小
- id 获取id
- tag_name 获取标签名
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://www.zhihu.com/explore")
logo=driver.find_element_by_css_selector("div.top-recommend-feed.feed-item")
logo.get_attribute("class") # 获取元素的类名
logo.text # 获取元素的文本,可以获取子元素的文本
logo.id # id
logo.location # 在浏览器中的位置
logo.tag_name # 标签名
logo.size # 大小,占据多少像素,显示宽度和高度
browser.quit()
7.操作浏览器
- driver.maximize_window() 浏览器最大化
- driver.minimize_window() 浏览器最小化
- driver.set_window_size(480, 800) 设置浏览器宽480/高800
- driver.forword() 前进
- driver.back() 后退
- driver.refresh() 刷新网页
8.操作对象
- click() 点击对象
- send_keys('text') 在对象上模拟输入text文本
- clear() 清空对象的内容
- submit() 提交对象的内容
9.键盘事件
from selenium.webdriver.common.keys import Keys
send_keys(Keys.TAB) # TAB
send_keys(Keys.ENTER) # 回车
send_keys(Keys.CONTROL,'a') # 组合键ctrl+a
10.鼠标事件
鼠标事件一般包括鼠标右键、双击、拖动、移动鼠标到某个元素上等等
ActionChains 常用方法:
- perform() 执行所有ActionChains中存储的行为
- context_click() 右击
- double_click() 双击
- drag_and_drop() 拖动
- move_to_element() 鼠标悬停
交互链执行拖拽动作,多层框架frame的切换
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.alert import Alert
driver=webdriver.Chrome()
driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
driver.switch_to.frame("iframeResult") # 切换到目标元素所在的标签名frame上
source=driver.find_element_by_id("draggable") # 确定拖拽目标的起点
target=driver.find_element_by_id("droppable") # 确定拖拽目标的终点
actions=ActionChains(driver)
actions.drag_and_drop(source, target)
actions.perform() # 执行拖拽动作
time.sleep(2)
t=driver.switch_to.alert # 切换到alert弹出框对象上
print(t.text) # 获取弹出的文本
t.accept() # 点击确认按钮
time.sleep(3)
driver.quit()
三.selenium的3种等待方式
1.强制等待
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://baidu.com')
time.sleep(3) # 强制等待3秒再执行下一步
print(driver.current_url)
driver.quit()
2.隐式等待
隐式等待是设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步,不管你有没有拿到想要的元素
隐式等待对整个driver的周期都起作用,所以只要设置一次即可
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(30) # 隐性等待,最长等30秒
driver.get('https://baidu.com')
print(driver.current_url)
driver.quit()
3.显示等待
明确的要等到某个元素的出现或者是某个元素满足给定的条件,才会结束等待,保证条件一定会执行成功
等不到,就一直等,在规定的时间之内都没找到,就抛出异常。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver=webdriver.Chrome()
url="https://www.taobao.com"
driver.get(url)
# 创建等待的时间
wait=WebDriverWait(driver,10)
# 创建等待的条件,条件里传入一个元组,返回一个对象
input=wait.until(EC.presence_of_element_located((By.ID,"q")))
button=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn-search")))
button.click()
driver.quit()
4.EC(expected_conditions)
显式等待一般配合EC来使用,用于确定你要等待的元素满足某个条件或者不满足某个条件,确保元素一定加载出来,否则抛出异常
- title_is: 判断当前页面的title是否精确等于预期
- title_contains: 判断当前页面的title是否包含预期字符串
- presence_of_element_located:判断某个元素是否被加到了dom树里,并不代表该元素一定可见
- visibility_of_element_located:判断某个元素是否可见.可见代表元素非隐藏,并且元素的宽和高都不等于0
- visibility_of:跟上面的方法做一样的事情,只是上面的方法要传入locator,这个方法直接传定位到的element就好了
- presence_of_all_elements_located:判断是否至少有1个元素存在于dom树中
- text_to_be_present_in_element:判断某个元素中的text是否包含了预期的字符串
- text_to_be_present_in_element_value:判断某个元素中的value属性是否包含了预期的字符串
- frame_to_be_available_and_switch_to_it:判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False
- invisibility_of_element_located:判断某个元素中是否不存在于dom树或不可见
- element_to_be_clickable:判断某个元素中是否可见并且是enable的,这样的话才叫clickable
- staleness_of:等某个元素从dom树中移除,注意,这个方法也是返回True或False
- element_to_be_selected:判断某个元素是否被选中了,一般用在下拉列表
- element_selection_state_to_be:判断某个元素的选中状态是否符合预期
- element_located_selection_state_to_be:跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入locator
- alert_is_present:判断页面上是否存在alert,这是个老问题,很多同学会问到
四.cookies的处理
- driver.get_cookies() 获取浏览器cookie
- driver.delete_all_cookies() 删除浏览器cookie
- driver.add_cookie(cookies) 往浏览器添加cookie
import time
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://www.zhihu.com/explore")
driver.get_cookies()
driver.add_cookie({"name":"name","domain":"www.zhihu.com","value":"germey"})
print(driver.get_cookies())
driver.delete_all_cookies()
print(driver.get_cookies())
driver.quit()
五.选项卡管理
import time
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://www.zhihu.com/explore")
# 在同一个窗口打开一个新的网页
driver.execute_script("window.open()")
all_handles = driver.window_handles # 获取所有的窗口或句柄
driver.switch_to.window(all_handles[1]) # 切换到第二个选项卡
driver.get("https://www.taobao.com")
time.sleep(1)
driver.switch_to.window(all_handles[0]) # 回到第一个选项卡
driver.get("https://baidu.com")
driver.quit()
六.异常处理
from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException
driver=webdriver.Chrome()
try:
driver.get("https://www.zhihu.com/explore")
except TimeoutException:
print("Time out")
try:
driver.find_element_by_id("hello")
except NoSuchElementException:
print("No Element")
finally:
driver.quit()
七.selenium的代理模式
from selenium import webdriver
option = webdriver.ChromeOptions()
option.add_argument("--proxy-server=http://61.138.33.20:808")
driver = webdriver.Chrome(options=option)
driver.get('http://httpbin.org/get')
info = driver.page_source
print(info)
driver.quit()
八.selenium使用授权代理
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
def create_proxyauth_extension(proxy_host, proxy_port,
proxy_username, proxy_password,
scheme='http', plugin_path=None):
if plugin_path is None:
plugin_path = 'vimm_chrome_proxyauth_plugin.zip'
manifest_json = """
{
"version": "1.0.0",
"manifest_version": 2,
"name": "Chrome Proxy",
"permissions": [
"proxy",
"tabs",
"unlimitedStorage",
"storage",
"<all_urls>",
"webRequest",
"webRequestBlocking"
],
"background": {
"scripts": ["background.js"]
},
"minimum_chrome_version":"22.0.0"
}
"""
background_js = string.Template(
"""
var config = {
mode: "fixed_servers",
rules: {
singleProxy: {
scheme: "${scheme}",
host: "${host}",
port: parseInt(${port})
},
bypassList: ["foobar.com"]
}
};
chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});
function callbackFn(details) {
return {
authCredentials: {
username: "${username}",
password: "${password}"
}
};
}
chrome.webRequest.onAuthRequired.addListener(
callbackFn,
{urls: ["<all_urls>"]},
['blocking']
);
"""
).substitute(
host=proxy_host,
port=proxy_port,
username=proxy_username,
password=proxy_password,
scheme=scheme,
)
with zipfile.ZipFile(plugin_path, 'w') as zp:
zp.writestr("manifest.json", manifest_json)
zp.writestr("background.js", background_js)
return plugin_path
if __name__ == "__main__":
proxyauth_plugin_path = create_proxyauth_extension(
proxy_host="host",
proxy_port=16819,
proxy_username="username",
proxy_password="password"
)
chrome_options = webdriver.ChromeOptions()
chrome_options.add_extension(proxyauth_plugin_path)
driver = webdriver.Chrome(options=chrome_options)
driver.get("http://61.146.213.163:8011/user_kfs.aspx")
print(driver.page_source)
driver.quit()
九.忽略证书错误日志
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
driver = webdriver.Chrome(options=options)