python + selenium 学习笔记 -摘要

一、浏览器操作相关

from selenium import webdriver

driver = webdriver.Chrome()

driver.maximize_window()   # 窗口最大化
driver.set_window_size(400,800)  # 设置窗口大小

driver.back()   # 回退一层
driver.forward()  # 前进一层
driver.quit()  # 退出浏览器
driver.close()  # 关闭浏览器

二、元素定位

# 根据id定位
driver.find_element_by_id("kw").send_keys("hello")
# 根据name属性定位
driver.find_element_by_name("kw").send_keys("hello")
# 根据class定位
driver.find_element_by_class_name("kw").send_keys("hello")
# 根据链接文本内容定位,完全匹配
driver.find_element_by_link_text("kw").send_keys("hello")
# 根据链接文本内容定位,模糊匹配
driver.find_element_by_partial_link_text("kw").send_keys("hello")
# 根据标签名定位
driver.find_element_by_tag_name("kw").send_keys("hello")
# 根据xpath定位
driver.find_element_by_xpath("kw").send_keys("hello")
# 根据css定位
driver.find_element_by_css_selector("kw").send_keys("hello")

三、xpath 、 css适用定位

 3.1、xpath定位

# 1.层级和属性结合定位
driver.find_element_by_xpath("//form[@id='login']/ul/input[1]")

# 2.逻辑运算组合定位
driver.find_element_by_xpath("//input[@class='login' and @name='username']")

# 3.根据部分元素属性定位(模糊定位)
driver.find_element_by_xpath("//div[contains(@id, 'btn-attention')]")  # 包含指定内容即可
driver.find_element_by_xpath("//div[starts-with(@id, 'btn-attention')]")  # id以btn-attention
driver.find_element_by_xpath("//div[ends-with(@id, 'btn-attention')]")  # id以btn-attention')结尾

# 4. 通过子节点获取父节点
driver.find_element_by_xpath("//div[@id='C']/..).text  # .表示当前节点 , ..表示父节点

 3.2、css常用定位

  selenium 极力推荐使用css定位,而不是xpath来定位元素,原因是css定位比xpath定位速度快,语法也更加简洁

# css常用定位方法
# 1.css定位
find_element_by_css_selector()

# 2.根据id定位
#:id选择器,根据id属性来定位元素
# eg:driver.find_element_by_css_selector("#kw").send_keys("hello")


# 3.根据class定位
.:class选择器,根据class属性来定位元素
# eg:driver.find_element_by_css_selector(".login").send_keys("hello")


# 4.根据属性来定位
[attrbute='value']:根据属性来定位元素
# eg:driver.find_element_by_css_selector("[autocomplete='off']").send_keys("hello")

# 5.根据元素层级来定位
element>element:根据元素层级来定位 父元素>子元素
#eg:driver.find_element_by_css_selector("form#login>ul>input").send_keys("hello")  # login是form标签里面的id属性


# 6.多class属性定位(多个class之间直接用'.'符号连接)
#eg:driver.find_element_by_css_selector(".register.login").send_keys("hello") 

# 7.兄弟元素定位
+:定位当前节点之后的第一个兄弟节点
~:定位当前节点后面的所有兄弟节点,使用element定位默认取第一个,使用elements定位取到一组兄弟节点
#eg:
driver.find_element_by_css_selector('div#D + div').text
driver.find_element_by_css_selector('div#D ~ div').text

 四、下拉菜单列表选项定位

1、使用上述xpath、css等方法可以实现

2、使用Select实现

 导入:from selenium.webdriver.support.ui import Select

from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_css_selector("[name='selectinput']"))  # 定位到下拉菜单组件

select.select_by_index(2)  # 定位到index 第二个option元素
select.deselect_by_value(1)  # 定位到属性value=1的option元素
select.select_by_visible_text("保留七天")  # 根据内容直接定位指定option元素
select.all_selected_options  # 所有option元素

五、鼠标操作

  • 需要引入ActionChains类
  • 然后定位相关元素
  • 在ActionChains().调用相关鼠标操作方法
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver.find_element_by_css_selector("#kw").send_keys("Python")

# 获取搜索框元素对象
element=driver.find_element_by_css_selector("#kw")

#双击操作
ActionChains(driver).double_click(element).perform()

#右击操作
ActionChains(driver).context_click(element).perform()

#鼠标悬停
above=driver.find_element_by_css_selector(".pf")
ActionChains(driver).move_to_element(above).perform()
#ActionChains操作方法列表

click(on_element=None) ——单击鼠标左键

click_and_hold(on_element=None) ——点击鼠标左键,不松开

context_click(on_element=None) ——点击鼠标右键

