一、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. LINQ体验(2)——C# 3.0新语言特性和改进(上篇)

    整体来说.Visual Studio 2008和.NET 3.5是建立在.NET2.0核心的基础之上,.NET2.0核心本身将不再变化(假设不了解.NET2.0的朋友,请參看MSDN或者一些经典的书籍 ...

  2. vbs use

    VBScript中SendKeys的妙用 标签: vbscriptbasicmicrosoftinsertdeletestring 2011-05-26 15:29 1830人阅读 评论(0) 收藏  ...

  3. spring+springmvc+hibernate架构、maven分模块开发样例小项目案例

    maven分模块开发样例小项目案例 spring+springmvc+hibernate架构 以用户管理做測试,分dao,sevices,web层,分模块开发測试!因时间关系.仅仅測查询成功.其它的准 ...

  4. luogu3834 【模板】可持久化线段树1(主席树)

    关键字:线段树 可持久化 线段树:当版本(即对应的原序列的区间[1,r])一定时,每个节点的left,right下标为值域,值为其对应的原序列区间[1,r]中元素大小在值域中的元素个数. 可持久化:新 ...

  5. Android+Jquery Mobile学习系列(9)-总结和代码分享

    经过一个多月的边学习边练手,学会了Android基于Web开发的毛皮,其实开发过程中用Android原生API不是很多,更多的是HTML/Javascript/Css. 个人觉得基于WebView的J ...

  6. codeforces 899F Letters Removing set+树状数组

    F. Letters Removing time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. 78.员工个人信息保镖页面 Extjs 页面

    1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" ...

  8. 有关于dict(字典)的特性与操作方法

    有关于dict(字典)的特性与操作方法 1.字典的特性 语法: dic = {key1 : value1,key2 : value2,key3 : value3............} 注:字典中k ...

  9. Java.HttpClient绕过Https证书解决方案一

    方案1 import javax.net.ssl.*; import java.io.*; import java.net.URL; import java.security.KeyManagemen ...

  10. wap网测一道题目

    1. 给定一个字符串s, 1 <= len(s) <= 3000, 定义odd palindrome string为长度为奇数的回文串, 求s中该奇回文串的个数. 比如axbcba , 结 ...