学习笔记 -- Python爬虫 - selenium


本文记录内容来自多位博主, 具体请参考以下链接:  

selenium总结1
selenium总结2
警告框
等待方式



selenium安装


1. 安装 selenium

打开 cmd : pip install selenium

2. 下载浏览器驱动

在这里提供三个常用的下载地址(更多的浏览器驱动请查看首行第二个链接):

  1. Chromedriver
  2. Firefoxdriver
  3. MicrosoftWebdriver

部分驱动可能会受浏览器的版本影响这里再提供一个 Google 浏览器的下载路径(我再下载时并没有碰到这个问题)

查看驱动和浏览器的映射关系

尽量把下载好的驱动放到一个显眼的位置, 再使用驱动时需要用到路径



selenium使用



基于浏览器驱动对象的方法和属性


实例化对象
  • Chrome()
from selenium.webdriver import Chrome

# 使用驱动时会返回一个浏览器对象, 此时运行程序会自动打开一个浏览器
driver = Chrome("E:\\driver\\chromedriver")

下列方法是由 Chrome 创建出来的对象直接调用的方法及属性


发出请求
  • get()

driver.get() <-- 打开指定的网址

from selenium.webdriver import Chrome

driver = Chrome("E:\\driver\\chromedriver")
url = "www.baidu.com"

driver.get(url) 

获取源码
  • page_source

driver.page_source <-- 返回页面的源码数据

from selenium.webdriver import Chrome

driver = Chrome("E:\\driver\\chromedriver")
url = "www.baidu.com"

driver.get(url) 
page_source = driver.page_source

断言

不管是在做功能测试还是自动化测试,最后一步需要拿实际结果与预期进行比较。这个比较称之为断言。

  • title 获取当前页面标题

driver.title <-- 返回当前页面的标题

  • current_url 获取当前页面 url

driver.current_url <-- 返回当前页面 url


标签定位

selenium 提供了8中方法来定位:

  1. find_element_by_id()

driver.find_element_by_id() <-- 输入 id 标签的值, 返回该标签对象

  1. find_element_by_name()

driver.find_element_by_name() <-- 输入 name 标签的值, 返回该标签对象

  1. find_element_by_class_name()

driver.find_element_by_class_name() <-- 输入 class 标签的值, 返回该标签对象

  1. find_element_by_tag_name()

driver.find_element_by_tag_name() <-- 输入标签名称, 返回该标签对象

  1. find_element_by_link_text()

driver.find_element_by_link_text() <-- 输入标签的文本内容, 返回该标签对象 (精准匹配)

  1. find_element_by_partial_link_text()

driver.find_element_by_partial_link_text() <-- 输入标签的文本内容, 返回该标签对象 (模糊匹配)

  1. find_element_by_xpath()

driver.find_element_by_xpath() <-- 输入 xpath 表达式, 返回该标签对象

  1. find_element_by_css_selector()

driver.find_element_by_css_selector() <-- 类选择器

参考网址: 类选择器

上述方法只能返回一个标签对象, 将方法的 element 改为 elements 即可返回一个列表的多个标签对象

from selenium.webdriver import Chrome

driver = Chrome("E:\\driver\\chromedriver")
url = "www.baidu.com"

# 使用get方法打开一个网页
driver.get(url) 
# 定位的方法会返回定位的标签对象
search_input = driver.find_element_by_id("kw")

设置窗口大小及刷新页面
  • 刷新页面: refresh()

driver.refresh() <-- 刷新当前浏览器页面

  • 设置窗口大小: set_window_size(x, y) x 为宽, y 为 高

driver.set_window_size(1920, 1080) <-- 将窗口大小设置为 1920*1080

  • 最大化浏览器: maximize_window()

driver.maximize_window() <-- 最大化当前浏览器

from selenium.webdriver import Chrome
import time

driver = Chrome("E:\\driver\\chromedriver")
driver.get("www.baidu.com")
driver.set_window_size(1920, 1080)
time.sleep(2)
driver.refresh()

无头浏览器

在执行 selenium 时, 不再弹出浏览器窗口显示执行界面

  1. 导入并创建一个 Options 对象

