一、selenium 简介

随着网络技术的发展,目前大部分网站都采用动态加载技术,常见的有 JavaScript 动态渲染和 Ajax 动态加载

对于爬取这些网站,一般有两种思路:

  • 分析 Ajax 请求,通过模拟请求得到真实的数据,这种方法在之前的文章中已经多次使用,这里就不再赘述了
  • 使用 selenium 模拟浏览器进行动态渲染,从而获取网站返回的真实数据,以下我们将详细讲解这种方法

selenium 究竟是什么呢?简单来说,selenium 就是一个用于 Web 应用程序的测试工具

根据官方文档所说,selenium 最大的优点就是它可以直接运行在浏览器上,模拟用户的真实行为

但同时这也是它最大的缺点,由于需要模拟真实的渲染过程,所以导致它的运行速度变慢

其它详细的说明请参考 官方文档

二、selenium 使用

0、准备工作

  • 安装 selenium
pip install selenium
  • 安装驱动

在使用 selenium 的时候,必须有对应的浏览器驱动器文件在 Python 的安装目录下,否则会出现异常

Chrome 驱动器下载官网如下:https://sites.google.com/a/chromium.org/chromedriver/home

由于上面的官网需要翻墙才能访问,所以博主也在这里简单的给大家讲讲安装驱动的方法,具体的步骤如下:

  1. 打开 Chrome 浏览器,在地址栏中输入地址 chrome://settings/help,查看 Chrome 浏览器的版本信息

    例如 70.0.3538.67

  2. 将上面的信息去掉最后一部分后附加到 https://chromedriver.storage.googleapis.com/LATEST_RELEASE_

    例如 https://chromedriver.storage.googleapis.com/LATEST_RELEASE_70.0.3538

  3. 访问上面的链接,得到对应的驱动器版本信息

    例如 70.0.3538.97

  4. 将上面的信息附加到 https://chromedriver.storage.googleapis.com/index.html?path=,并在最后带上斜杠

    例如 https://chromedriver.storage.googleapis.com/index.html?path=70.0.3538.97/

  5. 访问上面的链接,选择合适平台(linux、mac、win)压缩包进行下载

  6. 等待下载完成后解压,将解压后的文件放到 Python 安装目录下即可

1、导入模块

>>> from selenium import webdriver

webdriver 就是我们上面所说的浏览器驱动器,它支持多种浏览器,下面以 Chrome 浏览器为例说明

2、开启浏览器

>>> browser = webdriver.Chrome()
>>> type(browser)
# <class 'selenium.webdriver.chrome.webdriver.WebDriver'>

3、访问页面

使用 WebDriver 对象的 get(url) 方法可以访问对应 URL 的页面

>>> browser.get('https://www.baidu.com')
>>> print(browser.current_url) # current_url 属性可以得到当前网页的 URL
# https://www.baidu.com/
>>> print(browser.page_source) # page_source 属性可以得到当前网页的源代码

4、查找元素

方法一

方法 描述
find_element_by_id(id) 通过 id 匹配
find_element_by_name(name) 通过 name 匹配
find_element_by_class_name(name) 通过 class_name 匹配
find_element_by_tag_name(name) 通过 tag_name 匹配
find_element_by_link_text(link_text) 通过 link_text 匹配
find_element_by_partical_link_text(link_text) 通过 partical_link_text 匹配
find_element_by_css_selector(css_selector) 通过 css_selector 匹配
find_element_by_xpath(xpath) 通过 xpath 匹配

以下尝试使用几种方法匹配输入框:

>>> search_bar = browser.find_element_by_id('kw')
>>> search_bar = browser.find_element_by_css_selector('#kw')
>>> search_bar = browser.find_element_by_xpath('//*[@id="kw"]')
>>> type(search_bar)
# <class 'selenium.webdriver.remote.webelement.WebElement'>

方法二

>>> from selenium.webdriver.common.by import By
>>> element = browser.find_element(by,value)
  • 参数 value 是与匹配方法对应的匹配表达式
  • 参数 by 指定匹配方法,其可选值列举如下(和方法一类似)
