【python】初探Selenium

Selenium简介

Javascript动态渲染的界面不止Ajax一种,当网页中请求的内容不包含Ajax请求(某些网站的图形是经Javascript计算后生成的),或者Ajax请求被加密(例如淘宝的Ajax接口含有加密参数,难以爬取),利用Selenium可以直接模拟人的点击对网站内容进行处理

学会库的用法最直接的办法就是阅读文档:
中文文档:https://python-selenium-zh.readthedocs.io/zh_CN/latest/

使用简介

准备工作

①直接使用pip方法进行安装

pip install selenium

②ChromeDriver的安装
安装地址:http://npm.taobao.org/mirrors/chromedriver/
找到自己chrome当前的版本并进行相应的下载

然后找到自己想存储的文件位置,并把它加入到环境变量中

from selenium import webdriver
browsr = webdriver.Chrome()

也可以选择其他浏览器,但是chrome浏览器的内核比较强大,所以用chrome比较多

如果出现闪退,看版本是否正确,或者引用time库,让其暂停任意时间

from selenium import webdriver
import time
browsr = webdriver.Chrome()
time.sleep(10)

基本使用

声明浏览器对象

你也可以使用火狐、edge、safari等等浏览器,但这里我用的是chrome所以就用chrome做演示了

from selenium import webdriver
browsr = webdriver.Chrome()

访问页面

使用get()方法可以直接向目标网页发起链接请求

brower.get('www.baidu.com')
print(browser.page_source)
browser.close()

以上代码运行后会显示出一个浏览器,并且在控制台打印百度网站的源码
在这里插入图片描述
在这里插入图片描述

查找结点

根据不同方式选择节点,等方法,加上s就是找到这个界面中所有的目标节点

browser.find_element_by_id('q')
browser.find_element_by_xpath()
browser.find_element_by_css_selector()

在这里插入图片描述
在这里插入图片描述

使用find_element()方法,传入两个参数,第一个参数表示根据什么来查找,第二个参数表示该属性值。结果和上面得到的完全一致,只不过更加灵活,例如下面:

browser.find_element(By.ID,'q')

节点交互

基本操作如下

input = browser.find_element_by_id('q')#找到输入的接口
# 输入文字
input.send_keys('IpadPro')
# 清空文字
input.clear()
#找到按钮的位置
button=browser.find_element_by_id('.....')
# 点击按钮
button.click()

动作链

当有一些操作没有特定执行对象的时候用动作链来执行,最后使用perform()方法实行
ActionChains可以分步写,也可以一次性写完,如下:

menu = browser.find_element_by_css_selector(".nav")
hidden_submenu = browser.find_element_by_css_selector(".nav #submenu1")
#一次性写完
ActionChains(browser).move_to_element(menu).click(hidden_submenu)
# 分布写完
actions = ActionChains(browser)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()

实现CTRL+c
键盘事件
key_down 模拟键盘摁下某个按键 key_up 松开某个按键,与sendkey连用完成一些操作,每次down必须up一次否则将出现异常。按下某个字符就要调用send_keys()方法,最后调用perform方法

ActionChains(driver).key_down(Keys.CONTROL,dis).send_keys('c').perform()
# key_down(value,element)后一个参数是想要操作的元素
value:按下的键(例如按下CRTL键:Keys.CONTROL)
element:想选中的元素

执行JavaScript

对于某些操作,selenium api没有提供,这时候可以用脚本

browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 滑动到底部
browser.execute_script('alert("To Buttom")')
# alert内部填上想弹出的文字

下面结合上面两个举个例子:

# 可以用于双击某个动态生成位置的地方
driver = webdriver.Chrome()
# 最大化窗口
driver.maximize_window()
driver.get('http://ui.imdsx.cn/uitester/')
time.sleep(2)
driver.execute_script('window.scrollTo(0,0);')
#scrollTo()函数会将屏幕右上角作为(00)
time.sleep(1)
a = driver.find_element_by_id('a').location  # 获取元素坐标,返回的是一个字典
# {'x': 716, 'y': 112}
dis = driver.find_element_by_id('dis1')
ActionChains(driver).move_by_offset(a['x'],a['y']).double_click(dis).perform()

