热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Python爬虫学习笔记13】使用Selenium模拟浏览器行为

在上一篇笔记《Ajax数据爬取简介》中我们提到,在爬取动态渲染页面的数据时(通常为Ajax),我们可以使用AJAXURL分析法和Selenium模拟浏览器行为两种方法,其中前者已经

在上一篇笔记《Ajax数据爬取简介》中我们提到,在爬取动态渲染页面的数据时(通常为Ajax),我们可以使用AJAX URL分析法和Selenium模拟浏览器行为两种方法,其中前者已经分析一般思维已叙述,在本节中我们主要介绍如何使用Selenium模拟浏览器行为来获取数据。

一、准备工作

在正式介绍使用之前,我们需要先安装selenium库,安装库的过程和之前一样,我们可以直接使用命令’pip install selenium’。安装完成后我们还需要配置好用于驱动浏览器行为的驱动器driver,每一个浏览器对应的driver都是不同的,具体可以参看下表:

Browser Download URL
Chrome https://sites.google.com/a/chromium.org/chromedriver/downloads
Edge https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Firefox https://github.com/mozilla/geckodriver/releases
Safari https://webkit.org/blog/6900/webdriver-support-in-safari-10/

下载完对应版本的XXXdriver.exe文件后,将其放入我们python安装路径的scripts目录下即可,以供全局使用。例如,以Chrome为例,我的chromedriver.exe便可放在’C:\Users\UnikFox\AppData\Local\Programs\Python\Python36\Scripts’。

此外,这里要留意的是,每个浏览器版本的driver也是不同的,在下载页可以看到各driver所支持的浏览器版本。

二、基本使用

1.启动浏览器并访问页面

模拟浏览器的启动只需要实例化selenium的webdriver模块中相应的对象即可,然后通过这个对象的get(url)方法便可请求URL映射的页面,之后我们就可以通过访问这一个对象的属性来获取相应的页面数据信息。这里我们仍以Chrome为例,运行后我们便可发现其自动地打开了一个Chrome浏览器,并在顶部显示“Chrome正受到自动测试软件地字样”,说明我们使用selenium成功地打开了浏览器,同时我们还会发现也已经进入了我们所请求的页面。

## 模拟启动浏览器
# 导入webdriver模块
from selenium import webdriver

# 实例化webdriver对象
browser = webdriver.Chrome()

# 请求页面
browser.get('https://www.baidu.com')

# 获取网页源代码
html_text = browser.page_source

【Python爬虫学习笔记13】使用Selenium模拟浏览器行为

2.关闭页面

在我们模拟完成后,可以使用browser对象的close()和quit()方法关闭页面,其主要区别是前者为关闭当前页面,而后者为退出整个浏览器。

# 关闭当前页面
browser.close()

# 退出整个浏览器
browser.quit()

3.解析元素

在我们获取到页面的HTML源文本后,如要对其进行解析,实际上我们可以使用之前介绍的lxml和beautifulsoup两种解析方法,不过这里我们主要来说明一下使用selenium的解析策略。

在selenium中,我们解析元素都是通过browser来实现的,解析的方法可以是通过元素id、元素名name、类名class_name、CSS选择器或者xpath语法,在实际中具体使用时我们只需要调用browser的相关方法即可。

例如,如果我们要解析百度中的输入框input元素,则可以使用如下的解析方法:

HTML源文本:

   

   

   

## 解析元素
from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.baidu.com')

# 通过id解析
inputTag = browser.find_element_by_id('kw')

# 通过name解析
inputTag = browser.find_element_by_name('wd')

# 通过class_name解析
inputTag = browser.find_element_by_class_name('s_ipt')

# 通过CSS选择器解析
inputTag = browser.find_element_by_css_selector('.quickdelete-wrap > input')

# 通过xpath解析
inputTag = browser.find_element_by_xpath('//input[@id="kw"]')

print(type(inputTag))
# Output: 

print(inputTag)
# Output: 

其实,在实际爬虫中我们更多的情况是需要解析多个元素,此时我们便可以通过’browser.find_elements_by_XXX()’来解析,和单个元素解析不同,其返回的是一个WebElement元素列表,即find_element是获取第一个满足条件的元素,而find_elements则是获取所有满足条件的元素。

此外,通过上述这种解析可能不够灵活,因为它都将解析方法都固定了,实际上selenium还为我们提供了一种可灵活选择解析方法的解析函数,这样上述示例便可等价为:

## 使用By来解析元素
from selenium import webdriver
# 导入By对象
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get('https://www.baidu.com')

# 通过id解析
inputTag = browser.find_element(By.ID,'su')

# 通过name解析
inputTag = browser.find_element(By.NAME,'wd')

# 通过class_name解析
inputTag = browser.find_element(By.CLASS_NAME,'s_ipt')

# 通过CSS选择器解析
inputTag = browser.find_element(By.CSS_SELECTOR,'.quickdelete-wrap > input')

# 通过xpath解析
inputTag = browser.find_element(By.XPATH,'//input[@id="kw"]')

4.提取元素信息