描述
By.ID 通过 id 匹配
By.NAME 通过 name 匹配
By.CLASS_NAME 通过 class_name 匹配
By.TAG_NAME 通过 tag_name 匹配
By.LINK_TEXT 通过 link_text 匹配
By.PARTIAL_LINK_TEXT 通过 partical_link_text 匹配
By.CSS_SELECTOR 通过 css_selector 匹配
By.XPATH 通过 xpath 匹配

以下尝试使用几种方法匹配确认按钮:

>>> from selenium.webdriver.common.by import By
>>> button = browser.find_element(By.ID,'su')
>>> button = browser.find_element(By.CSS_SELECTOR,'#su')
>>> button = browser.find_element(By.XPATH,'//*[@id="su"]')
>>> type(button)
# <class 'selenium.webdriver.remote.webelement.WebElement'>

注意

对于两种方法来说,若成功找到则返回 WebElement 对象,若没有找到则抛出 NoSuchElementException 异常

当需要查找多个元素时,只需要把方法中的 element 改成 elements 即可,此时返回的是匹配列表

5、元素交互操作

常见的元素交互操作列举如下:

  • 获取文本节点(可以使用 text 属性获取文本节点)
  • 获取元素属性值
>>> button.get_attribute('type')
# 'submit'
  • 写入输入框
>>> search_bar.send_keys('Selenium') # 向输入框输入内容
>>> search_bar.clear() # 清空输入框
>>> search_bar.send_keys('Selenium')
>>> from selenium.webdriver.common.keys import Keys
>>> search_bar.send_keys(Keys.ENTER) # 向输入框输入ENTER键
  • 点击提交按钮
>>> button.click() # 点击提交按钮,等价于上面的 search_bar.send_keys(Keys.ENTER)

6、执行交互动作

将动作附加在动作链中串行执行,常用的方法列举如下:

方法 描述
click(on_element=None) 鼠标左键点击元素
double_click(on_element=None) 鼠标左键双击元素
context_click(on_element=None) 鼠标右键点击元素
click_and_hold(on_element=None) 按下鼠标
release(on_element=None) 松开鼠标
move_to_element(to_element) 移动鼠标到指定元素中央
drag_and_drop(source, target) 拖拽元素
key_down(value, element=None) 按下键盘,一般只用在 Ctrl、Alt 和 Shift
key_up(value, element=None) 松开键盘
send_keys(keys_to_send) 发送键盘输入到当前聚焦元素
send_keys_to_element(element, keys_to_send) 发送键盘输入到指定元素
pause(seconds) 在指定的时间内暂停所有的输入
perform() 执行动作链的所有动作

以下示例为滚动到下一页按钮所在位置并点击下一页按钮翻页

>>> from selenium.webdriver.common.action_chains import ActionChains
>>> target = browser.find_element_by_class_name('n')
>>> ActionChains(browser).move_to_element(target).click(target).perform()

7、执行 JavaScript

JavaScript 能完成绝大部分的网页操作,由于内容庞杂,这里就不展开细说了

以下通过一个简单的例子来说明 JavaScript 的作用,其功能为拖动网页至底部:

>>> js = "window.scrollTo(0,document.body.scrollHeight)"
>>> browser.execute_script(js)

8、等待

规定等待的最长时间,若超过时间还未找到指定元素时,则抛出异常,先上代码感受一下:

>>> from selenium.webdriver.support.wait import WebDriverWait
>>> from selenium.webdriver.support import expected_conditions as EC
>>> wait = WebDriverWait(browser,10)
>>> try:
element = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'n')))
except:
browser.quit()

其它的 expected_conditions 方法列举如下:

属性 描述
title_is(title) 验证 title 是否等于 browser.title
title_contains(title) 验证 title 是否包含于 browser.title
presence_of_element_located(locator) 验证 locator 元素是否加载在 DOM 中
presence_of_all_elements_located(locator) 验证 locator 元素是否全部加载在 DOM 中
visibility_of_element_located(locator) 验证 locator 元素是否可见
invisibility_of_element_located(locator) 验证 locator 元素是否隐藏
text_to_be_present_in_element(locator,text) 验证 text 是否包含于 locator 元素的 text 中
text_to_be_present_in_element_value(locator,text) 验证 text 是否包含于 locator 元素的 value 中
frame_to_be_available_and_switch_to_it(locator) 验证 locator(frame) 元素是否可切入
element_to_be_clickable(locator) 验证 locator 元素是否可点击
element_located_to_be_selected(locator) 验证 locator 元素是否被选中