from selenium.webdriver.chrome.options import Options
options = Options()

  1. .add_argument("–headless")

options.add_argument("–headless")

  1. .add_argument(“disable–gpu”)

options.add_argument(“disable–gpu”)

from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--headless")
options.add_argument("--disable-gpu")

driver = Chrome(executable_path="E://driver//chromedriver", options=options)


规避检测

非人为的去访问网页时, 在 consola 中输入, window.navigator.webdriver 会显示 True, 证明这并不是一个人为的访问行为

  • chrome为例, 79版本以前的浏览器使用
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = Chrome(executable_path="E://driver//chromedriver", options=options)

  • 79版本之后, 修改此值不再生效, 这里搬一下其他博主的方法
from selenuim import webdriver
driver = webdriver.Chrome()
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
  "source": """
    Object.defineProperty(navigator, 'webdriver', {
      get: () => undefined
    })
  """
})

79版本之后的 chrome 使用上述方法, 虽然可以在consola中显示人为访问的行为, 但是我在使用时, 部分网页仍然拒绝访问

页面截屏
  • 对当前页面截屏: save_screenshot(filename)

driver.save_screenshot() <-- 接收一个参数, 为图片保存的地址

from selenium.webdriver import Chrome

driver = Chrome(executable_path="E://driver//chromedriver")
driver.get("https://www.baidu.com")
driver.save_screenshot("./图片.jpg")

执行 JS 代码
  • execute_script()

driver.execute_script() <-- 传入 js 代码并执行

from selenium.webdriver import Chrome

driver = Chrome("E:\\driver\\chromedriver")
driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")

前进后退
  • 前进 forward()

driver.forward() <-- 页面前进

  • 后退 back()

driver.back() <–页面后退

from selenium.webdriver import Chrome
import time

driver = Chrome("E:\\driver\\chromedriver")
# 打开百度首页
driver.get("www.baidu.com")
time.sleep(2)
# 打开百度翻译
driver.get("https://fanyi.baidu.com/")
time.sleep(2)
# 后退到首页
driver.back()
time.sleep(1)
# 前进回百度翻译
driver.forward()

页面窗口切换

当我们点击浏览器上的链接时, 会创建出新的页面, 进行窗口的切换需要获得页面的句柄

  • 获取当前页面句柄 : current_window_handle

driver.current_window_handle <-- 返回当前页面句柄

  • 返回所有窗口的句柄 : window_handles

driver.window_handles <-- 返回所有已打开的页面句柄

  • 切换到对应的窗口 : switch_to.window()

driver.switch_to.window() <-- 传入对应的窗口句柄

from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep

driver = Chrome("E:\\driver\\chromedriver.exe")
driver.get("https://www.baidu.com")
handle = driver.current_window_handle
print(handle)

button = WebDriverWait(driver, 20, 0.5).until(EC.visibility_of_element_located((By.XPATH, "//*[@id='s-hotsearch-wrapper']/div/a[1]/div")))
button.click()
sleep(5)

button1 = WebDriverWait(driver, 20, 0.5).until(EC.visibility_of_element_located((By.XPATH, "//*[@id='bottom_layer']/div[1]/p[4]/a")))
button1.click()
sleep(5)

all_handles = driver.window_handles
print(driver.window_handles)

for h in all_handles:
    driver.switch_to_window(h)
    sleep(3)


driver.quit()



基于元素的方法和属性



文本输入
  • 输入内容 send_keys()

search_input.send_keys() <-- 传入一个字符串对象

  • 传入本地文件 send_keys()

search_input.send_keys() <-- 传入文件的绝对路径

  • 清除文本 clear()

search_input.clear() <-- 清除该标签对象中的内容

from selenium.webdriver import Chrome

driver = Chrome("E:\\driver\\chromedriver")
url = "www.baidu.com"

# 使用get方法打开一个网页
driver.get(url) 
# 定位的方法会返回定位的标签对象
search_input = driver.find_element_by_id("kw")
# 向搜索框内输入内容
search_input.send_keys("飞机")
# 向搜索框传入文件
search_input.send_keys("E:\\xiaojichimi.txt")
# 清除文本
search_input.clear()