在我们获取到元素后,就要对元素的内容进行提取,提取对象包括元素的文本信息和元素的属性信息,分别对应着text属性和get_attribute(),使用示例如下:

HTML源文本:

©2018 Baidu 使用百度前必读 意见反馈 京ICP证030173号  京公网安备11000002000001号 

 

copyright = browser.find_element_by_id('cp')
print(copyright.text)       #©2018 Baidu 使用百度前必读 意见反馈 京ICP证030173号  京公网安备11000002000001号
print(inputTag.get_attribute('id'))       #cp

5.操作元素

元素的操作主要是点击和输入,在selenium中实现方式也很简便,只需要对相应待操作元素使用click()和send_keys()方法即可,使用示例如下:

#使用send_keys和click方法模拟输入和点击

inputTag = browser.find_element_by_id('kw')
inputTag.send_keys('python')

inputTag.click()

此外,在输入中若要清除已输入的内容,则可以使用clear()方法。对于任何与点击操作有关的行为都可以用这种方法实现,比如说单选和复选,前提只需要获取相应的元素就行了。

除了表单和单复选外,处理较多的还有下拉选择,因下拉点击后还需要选中元素,我们不能直接进行操作。不过我们可以借助selenium的一个类selenium.webdriver.support.ui.Select来实现,先将下拉选择元素作为参数传入这个类中实例化对象,然后我们就可以使用这个对象进行选择了。使用示例如下:

## 模拟下拉选择操作
from selenium import webdriver
# 导入selenium提供的下拉选择类
from selenium.webdriver.support.ui import Select

# <此处省略部分代码>

# 选中下拉标签并实例化Select对象
selectTag = Select(driver.find_element_by_name("FoodMenu"))

# 三种选择方式
# 根据序列索引选择(从0开始)
selectTag.select_by_index(1)
# 根据属性值value选择
selectTag.select_by_value("Fish")
# 根据可视文本选择
selectTag.select_by_visible_text("")

# 取消选中所有选项
selectTag.deselect_all()

三、其他使用

1.行为链

首先,什么是行为链呢?在上述的示例中,我们都是通过对单个元素执行单步操作完成的,其实还存有另一些操作,它们没有特定的执行对象,比如鼠标拖拽、键盘按键等,这些动作是用另一种方式来执行的,常分为多步,这就是行为链,又称为动作链。

由于行为链在爬虫中运用得不多,在此以将鼠标移动到某个元素上并执行点击事件为示例简单介绍一下:

## 使用行为链示例
from selenium import webdriver
# 导入行为链模块
from selenium.webdriver import ActionChains

# <此处省略部分代码>

#获取操作对象元素
inputTag = browser.find_element_by_id('kw')
submitTag = browser.find_element_by_id('su')

# 实例化行为链,传入参数webdriver对象
actiOns= ActionChains(browser)

# 有序化定义行为链对象得执行步骤
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
actions.move_to_element(submitTag)
actions.click(submitTag)

# 执行行为链
actions.perform()

此外,还有如下得常见鼠标操作得方法:

点击但不松开鼠标:click_and_hold(element)
右键点击:context_click(element)
双击:double_click(element)

2.COOKIE操作

使用Selenium我们可以很方便地对COOKIE进行获取、添加和删除操作,使用示例如下:

## COOKIE操作
from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.baidu.com')

# 获取所有COOKIE
print(browser.get_COOKIEs())
#[{'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '26523_1465_21094_27244_20930'}, ...,{'domain': '.baidu.com', 'expiry': 3686218697.591083, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1538735048'}]

# 获取指定名的COOKIE
print(browser.get_COOKIE('PSTM'))
#{'domain': '.baidu.com', 'expiry': 3686218697.591083, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1538735048'}

# 添加COOKIE
browser.add_COOKIE({'name':'name','domain':'www.baidu.com','value':'UnikFox'})
print(browser.get_COOKIEs())
#[{'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '26523_1465_21094_27244_20930'}...{'domain': 'www.baidu.com', 'expiry': 2169455052, 'httpOnly': False, 'name': 'name', 'path': '/', 'secure': True, 'value': 'UnikFox'}]

# 删除指定名的COOKIE
browser.delete_COOKIE('name')
print(browser.get_COOKIEs())
#[{'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '26523_1465_21094_27244_20930'}, ...,{'domain': '.baidu.com', 'expiry': 3686218697.591083, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1538735048'}]

# 删除所有COOKIE
browser.delete_all_COOKIEs()
print(browser.get_COOKIEs())
#[]

3.页面等待

由于很多时候我们无法预知页面元素需要花多长的时间进行加载,这时候我们就需要使用等待技术等待页面加载完成在进行解析。常用的等待方式分为显式等待和隐式等待。其中,显式等待即静态等待,无论是否加载完成都会等待,类似于time.sleep();而隐式等待则是条件等待,通常会设置一个条件,在等待的期间当条件满足时就会结束等待,若等待时间到了条件仍未满足就会抛出TimeoutException错误。

使用示例如下:

## 页面等待
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

browser = webdriver.Chrome()
browser.get('https://www.douban.com')