9、关闭浏览器

方法 描述
close() 关闭当前窗口
quit() 关闭所有关联窗口

一个简单的示例如下:

>>> browser.quit()

【参考资料】

【爬虫系列相关文章】

爬虫系列(十二) selenium的基本使用的更多相关文章

  1. 爬虫系列(十) 用requests和xpath爬取豆瓣电影

    这篇文章我们将使用 requests 和 xpath 爬取豆瓣电影 Top250,下面先贴上最终的效果图: 1.网页分析 (1)分析 URL 规律 我们首先使用 Chrome 浏览器打开 豆瓣电影 T ...

  2. 爬虫系列(十三) 用selenium爬取京东商品

    这篇文章,我们将通过 selenium 模拟用户使用浏览器的行为,爬取京东商品信息,还是先放上最终的效果图: 1.网页分析 (1)初步分析 原本博主打算写一个能够爬取所有商品信息的爬虫,可是在分析过程 ...

  3. Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】

    2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...

  4. SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据

    原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...

  5. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  6. struts2官方 中文教程 系列十二:控制标签

    介绍 struts2有一些控制语句的标签,本教程中我们将讨论如何使用 if 和iterator 标签.更多的控制标签可以参见 tags reference. 到此我们新建一个struts2 web 项 ...

  7. Alamofire源码解读系列(十二)之时间轴(Timeline)

    本篇带来Alamofire中关于Timeline的一些思路 前言 Timeline翻译后的意思是时间轴,可以表示一个事件从开始到结束的时间节点.时间轴的概念能够应用在很多地方,比如说微博的主页就是一个 ...

  8. 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  9. SpringBoot系列(十二)过滤器配置详解

    SpringBoot(十二)过滤器详解 往期精彩推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件 ...

随机推荐

  1. Javaproject集成log4J 1.x

    log4j是Java开发平台中的日志管理工具,是Apache基金会的一个开源项目.它的作用能够简单的理解为在开发过程中替代system.out的功能. 1.在project中集成log4j: (1)在 ...

  2. Java-CyclicBarrier的简单样例

    内容:一个主任务等待两个子任务,通过CyclicBarrier的await()实现.此Runnable任务在CyclicBarrier的数目达到后,全部其他线程被唤醒前被运行. public clas ...

  3. 回调函数实现类似QT中信号机制(最简单)

    1. 定义回调接口类: class UIcallBack{public: virtual void onAppActivated() = 0; virtual void onShowMore() = ...

  4. bin/sh^M:损坏的解释器: 没有那个文件或目录

    脚本文件保存时使用了DOS格式,用DOS2UNIX转为UNIX格式,也可以用vim打开,用:set ff=unix转换.不要在 Windows下编辑脚本文件,否则经常会遇到这种问题. 代码:sed - ...

  5. Android updater-scripts(Edify Script)各函数详细说明【转】

    本文转载自:http://blog.csdn.net/kwuwei/article/details/40616909 这是Android系统来运行updater-scripts的Edify语言的基本介 ...

  6. bzoj5085: 最大

    暴力是4方的,开始我只3方(扫描的时候更新当前最大) 二分+暴力可以做到m^2logMAX 二分答案,暴力枚举可行的两个位置形成一段,对于段,最多只会有m^2种情况. #include<cstd ...

  7. hdu 1754(单点更新 ,区间最大值)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  8. 0420-mysql命令(数据库操作层级,建表,对表的操作)

    注意事项: 符号必须为英文. 数据库操作层级: 建表大全: #新建表zuoye1:drop table if exists zuoye1;create table zuoye1(    id int ...

  9. 洛谷P3047 [USACO12FEB]Nearby Cows(树形dp)

    P3047 [USACO12FEB]附近的牛Nearby Cows 题目描述 Farmer John has noticed that his cows often move between near ...

  10. Django day17 博客项目(一)

    一: 博客项目需求分析 首页(显示文章) 文章详情 点赞, 点踩 文章评论 字评论 评论的展示 登录功能(图片验证码) 注册功能(基于form验证,ajax) 个人站点(不同人不同样式,文章过滤) 后 ...