点击和回车
  • 点击 click()

button.click() <-- 点击 button 标签对象

  • 回车 submit()

search_input.submit() <-- 执行回车操作

from selenium.webdriver import Chrome

driver = Chrome("E:\\driver\\chromedriver")
url = "www.baidu.com"

# 使用get方法打开一个网页
driver.get(url) 
# 定位的方法会返回定位的标签对象
search_input = driver.find_element_by_id("kw")
# 向搜索框内输入内容(输入内容后可以直接使用回车)
search_input.send_keys("飞机")
search_input.submit()
# 定位到搜索按钮
button = driver.find_element_by_id("su")
button.click()


元素的常用属性及方法
  • 返回元素的尺寸: size

search_input.size <-- 返回该标签对象的尺寸(width, height)

  • 返回元素的坐标: location

search_input.location <-- 返回该标签对象的坐标(x, y)

  • 返回元素的文本信息: text

search_input.text <-- 返回该标签对象的文本信息

  • 返回元素的属性值: get_attribute()

search_input.get_attribute() <-- 传入一个标签的名称, 返回该标签的属性值

  • 返回元素的结果是否可见: is_displayed()

search_input.is_displayed() <-- 返回一个bool型值, 表示该标签是否可见

from selenium.webdriver import Chrome

driver = Chrome("E:\\driver\\chromedriver")
driver.get("www.baidu.com")
# 定位到搜索框
search_input = driver.find_element_by_id("kw")
# 返回搜索框的尺寸
print(search_input.size) # print(search_input.size["width"])  print(search_input.size["height"])
# 返回搜索框的左边
print(search_input.location) # print(search_input.location["x"])  print(search_input.location["y"])
# 返回搜索框的文本信息
print(search_input.text)
# 返回搜索框中的属性值
print(search_input.get_attribute("type")) 指定想要获取的属性
# 返回元素的结果是否可见
print(search_input.is_displayed()) # 返回bool类型的值


动作链

模拟在浏览器中的一系列动作(连续性 动作)

  • 动作链: ActionChains() <–传入浏览器驱动创建出来的对象
    使用 ActionChains(驱动对象) 类创建对象, 使用对象调用下列方法

from selenium.webdriver import ActionChains
mouse = ActionChains() <-- 返回一个动作链对象

  • 点击长按: click_and_hold() <–接收的参数是一个标签的定位

    mouse.click_and_hold() <-- 传入一个对象, 表示长按此对象

  • 移动偏移: move_by_offset(x, y) <–X轴移动量, Y轴移动量

    mouse.move_by_offset(100, 0) <-- 传入两个参数, 表示将当前定位的对象向右偏移 100 个像素

  • 右击: context_click()

    mouse.context_click() <-- 右击传入的对象, 默认为当前定位的对象

  • 双击: double_click()

    mouse.double_click() <-- 双击传入的对象, 默认为当前定位的对象

  • 指定区域内点击: move_to_element_with_offset(to_element, x, y)

    mouse.move_to_element_with_offset() <-- 传入一个对象(to_element), 两个参数(x, y) 在对象内偏移量并点击

  • 拖动: drag_and_drop() <–将一个元素拖动到另一个元素的位置

    mouse.drag_and_drop() <-- 接收两个参数对象, 将第一个对象拖到第二个对象的位置

  • 鼠标悬停: move_to_element() <–将光标移动动指定标签的位置

    mouse.move_to_element() <-- 接收一个参数对象, 将光标移动到该对象的位置

  • 释放动作: release()

    mouse.release() <-- 释放当前的动作

  • 立即执行动作: perform()

    perform() <-- 配合执行动作使用, 表示执行当前的动作
    例: mouse.move_to_element().perform()

from selenium.webdriver import Chrome
import time
# 导入动作链对应的类
from selenium.webdriver import ActionChains

driver = Chrome("E:\\driver\\chromedriver")
driver.get("https://detail.1688.com/offer/524426612853.html")
slider = driver.find_element_by_id("nc_1_n1z")
# 实例化一个动作链对象
action = ActionChains(driver)
# 点击长按指定的标签
action.click_and_hold(slider)
# 滑动标签
for i in range(1, 5):
	# 横向滑动25个像素, 并立即执行
	action.move_by_offset(25,0).perform()
	time.sleep(0.3)