double_click(on_element=None) ——双击鼠标左键

drag_and_drop(source, target) ——拖拽到某个元素然后松开

drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开

key_down(value, element=None) ——按下某个键盘上的键

key_up(value, element=None) ——松开某个键

move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标

move_to_element(to_element) ——鼠标移动到某个元素

move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置

perform() ——执行链中的所有动作

release(on_element=None) ——在某个元素位置松开鼠标左键

send_keys(*keys_to_send) ——发送某个键到当前焦点的元素

send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素

 六、键盘操作

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

#键盘全选操作 Ctrl+A
driver.find_element_by_css_selector("#kw").send_keys(Keys.CONTROL,'a')

#键盘选择复制或剪切操作 Ctrl+C
driver.find_element_by_css_selector("#kw").send_keys(Keys.CONTROL,'c')  # 复制
driver.find_element_by_css_selector("#kw").send_keys(Keys.CONTROL,'x')  # 剪切

#粘贴复制内容
driver.find_element_by_css_selector(".sec-input").send_keys(Keys.CONTROL,'v')

常用:

# 组合键操作
send_keys(Keys.CONTROL,'a')   #全选(Ctrl+A)

send_keys(Keys.CONTROL,'c')   #复制(Ctrl+C)

send_keys(Keys.CONTROL,'x')   #剪切(Ctrl+X)

send_keys(Keys.CONTROL,'v')   #粘贴(Ctrl+V)

# 非组合键操作
Keys.ENTER  # 回车键
Keys.BACK_SPACE  # 删除键
Keys.SPACE  # 空格键
Keys.TAB  # 制表键
Keys.ESCAPE   # 回退键
Keys.F5  # 刷新键

七、元素等待

  • 显示等待
  • 隐式等待

有时候我们打开网页定位到某个元素,判断该元素是否存在,而网页打开花费的时间我们并不确定,通过元素等待操作可以让我们忽略这些问题。

  • WebDriverWait 显示等待针对元素必用
  • expected_conditions 预期条件类(里面包含方法可以调用,用于显示等待)
  • NoSuchElementException 用于隐式等待抛出异常
  • implicitly_wait   隐式等待
  • By 用于元素定位
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait            #注意字母大写
from selenium.webdriver.support import expected_conditions as EC     
from selenium.common.exceptions import NoSuchElementException

显示等待:

# 案例:检测百度页面搜索按钮是否存在,输入关键词“自学网 Selenium” ,如果存在则点击搜索

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

from time import sleep

driver=webdriver.Firefox()

driver.get("http://www.baidu.com")


driver.find_element_by_css_selector("#kw").send_keys("自学网 Selenium")

sleep(2)

#显示等待--判断搜索按钮是否存在
element=WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,"su")))    # timeout:5秒,每0.5秒检测一次
element.click()
sleep(3)

driver.quit()

隐式智能等待:

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from time import sleep,ctime

driver=webdriver.Firefox()
driver.get("http://www.baidu.com")

sleep(2)

driver.implicitly_wait(5) #隐式等待时间设定 5秒,等待时间内检测成功则不再等待,比sleep实用

#检测搜索框是否存在
try:
    print(ctime())
    driver.find_element_by_css_selector("#kw").send_keys("Python")
    driver. find_element_by_css_selector("#su").click
except NoSuchElementException as msg:
    print(msg)
finally:
    print(ctime())

sleep(3)
driver.quit()

八、frame嵌套页面元素定位

 多层框架或窗口的定位:

  • switch_to_frame()     # frame定位
  • switch_to_window()  # window窗口定位

1、多层框架(frame)

1).定位frame的多种方式

from selenium import webdriver
driver = webdriver.Firefox()
driver.switch_to.frame(0)  # 1.用frame的index来定位,第一个是0
# driver.switch_to.frame("frame1")  # 2.用id来定位
# driver.switch_to.frame("myframe")  # 3.用name来定位
# driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))  # 4.用WebElement对象来定位

通常使用id或name就可以解决大多数frame定位问题,但当没有id 、name时,就要使用index、WebElement来定位了,,如下:

<iframe src="myframetest.html" />

使用xpath定位,传入WebElement对象:

driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(@src,'myframe')]"))

2)、从frame切回主文档:

 切到frame中之后,我们便不能继续操作主文档的元素,这时如果想操作主文档内容,则需切回主文档

driver.switch_to.default_content()

3)、嵌套frame的操作

 需要一层一层往下定位,不能跳着定位

driver.switch_to.frame("frame1")  # 先切到frame1(上级frame)
driver.switch_to.frame("frame2")  # 再切到frame2

