selenium
一 安装与准备
1 pip install selenium
2 安装浏览器,下载浏览器对应的驱动
https://registry.npmmirror.com/binary.html?path=chromedriver
3 相关资料:
http://www.python3.vip/tut/auto/selenium/01/
https://www.bilibili.com/video/BV1Z4411o7TA?p=4
二 基本操作
1 浏览器
from selenium import webdriver
# 创建 WebDriver 对象,指明使用chrome浏览器驱动位置
wd = webdriver.Chrome(r'd:\webdrivers\chromedriver.exe') # 启动浏览器驱动与浏览器
# 设置寻找元素的最大等待时间,最大时间内周期性(每隔半秒钟)寻找该元素
wd.implicitly_wait(10)
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.baidu.com')
# 浏览器当前页面的源代码(一个或多个请求返回结果共同渲染后的前端源码)
wd.page_source
# 浏览器当前页面的标题
wd.title
# 当前页面url
wd.current_url
# 设置浏览器位置相较于屏幕左上角的位置
wd.set_window_position(300, 200)
# 页面刷新,模拟浏览器F5刷新
wd.refresh()
# 退出,释放资源
wd.quit()
*面浏览器
from selenium import webdriver
opt = webdriver.ChromeOptions() # 创建Chrome参数配置对象
# 把Chrome设置成可视化*面模式,windows/Linux 皆可
# opt.headless = True 或者采用下面方式
opt.add_argument('--headless') # *面
opt.add_argument('--disable-gpu') # 禁用gpu
driver = webdriver.Chrome(executable_path=r'd:\chromedriver.exe', options=opt) # 创建Chrome*面对象
2 选择元素的基本方法
1) 根据元素id属性选择元素
# 返回 WebElement 对象
element = wd.find_element_by_id('kw') # 获取元素
# element.send_keys("python\n") # 在元素中输入python回车,回车搜索
2) 根据元素的class属性获取元素
# 获取class名为animal的所有元素,返回一个列表
wd.find_elements_by_class_name('animal') # 列表,不存在[]
# 获取第一个class名为animal的元素
wd.find_element_by_class_name('animal') # 对象,不存在异常
例子
from selenium import webdriver
# 创建 WebDriver 实例对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome(r'd:\webdrivers\chromedriver.exe')
# WebDriver 实例对象的get方法 可以让浏览器打开指定网址
wd.get('http://cdn1.python3.vip/files/selenium/sample1.html')
# 根据 class name 选择元素,返回的是 一个列表
# 里面 都是class 属性值为 animal的元素对应的 WebElement对象
elements = wd.find_elements_by_class_name('animal')
# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容
for element in elements:
print(element.text) # 获取元素文本内容
3)通过标签名获取元素
# 获取所有标签名为div的元素,返回列表
elements = wd.find_elements_by_tag_name('div')
# 获取第一个标签名为div的元素,返回对象
element = wd.find_element_by_tag_name('div')
4) 在获取完的元素基础上继续调用前面获取元素的方法,仅查询范围有变化,用法不变
5) 获取a链接元素
# find_element_by_link_text('完整文本')
wd.find_element_by_link_text('登录').click()
# find_element_by_partial_link_text('部分文本内容')
wd.find_element_by_partial_link_text('a标签包含的文本内容')
6) 通过名字获取元素
wd.find_element_by_name('name')
7) 其他表现形式
from selenium.webdriver.common.by import By
wd.find_element(By.CLASS_NAME, 'classname')
wd.find_element(By.LINK_TEXT, 'text')
wd.find_element(By.TAG_NAME, 'div')
...
3 操作元素
1) 点击元素
element.click()
2) 获取元素内文本内容
element.text
3) 获取元素属性
element.get_attribute(属性名)
4) 获取元素包含的所有html内容
element.get_attribute('outerHTML')
5)获取元素内部的所有html内容
element.get_attribute('innerHTML')
6) 获取input输入框里面的文字
element.get_attribute('value')
7) 获取元素文本内容(无法用text获取时)
element.get_attribute('innerText')
element.get_attribute('textContent')
8) 清除输入框中的内容
element.clear()
9) 输入框中输入内容
element.send_keys('内容')
4 CSS Selector语法选择元素
1) 基本语法
find_element_by_css_selector(CSS Selector参数) # 单个
find_elements_by_css_selector(CSS Selector参数) # 多个
通过标签获取
elements = wd.find_elements_by_css_selector('div') # 获取所有标签名为div的元素
elements = wd.find_elements_by_tag_name('div')
通过class
elements = wd.find_elements_by_css_selector('.类名')
通过id
elements = wd.find_elements_by_css_selector('#ID名')
2) 选择子元素和后代元素
# 元素1 > 元素2 获取元素2,直接子元素
wd.find_elements_by_css_selector('.类名1 > 标签2') # 获取类名1下面的所有直接子元素标签2
# 元素1 > 元素2 > 元素3... 获取某个元素,可以多级
# 元素1 元素2 获取后代元素
wd.find_elements_by_css_selector('#ID1 标签2') # 获取ID1下的所有标签2
# 可以空格和>混用
wd.find_elements_by_css_selector('#ID1 .类名2 > 标签3') # 获取ID1下的所有类名2的子元素标签3
3) 根据属性选择
# [属性=值]
wd.find_elements_by_css_selector('[href="http...."]') # 获取包含指定href属性的元素
# 与基本获取方法混用
wd.find_elements_by_css_selector('div[href="http...."]') # 获取含有指定href的div元素
wd.find_elements_by_css_selector('div [href="http...."]') # 获取div下含有指定href的元素
4) 混合使用
# 组合使用
div#id.class[属性]
div #id.class[属性]
# 并列选取,使用逗号隔开
div, .class # 选择div和类名元素
.class div, .class span
5) 按照次序选择
# 限制:nth-child(第几个)
div:nth-child(2) # 选择所有div标签下的第二个子元素
# 限制:nth-last-child(1)
div:nth-last-child(1) # div下最后一个子元素
# 类型:nth-of-type(1)
span:nth-of-type(2) # 选择所有标签下第二个span元素
# 类型:nth-last-of-type(2)
span:nth-last-of-type(2) # 选择所有标签下最后一个span元素
# 限制:nth-child(odd)
span:nth-child(odd) # 获取所有span标签下的奇数节点
# 限制:nth-child(even)
span:nth-child(even) # 获取所有span标签下的偶数节点
# 限制 类型:nth-of-type-child(odd)
.ID div:nth-of-type(even) # ID下获取所有偶数的div节点
6)兄弟节点
# div + div
.ID + span # ID下紧跟的span元素,同一级
# div ~ div
.ID ~ span # ID下所有的span
5 frame或iframe元素,操作嵌套的html
# 切换到frame中
wd.switch_to.frame(ID或name或element对象) # 加在查找元素之前,切换到frame中
# 切回外层
wd.switch_to.default_content()
# 或者使用句柄切回外层
wd.switch_to.window(wd.window_handles[0])
6 切换窗口
current_windows = driver.window_handles # 获取当前所有的标签页的句柄的列表
wd.switch_to.window(current_windows[1]) # 传入下标切换
# 切换窗口
wd.switch_to.window(句柄) # 需要窗口的句柄
# 获取窗口的句柄
for handle in wd.window_handles: # 遍历获取的所有网页句柄
wd.switch_to.window(handle) # 切换到窗口
if 需要的字段 in wd.title:
break # 当前handle为所需的句柄
# 保存当前窗口的句柄
mainWindow = wd.current_window_handle
wd.switch_to.window(mainWindow) # 切换回当前窗口
7 select下拉框选择元素
# 创建Select对象
from selenium.webdriver.support.ui import Select
select = Select('传入操作的元素element')
# select_by_visible_text
select.select_by_visible_text('文本') # 可见文本
# select_by_value
select.select_by_value('属性值') # 该文本对应得属性值
# select_by_index
select.select_by_index('次序') # 该选项的次序,从1开始
# 前面加de表示不选,deselect_by_visible_text
# select.deselect_all 全不选
8 其他操作 ActionChains
例如:鼠标移动到元素上
from selenium import webdriver
driver = webdriver.Chrome(r'f:\chromedriver.exe')
driver.implicitly_wait(5)
driver.get('https://www.baidu.com/')
from selenium.webdriver.common.action_chains import ActionChains
ac = ActionChains(driver)
# 鼠标移动到元素上
ac.move_to_element(
driver.find_element_by_css_selector('[name="tj_briicon"]')
).perform() # 调用perform才会执行移动
9 冻结页面
// 在 开发者工具栏 console 里面执行如下js代码
setTimeout(function(){debugger}, 5000) // 表示在 5000毫秒后,执行 debugger 命令
10 xpath
/ 从根节点选取,或元素之间的过渡,一级一级关系 /html/body/div
// 元素之间过渡,可以不是一层的上下级关系 //div
.. 当前节点的父节点 //div/p/../
@ 选取属性 //div[@class='class_name']/@class 获取含class_name的标签的class名,在selenium不能写/@class,应该用get_attribute获取属性
text() 选取文本 //p[test()='哈哈']/text() # 只返回标签对象自己的内容,不会返回子级的,//p[test()='哈哈']//text() 返回所有text,包括子级的。在selenium中只能使用element.text
//div[1] # 所有div标签的第一个,从1开始
//div[last()] # 最后一个, last()-1倒数第二个
//div[position()>1] # 从第二个开始
//*[@*="user"] # 第一个*表示任意节点,第二个*表示任意属性
//div/node() # 匹配任意节点,包含注释属性等 //div/node()/text()
示例
/html/body//div/../a[@href='uer']/test()
//*[text()='嘿嘿']/div[last()-1]/p[2]/@id
//div[1]/./../p
11 执行js
# wd.execute_script(js语句)
wd.execute_script('window.scrollTo(0, {})'.format(500)) # 每次滚轮滑动500
12 获取cookie,删除
# 获取当前标签页的全部cookie信息,列表嵌套字典
wd.get_cookies()
# 删除一条cookie
wd.delete_cookie('cookiename')
# 删除所有cookie
wd.delete_all_cookies()
13 显示等待
from selenium.webdrive.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdrive.common.by import By
WebDriverWait(wd, 20, 0.5).until(
expected_conditions.presence_of_element_located(
(By.CLASS_NAME, 'classname')
)
)
14 使用代理ip
from selenium import webdriver
options = webdriver.ChromeOptions()
# 使用代理ip
options.add_argument('--proxy-server=http://202.2016.82:9527')
driver = wevdriver.Chrome(chrome_options=options)
15 替换user-agent
from selenium import webdriver
options = webdriver.ChromeOptions()
# 替换User-Agent
options.add_argument('--user-agent=Mozillia/5.0 HAHA')