# 指定区域内点击
Ve_code = driver.find_element_by_id("") # 指定元素
x = width # 指定宽度
y = height # 指定高度
mouse.move_to_element_with_offset(Ve_code, x, y).click().perform()

# 释放动作
action.release()


键盘动作

Keys()类提供了键盘上几乎所有按键的方法。 前面了解到, send_keys()方法可以用来模拟键盘输入, 除此 之外, 我们还可以用它来输入键盘上的按键, 甚至是组合键, 如 Ctrl+A、 Ctrl+C 等。

from selenium.webdriver.common.keys import Keys <-- 导入 Keys 类

  • send_keys(Keys.BACK_SPACE) 退格键

search_input.send_keys(Keys.BACK_SPACE) <-- 删除前一个内容

  • send_keys(Keys.SPACE) 空格键

search_input.send_keys(Keys.SPACE) <-- 输入空格

  • send_keys(Keys.TAB) 制表键

search_input.send_keys(Keys.TAB) <-- 制表符

  • send_keys(Keys.ESCAPE) 回退键

search_input.send_keys(Keys.ESCAPE) <-- 键盘上的 Esc

  • send_keys(Keys.ENTER) 回车键

search_input.send_keys(Keys.ENTER) <-- 回车键

  • send_keys(Keys.CONTROL,‘a’) 全选

search_input.send_keys(Keys.CONTROL, “a”) <-- ctrl+a 全选

  • send_keys(Keys.CONTROL,‘c’) 复制

search_input.send_keys(Keys.CONTROL, “c”) <-- ctrl+c 复制

  • send_keys(Keys.CONTROL,‘x’) 剪切

search_input.send_keys(Keys.CONTROL, “x”) <-- ctrl+x 复制

  • send_keys(Keys.CONTROL,‘v’) 粘贴

search_input.send_keys(Keys.CONTROL, “v”) <-- ctrl+v 粘贴

  • send_keys(Keys.F1) 键盘 F1-F12(方法类似)

search_input.send_keys(Keys.F1) <-- 键盘 F1


iframe


在原有的框架中创建包含另外一个文档的内联框架


如果定位的标签存在于 iframe 标签中, 则不能直接定位到该标签, 需要切换浏览器标签定位的作用域
  • 切换iframe: switch_to_frame()

driver.switch_to_frame() <-- 切换工作域, 默认支持接收 id 和 name 的属性值

  • 释放iframe: switch_to_default_content()

driver.switch_to_default_content() <-- 释放当前的工作域

iframe的切换是默认支持 id 和 name的, 如果两个属性值都为空可以先定位到iframe的标签, 在将返回结果作为参数传入

from selenium.webdriver import Chrome

driver = Chrome("E:\\driver\\chromedriver")
driver.get("www.baidu.com") # 这里没有找到合适的网页, 所以临时用百度充当一下
# 切换作用域
driver.switch_to_frame("kw")
# 定位iframe标签切换
frame = driver.find_element_by_tag_name("iframe")
driver.switch_to_frame(frame)
# 释放iframe
driver.switch_to_default_content()


等待方式


加入等待时间,主要是考虑到网页加载需要时间,可能由于网速慢,或者使用了 ajax 技术实现了异步加载等,如果程序找不到指定的页面元素,就会导致报错发生。


强制等待 : time.sleep()

使用 Python 自身的库 time.sleep() 可以实现强制等待。

强制等待使用简单,但是,当网络条件良好的时候,建议减少使用,因为如果频繁使用强制等待的方式等待元素加载,会导致整个项目的自动化时间延长。

这种等待方式的使用场景主要是脚本调试。

time.sleep() <-- 指定程序休眠的时间



隐式等待 : implicitly_wait()

隐式等待实际上是,设置了一个最长的等待时间,如果在规定时间内网页加载完成, 则直接执行下一步, 如果到达设定的时间, 则抛出异常

driver.implicitly_wait() <-- 指定隐式等待时间

