文章目录
Selenium 介绍
• selenium是一个web的自动化测试工具,最初是为网站自动化测试而开发的,selenium可以直接运行在浏览器上,它支持所有主流的浏览器,可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏
• chromedriver是一个驱动Chrome浏览器的驱动程序,使用他才可以驱动浏览器。当然针对不同的浏览器有不同的driver。以下列出了不同浏览器及其对应的driver:
• Chrome:https://sites.google.com/a/chromium.org/chromedriver/downloads
• Firefox:https://github.com/mozilla/geckodriver/releases
• Edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
• Safari:https://webkit.org/blog/6900/webdriver-support-in-safari-10/
• 下载chromedriver
安装Selenium:pip install selenium
Phantomjs快速入门
无头浏览器:一个完整的浏览器内核,包括js解析引擎,渲染引擎,请求处理等,但是不包括显示和用户交互页面的浏览器
Phantomjs案例
1.加载网页
from selenium import webdriver
driver = webdriver.PhantomJS("安装目录")
driver.get("https://www.baidu.com")
driver.save_screenshot("baidu.png")
2.定位和操作
driver.find_element_by_id("kw").send_keys("长城")
driver.find_element_by_id("su").click()
3.查看请求信息
driver.page_source
driver.get_cookies()
driver.current_url
4.退出
driver.quit()
selenium快速入门
from selenium import webdriver
# 实例化浏览器
driver = webdriver.Chrome()
# 发送请求
driver.get('https://www.baidu.com')
# 退出浏览器
driver.quit()
1:定位元素
Selenium提供了8种定位方式:
id
name
class name
tag name
link text
partial link text
xpath
css selector
- find_element_by_id:根据id来查找某个元素
submitTag = driver.find_element_by_id('su')
submitTag1 = driver.find_element(By.ID,'su')
- 通过class name定位:
dr.find_element_by_class_name("s_ipt")
- find_element_by_name:根据name属性的值来查找元素
submitTag = driver.find_element_by_name('email')
submitTag1 = driver.find_element(By.NAME,'email')
- find_element_by_tag_name:根据标签名来查找元素
submitTag = driver.find_element_by_tag_name('div')
submitTag1 = driver.find_element(By.TAG_NAME,'div')
- find_element_by_xpath:根据xpath语法来获取元素
dr.find_element_by_xpath("//*[@id='kw']")
dr.find_element_by_xpath("//*[@name='wd']")
dr.find_element_by_xpath("//input[@class='s_ipt']")
dr.find_element_by_xpath("/html/body/form/span/input")
dr.find_element_by_xpath("//span[@class='soutu-btn']/input")
dr.find_element_by_xpath("//form[@id='form']/span/input")
dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")
注意:
find_element是获取第一个满足条件的元素。find_elements是获取所有满足条件的元素
2:多表单切换
在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位。这时就需要通过switch_to.frame()方法将当前定位的主体切换为frame/iframe表单的内嵌页面中
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://mail.163.com/")
driver.switch_to.frame(0)#需要跳转到表单内,但是发现表单id是变化的,所以就使用【0】定位表单
driver.find_element_by_name("email").clear()
driver.find_element_by_name("email").send_keys("ahhahah")
driver.find_element_by_name("password").clear()
driver.find_element_by_name("password").send_keys("ahhahah")
driver.find_element_by_id("dologin").click() # 登录按钮
注意:当登陆后别忘了跳出表单(.switch_to.default_content())再去爬取数据
参考文章
3:控制浏览器操作的一些方法
4:鼠标事件
-
click(on_element=None):单击
on_element:指被点击的元素,如果该参数为none,将单击当前鼠标所在位置 -
double_click(on_element=None):双击
on_element:只要双击的元素,如果该参数为none,将单击当前鼠标所在位置 -
context_click(on_element=None): 右击
-
on_element:只要双击的元素,如果该参数为none,将单击当前鼠标所在位置
-
drag_and_drop(source, target):鼠标拖动
Source:鼠标拖动的元素 Target:鼠标释放的目标元素 -
move_to_element(to_element) :鼠标悬停
to_element:指定元素 -
move_to_t(to_element) :鼠标移动
to_element:指定元素 -
perform():提交已保存的操作
-
click_and_hold(on_element=None):按住鼠标左键在元素上,点击并且不释放
-
on_element:指要按住鼠标左键的元素,如果该参数为none,将单击当前鼠标所在位置。
-
release(on_element=None) 释放鼠标
on_element:被鼠标释放的元素
from selenium import webdriver
#1.引入 ActionChains 类
from selenium.webdriver.common.action_chains import ActionChains
#1.创建Chrome浏览器对象,这会在电脑上在打开一个浏览器窗口
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")
#2.定位到要悬停的元素
element= driver.find_element_by_link_text("设置")
#3.对定位到的元素执行鼠标悬停操作
ActionChains(driver).move_to_element(element).perform()
#找到链接
elem1=driver.find_element_by_link_text("搜索设置")
elem1.click()
#通过元素选择器找到id=sh_2,并点击设置
elem2=driver.find_element_by_id("sh_1")
elem2.click()
#保存设置
elem3=driver.find_element_by_class_name("prefpanelgo")
elem3.click()
5: 键盘事件
from selenium import webdriver
# 导入selenium中的键盘事件keys
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
time.sleep(3)
# 搜索框中输入‘selenium’
driver.find_element_by_id('kw').send_keys('selenium')
# 调用键盘事件 空格
driver.find_element_by_id('kw').send_keys(Keys.SPACE)
driver.find_element_by_id('kw').send_keys('python')
# 调用键盘事件 组合键control+a
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a')
6:Cookie操作
• 获取所有的cookie
cookies = driver.get_cookies()
• 根据cookie的name获取cookie
value = driver.get_cookie(key)
• 删除某个cookie
driver.delete_cookie('key')
7:Selenium页面等待
页面等待
现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。为了解决这个问题。所以Selenium 提供了两种等待方式:一种是隐式等待、一种是显式等待
- 隐式等待:调用driver.implicitly_wait。那么在获取不可用的元素之前,会先等待10秒中的时间
driver.implicitly_wait(10)
- 显示等待:显示等待是表明某个条件成立后才执行获取元素的操作。也可以在等待的时候指定一个最大的时间,如果超过这个时间那么就抛出一个异常。显示等待应该使用selenium.webdriver.support.excepted_conditions期望的条件和selenium.webdriver.support.ui.WebDriverWait来配合完成
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()
driver.get("https://www.baidu.com/")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "id"))
)
finally:
driver.quit()
一些其他的等待条件
• presence_of_element_located:某个元素已经加载完毕了。
• presence_of_all_elements_located:网页中所有满足条件的元素都加载完毕了。
• element_to_be_clickable:某个元素是可以点击了
注意:一般加上显示等待配合隐式
更多条件请参考:
详情请点击查看
8:打开多窗口和切换页面
• 有时候窗口中有很多子tab页面。这时候肯定是需要进行切换的。selenium提供了一个叫做switch_to_window来进行切换,具体切换到哪个页面,可以从driver.window_handles中找到
# 打开一个新的页面
driver.execute_script("window.open('url')")
print(driver.current_url)
# 切换到这个新的页面中
driver.switch_to_window(self.driver.window_handles[1])
9:调用JavaScript代码
from selenium import webdriver
from time import sleep
#1.访问百度
driver=webdriver.Chrome()
driver.get("http://www.baidu.com")
#2.搜索
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
#3.休眠2s目的是获得服务器的响应内容,如果不使用休眠可能报错
sleep(2)
#4.通过javascript设置浏览器窗口的滚动条位置
js="window.scrollTo(100,450);"
driver.execute_script(js)
sleep(3)
driver.close()
- 通过浏览器打开百度进行搜索,并且提前通过set_window_size()方法将浏览器窗口设置为固定宽高显示,目的是让窗口出现水平和垂直滚动条。然后通过execute_script()方法执行JavaScripts代码来移动滚动条的位置。
滚动条上下左右滚动代码演示
from selenium import webdriver
from time import sleep
driver=webdriver.Chrome()
driver.set_window_size(400,400)
driver.get("https://www.baidu.com")
#2.搜索
# driver.find_element_by_id("kw").send_keys("selenium")
# driver.find_element_by_id("su").click()
#3.休眠2s目的是获得服务器的响应内容,如果不使用休眠可能报错
sleep(10)
#4 滚动左右滚动条---向右
js2 = "var q=document.documentElement.scrollLeft=10000"
driver.execute_script(js2)
sleep(15)
#5 滚动左右滚动条---向左
js3 = "var q=document.documentElement.scrollLeft=0"
driver.execute_script(js3)
sleep(15)
#6 拖动到滚动条底部---向下
js = "var q=document.documentElement.scrollTop=10000"
driver.execute_script(js)
sleep(15)
#7 拖动到滚动条底部---向上
js = "var q=document.documentElement.scrollTop=0"
driver.execute_script(js)
sleep(15)
driver.close()
滚动到页面底部也可以这样
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
窗口截图
无界面浏览器
option=webdriver.ChromeOptions()
option.add_argument('headless') # 设置option
driver = webdriver.Chrome(chrome_options=option) # 调用带参数的谷歌浏览器
selenium规避被检测识别
现在不少大网站有对selenium采取了监测机制。比如正常情况下我们用浏览器访问淘宝等网站的window.navigator.webdriver的值为undefined。而使用selenium访问则该值为true。那么如何解决这个问题呢?
只需要设置Chromedriver的启动参数即可解决问题。在启动Chromedriver之前,为Chrome开启实验性功能参数excludeSwitches,它的值为[‘enable-automation’]
from selenium.webdriver import Chrome
from selenium.webdriver import ChromeOptions
option = Chromeoptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
driver = Chrome(options=option)