# 隐式等待
browser.implicitly_wait(10)
browser.find_element_by_id('123456')

# 显式等待加载
element= WebDriverWait(browser,10).until(
    # 调用判断条件检查元素是否已加载显示
    EC.presence_of_element_located((By.ID,'123456'))    #传入检索元组(方法,值)
)
print(element)

browser.quit()

一些其他的等待条件:

presence_of_element_located():某个元素已加载完毕
presence_of_all_emement_located():网页中所有满足条件的元素都已加载完毕
element_to_be_cliable():某个元素已可以点击

4.打开新标签页面与切换页面

如果有时候一个浏览器需要打开不同的标签页面(这里不是新打开一个浏览器),我们可以借助browser的execute_script("window.open(url)")方法来实现,不过要注意的是,虽然打开了一个新的标签页面,但并没有切换过去,browser访问的还是原来的页面,我们可以通过browser.current_url来查看当前页面URL。

对于拥有多个子标签的页面,如果我们想要切换不同的页面,可以借助selenium提供的switch_to_window()切换方法,该方法接收待切换页面的对象,具体可通过browser.window_handles列表索引得到,而这给列表里的元素是按照browser访问页面的先后顺序自动定的。

使用示例如下:

## 打开新标签页面和切换页面
from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.baidu.com')

#打开一个新的标签页面
browser.execute_script("window.open('https://www.douban.com')")

# 查看当前访问得页面
print(browser.current_url)    # https://www.baidu.com/

# 查看window_handles记录列表
print(browser.window_handles) # ['CDwindow-9F7F732D4DCD86446392EADF4D719F07', 'CDwindow-A61A3EE061BC15495FF17AB629309A0B']

#切换页面
browser.switch_to.window(browser.window_handles[1])
print(browser.current_url)    # https://www.douban.com/

5.使用代理

在Selenium中我们也可以进行代理设置,不同的浏览器设置代理得方式不同,这里我们以Chrome为例介绍设置代理得方法。

在Chrome中设置代理,首先需要获取设置对象webdriver.ChromeOptions(),再使用该对象得add_argument()方法对其添加代理参数,最后再实例化浏览器驱动对象webdrive.Chrome(),同时传入参数设置对象即可。

使用示例如下:

from selenium import webdriver

# 不使用代理
browser = webdriver.Chrome()
browser.get('http://httpbin.org/ip')
"""
{
  "origin": "36.157.132.78"
}
"""

# 使用代理
# 获取设置对象
optiOns= webdriver.ChromeOptions()
# 新增设置参数
options.add_argument("--proxy-server=http://134.175.68.57:80")
# 实例化浏览器并传入设置选择参数
browser = webdriver.Chrome(chrome_optiOns=options)
browser.get('http://httpbin.org/ip')
"""
{
  "origin": "134.175.68.57"
}
"""

 



推荐阅读
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 深入解析HTML5字符集属性:charset与defaultCharset
    本文将详细介绍HTML5中新增的字符集属性charset和defaultCharset,帮助开发者更好地理解和应用这些属性,以确保网页在不同环境下的正确显示。 ... [详细]
  • Python 3 Scrapy 框架执行流程详解
    本文详细介绍了如何在 Python 3 环境下安装和使用 Scrapy 框架,包括常用命令和执行流程。Scrapy 是一个强大的 Web 抓取框架,适用于数据挖掘、监控和自动化测试等多种场景。 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • Linux CentOS 7 安装PostgreSQL 9.5.17 (源码编译)
    近日需要将PostgreSQL数据库从Windows中迁移到Linux中,LinuxCentOS7安装PostgreSQL9.5.17安装过程特此记录。安装环境&#x ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 在机器学习领域,深入探讨了概率论与数理统计的基础知识,特别是这些理论在数据挖掘中的应用。文章重点分析了偏差(Bias)与方差(Variance)之间的平衡问题,强调了方差反映了不同训练模型之间的差异,例如在K折交叉验证中,不同模型之间的性能差异显著。此外,还讨论了如何通过优化模型选择和参数调整来有效控制这一平衡,以提高模型的泛化能力。 ... [详细]
  • Unity与MySQL连接过程中出现的新挑战及解决方案探析 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • SecureCRT是一款功能强大的终端仿真软件,支持SSH1和SSH2协议,适用于在Windows环境下高效连接和管理Linux服务器。该工具不仅提供了稳定的连接性能,还具备丰富的配置选项,能够满足不同用户的需求。通过SecureCRT,用户可以轻松实现对远程Linux系统的安全访问和操作。 ... [详细]
  • 在Conda环境中高效配置并安装PyTorch和TensorFlow GPU版的方法如下:首先,创建一个新的Conda环境以避免与基础环境发生冲突,例如使用 `conda create -n pytorch_gpu python=3.7` 命令。接着,激活该环境,确保所有依赖项都正确安装。此外,建议在安装过程中指定CUDA版本,以确保与GPU兼容性。通过这些步骤,可以确保PyTorch和TensorFlow GPU版的顺利安装和运行。 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
author-avatar
955单车小宏
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有