隐式等待设置一次,对整个 driver 周期都能够起作用,所以,在最开始设置一次即可。

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) 设置隐式等待时间 10


显性等待 : WebDriverWait()

显性等待, WebDriverWait, 配合该类的until()和until_not()方法, 根据判断条件进行等待, 在规定时间内, 直到某个条件符合或不符合才会继续执行, 超出时间则抛出异常

具体参数和理论请参照 : https://blog.csdn.net/fenqi1989/article/details/107827793?

from selenium.webdriver import Chrome
# 导入模块 By, WebDriverWait, expocted_condtions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep

driver = Chrome("E:\\driver\\chromedriver.exe")
driver.get("https://www.baidu.com")
button = WebDriverWait(driver, 20, 0.5).until(EC.visibility_of_element_located((By.XPATH, "//*[@id='s-hotsearch-wrapper']/div/a[1]/div")))
button.click()

sleep(3)
driver.quit()
WebDriverWait(driver, 20, 0.5).until(
	EC.visibility_of_element_located(
	(By.XPATH, "//*[@id='s-hotsearch-wrapper']/div/a[1]/div")
	)
	)
	
直到 XPATH 定位的元素出现在页面且可以被定位才会继续向下执行

当我们在程序只使用一个显性等待时, 那么网页的加载就会停留在我们要定位的元素上, 之后的内容不会加载出来, 这时如果程序中有需要的内容未被加载则会报错, 此时需要显性等待和隐形等待一起使用, 但要注意的是: 最长的等待时间取决于两者之间的大者, 如果隐性等待时间>显性等待时间, 则该句代码的最长等待时间等于隐性等待时间




警告框

在WebDriver中处理JavaScript所生成的alert、confirm以及prompt十分简单,具体做法是使用 switch_to.alert 方法定位到 alert/confirm/prompt,然后使用text/accept/dismiss/ send_keys等方法进行操作。

消息框类型
  • alert 警告消息框

    警告消息框提供了一个"确定"按钮让用户关闭该消息框
    并且该消息框是模式对话框
    也就是说用户必须先关闭该消息框然后才能继续进行操作。
    
  • confirm 确认消息框

    确认消息框向用户提示一个"是与否"问题
    用户可以根据选择"确定"按钮和"取消"按钮。
    
  • prompt 提示消息对话

    提示消息框提供了一个文本字段
    用户可以在此字段输入一个答案来响应您的提示
    该消息框有一个"确定"按钮和一个"取消"按钮
    选择"确认"会响应对应的提示信息,选择"取消"会关闭对话框。
    

接收消息框方法及属性

selenium 中提供了 switch_to_alert() 用来接收消息框

driver.switch_to_alert() <–接收网页的消息框, 并返回一个消息框对象

  • text 返回消息框中的文字信息

    driver.switch_to_alert().text <-- 返回消息框中的文本内容

  • accept() 接受现有警告框, 即点击确认

    driver.switch_to_alert().accept() <-- 点击消息框的确认按钮

  • dismiss() 解散现有警告框, 即点击取消

    driver.switch_to_alert().dismiss() <-- 点击消息框中的取消按钮

  • send_keys() 发送文本至警告框

    driver.switch_to_alert().send_keys() <-- 传入内容到文本框中

具体详细内容及理论知识请参照:https://blog.csdn.net/w68688686/article/details/103989052


cookie操作


  • get_cookies() 获得所有的cookie信息

driver.get_cookies() <–以列表的形式 返回所有的cookie信息

  • get_cookie(name) 返回key为"name"的cookie信息

driver.get_cookie(“name”) <–返回key值为name的信息

  • add_cookie() 添加cookie

driver.add_cookie() <–添加cookie, 传入的参数是一个字典对象, 必须有name和value值

  • delete_cookie() 删除cookie

driver.delete_cookie(name, optionsString) <–删除cookie信息, name是要删除的cookie的名称,
“optionsString”是该cookie的选项,目前支持的选项包括“路径”,“域”。

  • delete_all_cookies() 删除所有cookie信息

driver.delete_all_cookies() <–删除所有cookie的信息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值