4)、从子级frame切换到父级frame方法:

driver.switch_to.parent_frame()  # 相当于后退一层。如果当前已是主文档,则无效果

有了parent_frame()这个相当于后退的方法,我们可以随意切换不同的frame,随意的跳来跳去了。所以只要善用以下三个方法,遇到frame分分钟搞定

driver.switch_to.frame(reference)
driver.switch_to.parent_frame()
driver.switch_to.default_content()

demo:

# 案例:在Frame.html文件种定位搜狗搜索页面,进行搜索操作

from selenium import webdriver
from time import sleep

driver=webdriver.Firefox()
#设置网页文件路径,r代表路径转义
file_path=r'E:Python_scriptWebdriverFrame.html'
#路径转义另一种写法
# file_path='E:\Python_script\Webdriver\Frame.html'
driver.get(file_path)

#切换到frame页面内
driver.switch_to.frame("search")

#定位到搜索框按钮输入关键词
driver.find_element_by_css_selector("#query").send_keys("Python")
sleep(3)

driver.find_element_by_css_selector("#stb").click()

sleep(3)
driver.quit()
View Code

2、多窗口操作

 有些页面的链接打开后,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口了。获取窗口的唯一标识用句柄表示,所以只需要切换句柄,我们就能在多个页面上灵活自如的操作了

driver.current_window_handle  # 获取当前句柄

driver.window_handles   # 获取所有句柄

driver.switch_to.window()  # 切换句柄 ,一个参数:窗口句柄

多窗口切换的两种方式: 

方法一:

    1.循环判断是否与首页句柄相等

    2.如果不等,说明是新页面的句柄

    3.获取的新页面句柄后,可以切换到新打开的页面上

    4.打印新页面的title,看是否切换成功

方法二:

    1.直接获取all_h这个list数据里面第二个hand的值

# 方法一:判断句柄,不等于首页就切换
for i in all_h:      # all_h:所有窗口句柄        
    if i != h:
        driver.switch_to.window(i)
        print driver.title


# 方法二:获取list里面第二个直接切换
driver.switch_to.window(all_h[1])

九、警告弹窗处理

在Webdriver中处理JavaScript生成的alert、confirm、prompt,使用switch_to_alert()方法定位到alert、confirm、prompt,然后进行如下操作:

  • text:返回alert/confirm/prompt中的文字信息
  • accept():接受现有警告框
  • dismiss():解散现有警告框
  • sendkeys(keysToSend):发送文本至警告框,如果没有对话框输入,不能用,否则会报错

demo:

 点击百度首页设置按钮,然后进入搜索设置页面,点击“保存设置”或“恢复默认”按钮,处理警告弹窗窗口

from selenium import webdriver
from time import sleep
from selenium.webdriver.common.action_chains import ActionChains

driver=webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

# driver.find_element_by_link_text('设置').click()
# 鼠标悬停字“设置”链接
link = driver.find_element_by_link_text('设置')
ActionChains(driver).move_to_element(link).perform()

# 打开搜索设置
driver.find_element_by_link_text('搜索设置').click()

# 保存设置
driver.find_element_by_link_text('保存设置').click()
# driver.find_element_by_link_text('恢复默认').click()

# 打印警告框的文字信息
print(driver.switch_to_alert().text)

# 接受警告框
driver.switch_to_alert().accept()

driver.quit()

十、文件上传操作

1、文件上传

 文件上传中,上传按钮的种类,大体上可以分为两种,一种是input框,另外一种就比较复杂,通过js、flash等实现,标签非input

 1)input类型的上传按钮-上传文件

from selenium import webdriver

driver = webdriver.Firefox()
driver.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = driver.find_element_by_id('file')
upload.send_keys(r'd:aidu.py')  # 直接send_keys
print upload.get_attribute('value')  # check value

driver.quit()

 2)非input类型的上传操作

  大体上有以下几种解决方案:

  1. autoIT,借助外力,我们去调用其生成的au3或exe文件。
  2. Python pywin32库,识别对话框句柄,进而操作
  3. SendKeys
  4. keybd_event,跟3类似,不过是模拟按键,ctrl+a,ctrl+c, ctrl+v...

 本次只介绍第三种SendKeys方式

# 需安装:pip install SendKeys

from selenium import webdriver
import win32gui
import win32con
import time

dr = webdriver.Firefox()
dr.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = dr.find_element_by_id('file')
upload.click()
time.sleep(1)

# SendKeys
SendKeys.SendKeys('D:\baidu.py')  # 发送文件地址
SendKeys.SendKeys("{ENTER}") # 发送回车键

print upload.get_attribute('value')
dr.quit()