获取节点信息


切换Frame

网页中有种节点叫作 iframe ,也就是子 Frame ,相当于页面的子页面,它的结构和外
网页的结构完全相同, Selenium 打开页面后,它默认是在父级 Frame 里面操作,而此时如果页面中
还有子Frame ,它是不能获取到子 Frame 里面的节点的 这时就需要使用 switc _to.frame()方法来切换frame,填入的参数可以是index, name, or webelement
在这里插入图片描述


延时等待

Selenium 中, get()方法会在网页框架加载结束后结束执行,此时如果获取 page_source ,可能并不是浏览器完全加载完成的页面,如果某些页面有额外的 Ajax 请求,我们在网页代码中也不定能成功获取到.所以,这里需要延时等待一定时间,确保节点已经加载。这里等待的方式有两种 种是隐式等待, 种是显式等待
①隐式等待
使用隐式等待执行测试的时候,如果 Selenium 没有在 DOM 中找到节点,会继续等待,超过一定时间还找不到会抛出异常。默认时间是0

browser.implicitly_wait(5)

②显式等待
指定要查找的节点,然后指定一个最长等待时间。若超过时间依然没有加载出来就抛出超时异常。

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

browser = webdriver.Chrome()
browser.get('https://www.taobao.com/')
wait = WebDriverWait(browser, 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')))
print(input, button) 

更多等待条件及含义

等待条件含义
title_is标题是某内容
title_contains标题包含某内容
presence_of_element_located节点加载出,传入定位元组,如 (By.ID, ‘p’)
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 frame加载并切换
invisibility_of_element_located节点不可见
element_to_be_clickable节点可点击
staleness_of判断一个节点是否仍在 DOM,可判断页面是否已经刷新
element_to_be_selected节点可选择,传节点对象
element_located_to_be_selected节点可选择,传入定位元组
element_selection_state_to_be传入节点对象以及状态,相等返回 True,否则返回 False
element_located_selection_state_to_be传入定位元组以及状态,相等返回 True,否则返回 False
alert_is_present是否出现 Alert

前进和后退

browser.back()#后退
browser.forward()#前进

Cookies

对cookies进行获取、添加、删除

browser.add_cookie({。。。})
browser.get_cookies()#获取所有cookies
browser.get_cookie()#获取指定名字的cookie
browser.delete_all_cookies()
browser.delete_cookie()# 删除指定名字的cookie

注意
使用f12工具查看cookies的时候从headers得到的cookies没办法使用
需要在application查看
在这里插入图片描述

add_cookie接收的字典格式

cookie = {
    'domain': '.58.com', #Firefox浏览器不能写domain,如果写了会报错,谷歌需要写否则也是报错,这里就是一个坑。其他浏览器没测试不知道情况。
    'name': name,
    'value': value,
    "expires": "",
    'path': '/',
    'httpOnly': False,
    'HostOnly': False,
    'Secure': False,
}

name:cookie的名称

value:cookie对应的值,动态生成的

domain:服务器域名

expiry:Cookie有效终止日期

path:Path属性定义了Web服务器上哪些路径下的页面可获取服务器设置的Cookie

httpOnly:防脚本攻击

secure:在Cookie中标记该变量,表明只有当浏览器和Web Server之间的通信协议为加密认证协议时

选项卡管理

browser.execute_script('window.open()')#开启一个新的选项卡
browser.switch_to_window(browser.window_handles[1])#参数是标签页的代号,可以选择在某个标签页进行操作

异常处理

利用try except语句来捕获各种异常

from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementExcertion
browser = webdriver.Chrome()
try:
	browser. get ( ' https: I /www. baidL .com ’)
except TimeoutException:
	print(' time out ')
try:
	browser.find_element_by id('hello')
except NoSuchElementException:
	print(' No Element ') 
finally:
	browser.close() 

实战



©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页