热门标签 | 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"
}
"""

 



推荐阅读
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • macOS Big Sur全新设计大版本更新,10+个值得关注的新功能
    本文介绍了Apple发布的新一代操作系统macOS Big Sur,该系统采用全新的界面设计,包括图标、应用界面、程序坞和菜单栏等方面的变化。新系统还增加了通知中心、桌面小组件、强化的Safari浏览器以及隐私保护等多项功能。文章指出,macOS Big Sur的设计与iPadOS越来越接近,结合了去年iPadOS对鼠标的完善等功能。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文由编程笔记小编整理,主要介绍了使用Junit和黄瓜进行自动化测试中步骤缺失的问题。文章首先介绍了使用cucumber和Junit创建Runner类的代码,然后详细说明了黄瓜功能中的步骤和Steps类的实现。本文对于需要使用Junit和黄瓜进行自动化测试的开发者具有一定的参考价值。摘要长度:187字。 ... [详细]
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • 本文介绍了网页播放视频的三种实现方式,分别是使用html5的video标签、使用flash来播放以及使用object标签。其中,推荐使用html5的video标签来简单播放视频,但有些老的浏览器不支持html5。另外,还可以使用flash来播放视频,需要使用object标签。 ... [详细]
  • 本文整理了常用的CSS属性及用法,包括背景属性、边框属性、尺寸属性、可伸缩框属性、字体属性和文本属性等,方便开发者查阅和使用。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了markdown[软件代理设置]相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
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社区 版权所有