Selenium相当于一个机器人。模拟人类在浏览器上的一些行为,自动处理浏览器上的一些行为,比如点击,填充数据,删除cookie等。
chromedriver是一个驱动chrome浏览器的驱动程序,使用它才可以驱动浏览器。当然针对不同的浏览器有不同的driver。下面是对应不同浏览器的driver
1、Chrome:Chrome下载链接
2、Firefox:Firefox下载链接
3、Edge:Edge下载链接
4、Safari:Safari下载链接
Selenium:官方文档
from selenium import webdriver
# 创建一个driver
driver = webdriver.Chrome(executable_path='chromedriver.exe')
# 调用get()方法访问url
url = 'https://www.baidu.com/'
driver.get(url)
运行效果
driver.close() | 关闭当前页面 |
driver.quit() | 退出整个浏览器 |
find_element_by_id | 根据id查找某个元素 |
find_element_by_class_name | 根据类名查找元素 |
find_element_by_name | 根据name属性的值来查找元素 |
find_element_by_tag_name | 根据标签名来查找元素 |
find_element_by_xpath | 根据xpath语法来获取元素 |
find_element_by_css_selector | 根据css选择器选择元素 |
注意,find_element是获取第一个满足条件的元素。find_elements是获取所有满足条件的元素
1、find_element_by_id
# 调用find_element_by_id()
search_hero = driver.find_element_by_id('kw')
# 验证是否查找成功,使用send_keys()方法
search_hero.send_keys('python selenium')
2、find_element_by_class_name
search_hero = driver.find_element_by_class_name('s_ipt')
3、find_element_by_name
search_hero = driver.find_element_by_name('wd')
4、find_element_by_tag_name
search_hero = driver.find_element_by_tag_name('span')
print(search_hero)
5、find_element_by_xpath
search_hero = driver.find_element_by_xpath('//input[@id = "kw"]')
6、find_element_by_css_selector
search_hero = driver.find_element_by_css_selector("#form #kw")
1、webelement.send_keys:给输入框填充内容
2、webelement.click:点击
3、操作select标签:需要首先用frome selenium.webdriver.support.ui import Select
,来包装选中的对象,才能进行select
选择
select_by_index | 按索引进行选择 |
select_by_value | 按值进行选择 |
select_by_visible_text | 按照可见文本进行选择 |
举个例子: 在访问知乎的时候首先显示的是免密登录,如果想要密码登录的话必须鼠标点击相应的表单
# 但是点击的时候url是不会有什么变化的,因此可以采取click()方法实现操作
input_pwd = driver.find_elements_by_class_name('SignFlow-tab')[1]
# 实现鼠标点击的操作
input_pwd.click()
username_input = driver.find_element_by_name('username')
username_input.send_keys('123123')
password_input = driver.find_element_by_name('password')
password_input.send_keys('654321')
# 如果要点击提交
submit = driver.find_element_by_class_name('SignFlow-submitButton')
submit.click()
有些网站可能会在浏览器端做一些验证, 看行为是否符合人类的行为来进行反爬虫。这个时候我们可以使用行为链来模拟人的操作。行为链有很多复杂的操作,比如攻击、右键等,在自动化测试用大有用途。
有的时候再界面当中的操作要有很多步,此时可以使用鼠标行为链
selenium.webdriver.common.action_chains.ActionChains
来完成。
例如:要鼠标移动到某个元素上并执行点击的操作。
例子1::百度的搜索框和按钮
代码实现:
driver = webdriver.Chrome(executable_path='chromedriver.exe')
# 调用get()方法访问url
url = 'https://www.baidu.com/'
driver.get(url)
inputTag = driver.find_element_by_id('kw')
submitTag = driver.find_element_by_id('su')
actions = ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag, 'python selenium')
actions.move_to_element(submitTag)
actions.click(submitTag)
actions.perform()
代码实现效果:
例子2:知乎登录界面
代码实现:
# 创建driver
driver = webdriver.Chrome(executable_path='chromedriver.exe')
# 发送get请求
driver.get('知乎网址')
# 需要通过代码,先进入到密码登录界面
input_pwd = driver.find_elements_by_class_name('SignFlow-tab')[1]
# 找到之后,调用click()点击这个界面
input_pwd.click()
# 创建行为链对象
actions = ActionChains(driver)
# 行为链分步写, 先获取指定的标签,用户名密码输入框以及提交按钮
username_tag = driver.find_element_by_name('username')
password_tag = driver.find_element_by_name('password')
submitBtn = driver.find_element_by_class_name('SignFlow-submitButton')
# 开始书写行为链
actions.move_to_element(username_tag)
actions.send_keys_to_element(username_tag, '1234567890')
actions.move_to_element(password_tag)
actions.send_keys_to_element(password_tag, '654321')
actions.move_to_element(submitBtn)
# 点击提交按钮
actions.click(submitBtn)
# 执行链中的所有动作
actions.perform()
代码实习效果:
更多的操作:
click_and_hold(element) | 点击鼠标左键但不松开 |
content_click(element) | 右键点击 |
double_click(element) | 双击 |
1、获取所有cookie | for cookie in driver.get_cookies(): print(cookie) |
2、根据cookie的key获取value | value = driver.get_cookie(key) |
3、删除所有cookie | driver.delete_all_cookies() |
4、删除某一个cookie | driver.delete_cookie(key) |
5、添加cookie | driver.add_cookie({'name':'username', 'value':'python'}) |
# 创建driver
driver = webdriver.Chrome(executable_path='chromedriver.exe')
# 发送get请求
driver.get('https://www.baidu.com')
# 获取所有cookie
cookies = driver.get_cookies()
for i in cookies:
print(i)
# 获取某个cookie
cookie = driver.get_cookie('PSTM')
print(cookie)
#添加cookie
driver.add_cookie({'name':'python', 'value':'123'})
res = driver.get_cookie('python')
print(res)
#删除某个cookie
driver.add_cookie({'name':'python', 'value':'hello world'})
cookie = driver.get_cookie('python')
print(cookie)
driver.delete_cookie('python')
res = driver.get_cookie('python')
print(res)
# 删除所有cookie
res = driver.get_cookies()
print(res)
driver.delete_all_cookies()
res = driver.get_cookies()
print(res)
现在的网页越来越多采用了Ajax技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际界面等待时间过长导致某个dom元素还没出来,但是代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。为了解决这个问题。selenium提供了两种等待方式;一种是隐式等待
,一种是显示等待
隐式等待:
调用driver.implicitly_wait(参数为秒数)
在获取不可用的元素之前,会先等待一定的秒数
# 发送get()请求,查找不存在的元素
driver.get('https://www.baidu.com')
driver.implicitly_wait(10)
res = driver.find_element_by_name('python')
print(res)
显示等待
显示等待是表明某个条件成立后才执行获取元素的操作。也可以在等待的时候指定一个最大时间,如果超过这个时间那么就抛出一个异常。
显示等待应该使用selenium.webdriver.support.excepted_conditions
期望的条件和selenium.webdriver.support.ui.WebDriverWait
来配合完成。
代码如下:
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
# 创建driver
driver = webdriver.Chrome(executable_path='chromedriver.exe')
# 发送get请求
driver.get('https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc')
# 只有输入了起点和终点时,下面的点击才能实现
WebDriverWait(driver, 100).until(
EC.text_to_be_present_in_element_value((By.ID, 'fromStationText'), '上海')
)
WebDriverWait(driver, 100).until(
EC.text_to_be_present_in_element_value((By.ID, 'toStationText'), '成都')
)
res = driver.find_element_by_id('query_ticket')
res.click()
Expected Conditions
There are some common conditions that are frequently of use when automating web browsers. Listed below are the names of each. Selenium Python binding provides some convenience methods so you don’t have to code an expected_condition class yourself or create your own utility package for them.
title_is
title_contains
presence_of_element_located
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
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
The expected_conditions module contains a set of predefined conditions to use with WebDriverWait.
有时候窗口中有很多子tab页面。这时候肯定需要进行切换的。selenium提供了一个叫做switch_to.window
来进行切换,具体切换到哪个界面可以从driver.window_handles
中找到
# 先访问百度
driver.get('https://www.baidu.com/')
# 执行js脚本
driver.implicitly_wait(1)
# window.open(URL)方法是打开代码的js代码
driver.execute_script("window.open('https://music.douban.com/tag/民谣')")
# 虽然现在执行了js代码,看着好像是到了一个新界面,但是此时的page_source还是百度的
# 如果想要获取打开的网站的源代码,需要使用switch_to.window()
print(driver.page_source)
# 如果想要获取打开的网站的源代码,需要使用switch_to.window()
# 里面调用driver.window_handles[index]即可,这是一个列表
# 里面是窗口的句柄
for i in driver.window_handles:
print(i)
driver.switch_to.window(driver.window_handles[1])
print(driver.page_source)
有时候频繁爬取网页的话,服务器发现是爬虫之后会封掉ip地址。此时我们可以更改代理ip,以chrome为例
使用ChromeOptions
来设置
# 创建options
options = webdriver.ChromeOptions()
# 增加代理
options.add_argument("--proxy-server=http://代理ip")
# 创建一个driver
driver = webdriver.Chrome(executable_path='chromedriver.exe',chrome_options=options)
driver.get('url')
get_property | 获取html标签中官方的属性 |
get_attribute | 获取html标签中官方和非官方的属性 |
driver.save_screenshot | 获取当前页面的截图,如果请求失败了,可以把当前页面的截图保存下来,以便日后分析 |
代码如下:
driver.get('指定url')
res_id = driver.find_element_by_id('python') # 先找到对应的div
res_pro_value = res_id.get_property('id')
print('get_property:获取官方属性', res_pro_value)
res_pro_value1 = res_id.get_property('my_div')
print('get_property:获取非官方属性', res_pro_value1)
res_pro_value2 = res_id.get_attribute('my_div')
print('get_attribute:获取非官方属性',res_pro_value2)
driver.get('https://www.baidu.com')
driver.save_screenshot('baidu.png')
如果想要继续向下深入学习的话可以查看返回结果的类型,看看里面有什么样的方法
res_id = driver.find_element_by_id('python') # 先找到对应的div
print(type(res_id))