注:多文件上传就是在文件路径框里用引号括起单个路径,然后用逗号隔开多个路径,就是这么简单,例如:

"D:\a.txt","D:\b.txt"

十一、浏览器滚动条操作

from  selenium import webdriver
from time import sleep

driver=webdriver.Chrome()
driver.get("http://www.baidu.com/")
sleep(2)

#将滚动调拖到最底部
js="var action=document.documentElement.scrollTop=10000"
driver.execute_script(js)
sleep(2)

#将滚动条拖到最顶部
js="var action=document.documentElement.scrollTop=0"
driver.execute_script(js)
sleep(3)
# 鼠标下拉操作
target = driver.find_element_by_id("id_keypair")  #找到目标元素
driver.execute_script("arguments[0].scrollIntoView();", target) #拖动到可见的元素(页面转到指定目标元素位置)


# 鼠标下拉当前页面显示高度(数值)
browser.execute_script("window.scrollTo(0, document.body.scrollHeight); var lenOfPage=document.body.scrollHeight; return lenOfPage;")

十二、chromedriver不加载图片、phantomjs获取动态网页

1、Chromedriver不加载图片设置

# Chromedriver不加载图片
设置chromedriver不加载图片
chrome_opt = webdriver.ChromeOptions() # 实例化
prefs = {"profile.managed_default_content_settings.images":2}  # 设置不加载图片参数
chrome_opt.add_experimental_option("prefs", prefs)  # 添加进配置中
browser = webdriver.Chrome(executable_path="D:/Temp/chromedriver.exe",chrome_options = chrome_opt)  # 不加载图片使用

2、phantomjs获取动态页面

 需要下载phantomjs.exe,类似于Chromedriver之类

#phantomjs, 无界面的浏览器, 多进程情况下phantomjs性能会下降很严重

browser = webdriver.PhantomJS(executable_path="C:/phantomjs-2.1.1-windows/bin/phantomjs.exe")
browser.get("https://detail.tmall.com/item.htm?spm=a230r.1.14.3.yYBVG6&id=538286972599&cm_id=140105335569ed55e27b&abbucket=15&sku_properties=10004:709990523;5919063:6536025")
t_selector = Selector(text=browser.page_source)
print (t_selector.css(".tm-price::text").extract())
print (browser.page_source)
# browser.quit()

十三、网页自动截图

# 案例:分别打开我要自学网页面和百度页面,然后进行截图

from selenium import webdriver
from time import sleep

#加载浏览器驱动
driver=webdriver.Firefox()

#打开hao123页面并截图
driver.get("http://www.hao123.com")
driver.get_screenshot_as_file(r"E:Python_script51zxw.jpg")

#打开百度页面并截图
driver.get("http://www.baidu.com")
driver.get_screenshot_as_file(r"E:Python_scriptaidu.png")


sleep(2)
driver.quit()

十四、Cookie处理

from  selenium import webdriver
driver=webdriver.Chrome()
driver.get("http://www.baidu.com/")

#获取cookie全部内容
cookie=driver.get_cookies()
#打印全部cookile信息
print(cookie)
#打印cookie第一组信息
print(cookie[0])

#添加数据到网页cookie
driver.add_cookie({'name':'51zxw','value':'www.baidu.com'})
for cookie in driver.get_cookies():
    print("%s --- %s" %(cookie['name'],cookie['value']))

driver.quit()

demo:

# 案例:使用Cookie绕过百度验证码自动登录账户

from selenium import webdriver
from time import sleep

driver=webdriver.Firefox()
driver.get("http://www.baidu.com/")

#手动添加cookie
driver.add_cookie({'name':'BAIDUID','value':'9E4BF1D44014…(根据实际获取值填写)'})
driver.add_cookie({'name':'BDUSS','value':'根据实际抓包获取值填写'})

sleep(2)
driver.refresh()
sleep(3)
driver.quit()

 十五、知识点补充-By方式定位

导入:from selenium.webdriver.common.by import By

  • find_element(By.ID,"loginName")
  • find_element(By.NAME,"SubjectName")
  • find_element(By.CLASS_NAME,"u-btn-levred")
  • find_element(By.TAG_NAME,"input")
  • find_element(By.LINK_TEXT,"退出")
  • find_element(By.PARTIAL_LINK_TEXT,"退")
  • find_element(By.XPATH,".//*[@id='Title")
  • find_element(By.CSS_SELECTOR,"[type=submit]")

十六、设置ip代理

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://192.168.11.11:80")  # 设置ip代理
driver = webdriver.Chrome(executable_path = driver_path)
driver.get(url)
原文地址:https://www.cnblogs.com/Eric15/p/9884309.html