浏览器自动化:Selenium的使用

注意!本文中演示使用的编程语言为python,而浏览器为chrome。

一、Selenium简介

Selenium 是支持 web 浏览器自动化的一系列工具和库的综合项目。其本质是通过浏览器驱动程序,模拟浏览器的各种操作,比如跳转、输入、点击等,以便拿到完整的页面。而在爬虫中,它主要是为了解决requests库无法直接执行 JavaScript 代码的问题。

下面是一个最精简的使用案例(python代码):

from selenium import webdriver


driver = webdriver.Chrome()

driver.get("http://selenium.dev")

driver.quit()

二、入门指南

Selenium 通过使用 WebDriver 支持市场上所有主流浏览器的自动化。WebDriver是一个协议,并且定义了一个与语言无关的接口来控制web浏览器的行为。

每个浏览器都有一个特定的 WebDriver 实现,称为驱动程序。 驱动程序是负责委派给浏览器的组件,并处理与 Selenium 和浏览器之间的通信。

2.1 安装和使用驱动

2.1.1 安装

  1. 安装Selenium类库,根据使用的编程语言选择。
  2. 安装浏览器驱动,根据浏览器选择,注意版本。
  3. (可选)安装和配置Selenium Grid,如果需要进行测试的话。

2.1.2 用驱动的三种方式

  • 使用webdriver_manager

    from webdriver_manager.chrome import ChromeDriverManager
    
    service = Service(executable_path=ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service)
    
  • 将驱动程序添加到PATH 环境变量,以ubuntu为例:

    在终端中执行下列命令:

    echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
    source ~/.bash_profile
    
    # 测试,执行:chromedriver
    
  • 直接指出驱动程序的路径:

    service = Service(executable_path="/path/to/chromedriver")
    driver = webdriver.Chrome(service=service)
    

2.2 打开和关闭浏览器

通常,浏览器是用特定的选项启动的,这些选项描述了浏览器必须支持哪些功能,以及浏览器在会话期间应该如何运行。它们有些是通用的,有些是某些浏览器特有的。

我们接下来看看chrome浏览器使用默认选项的启动方法:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions

options = ChromeOptions()
driver = webdriver.Chrome(options=options)

driver.quit()

2.3 浏览器操作

  • 打开指定 URL:

    driver.get("http://www.google.com")
    
  • 按下浏览器的后退按钮:

    driver.back()
    
  • 按下浏览器的前进键:

    driver.forward()
    
  • 刷新当前页面:

    driver.refresh()
    
  • 执行 JavaScript 代码:

    driver.execute_script("js代码")
    
  • 添加cookie:

    driver.add_cookie({"name": "foo", "value": "bar"})
    
  • 保存当前窗口或标签页的id:

    保存id是为了方便切换窗口或标签页。

    original_window = driver.current_window_handle
    
  • 创建新窗口或新标签页并且切换:

    # 打开新标签页并切换到新标签页
    driver.switch_to.new_window('tab')
    
    # 打开一个新窗口并切换到新窗口
    driver.switch_to.new_window('window')
    
    # 切回到之前的标签页或窗口
    driver.switch_to.window(original_window)
    
  • 关闭窗口或标签页:

    # 关闭标签页或窗口
    driver.close()
    

2.4 获取浏览器信息

  • 获取当前页面的标题:

    driver.title  # 返回:"Google"
    
  • 从浏览器的地址栏读取当前的 URL:

    driver.current_url
    
  • 获取cookie:

    driver.get_cookie("foo")
    

2.5 代码与浏览器状态的同步

web平台本质上是异步的,所以WebDriver不跟踪DOM的实时活动状态。这就导致了一些问题,比如用户指示浏览器导航到一个页面,然后在试图查找元素时,由于异步加载等问题,可能会导致要找的元素没有加载出来,这就会导致一个 no such element 的错误。

2.5.1 显式等待

显示等待会使代码暂停程序执行或冻结线程,然后以一定的频率一直被调用,直到满足通过的条件或等待超时。

由于显式等待允许您等待条件的发生,所以它们非常适合在浏览器及其DOM和WebDriver脚本之间同步状态。

WebDriverWait(driver).until(python函数引用)

我们将函数引用作为条件传递, 显式等待将会重复运行直到其返回值为True。

比如,在找到<p>标签之前一直等待,直到找到为止:

el = WebDriverWait(driver).until(lambda d: d.find_element_by_tag_name("p"))
# find_element_by_tag_name方法表示按照标签名称查找元素

上面的代码中,因为等待将会吞没在没有找到元素时引发的 no such element 的错误,所以它会一直重试直到找到元素为止。然后它将获取一个 WebElement 的返回值,并将其传递回我们的脚本。

如果在规定时间内未得到条件为True的返回值,则等待将会抛出一个 timeout error 异常。

设置超时时间:

WebDriverWait(driver, timeout=3).until(……)

2.5.2 隐式等待

隐式等待是告诉WebDriver如果在查找一个或多个不是立即可用的元素时,继续在DOM中查找一段时间(也叫轮询)。默认设置为0,表示禁用。一旦设置好,隐式等待在真个浏览器会话周期内都会有效。

driver.implicitly_wait(10)  # 轮询10秒

警告!!!不要混合使用隐式和显式等待。这样做会导致不可预测的等待时间。例如,将隐式等待设置为10秒,将显式等待设置为15秒,可能会导致在20秒后发生超时。

2.6 查找元素

2.6.1 查找单个元素

在驱动程序实例上调用元素查找方法时,会返回对DOM中与所提供的参数值匹配的第一个元素的引用,这个值可以存储并用于将来的元素操作。

# 通过类属性的值查找
element = driver.find_element_by_class_name("类属性的值")

# 通过CSS选择器查找
element = driver.find_element_by_css_selector("#id属性的值 .类属性的值")

上面代码中,find_element_by_的后缀除了class_namecss_selector外,还有:

后缀描述
class_name通过类属性的值查找
css_selector通过CSS选择器查找
id通过ID属性的值查找
name通过 name 属性的值查找
link_text通过<a>标签的内部文本查找,文本内容需要完全匹配参数值
partial_link_text通过<a>标签的内部文本查找,文本内容只需部分匹配参数值
tag_name通过标签名称查找
xpath使用xpath查找

2.6.2 查找多个元素

find_elements方法(注意elements是复数形式)返回一个元素引用集合。如果没有匹配项,则返回空列表。

plants = driver.find_elements_by_tag_name("li")

该方法同样支持上面的多种后缀。

来自selenium官方文档的建议:

一般来说,**HTML 的 id 是在页面上定位元素的首选方法。**它们的工作速度非常快,可以避免复杂的 DOM 遍历带来的大量处理。

**如果没有唯一的 id,那么最好使用写得好的 CSS 选择器来查找元素。**XPath 和 CSS 选择器一样好用,但是它语法很复杂、很难调试并且运行速度很慢。

2.6.3 通过元素查找元素

元素对象也是支持定位器的。比如,查找<div>下的所有<p>

element = driver.find_element_by_tag_name('div')

elements = element.find_elements_by_tag_name('p')  # 注意,是通过element调用的find_elements_by_tag_name方法

2.7 操作元素

  • 鼠标左键单击元素:

    element.click()
    
  • 输入内容:

    该方法只适用于可以输入内容的表单等元素。

    element.send_keys("要输入的内容")
    
  • 重置元素:

    该方法只适用于可编辑和可重置的元素。比如,作用于<input>元素时,会清空输入的内容。

    element.clear()
    

2.8 获取元素内容

  • 获取元素属性值:

    element.get_attribute("属性名称")
    
  • 判断元素是否被“选择”:
    此方法确定元素是否被“选择”,用于复选框、单选按钮、输入元素和选项元素。已选择返回 True,否则返回 False

    element.is_selected()
    
  • 获取元素的标签名称:

    element.tag_name
    
  • 获取元素渲染后的文本:

    element.text
    
  • 获取元素的尺寸和坐标:

    element.rect
    

关于WbeDriver更加高级的用法,请参考官方文档:传送门

三、隐藏浏览器界面

在爬虫操作中,并不需要我们盯着看浏览器界面,所以一般会将其隐藏掉。Chrome浏览器提供了这一操作的支持。

from selenium.webdriver import Chrome, ChromeOptions

options = ChromeOptions()            # 创建Chrome参数对象
options.headless = True              # 把Chrome设置成可视化无界面模式,windows/Linux 皆可
driver = Chrome(options=options)     # 创建Chrome无界面对象
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花_城

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值