Selenium 简介

百度百科介绍:

Selenium [1] 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。

使用流程

  1. 根据平台下载需要的webdrive
Browser Component
Chrome chromedriver(.exe)
Internet Explorer IEDriverServer.exe
Edge MicrosoftWebDriver.msi
Firefox geckodriver(.exe)
Safari safaridriver

根据自己的环境进行下载,将下载好的压缩包解压到项目的根目录不需要安装,各个浏览器的版本和dirver的版本的选择需要相近,不能盲目选择最新的版本,否则会出现意想不到的bug,建议最好将浏览器升级至最新的稳定版本并选择对应的包。

  1. 下载依赖包
npm install selenium-webdriver
  1. 玩一下官方demo, 做适当的代码修改并根据代码进行注释
// 1. 引入selenium-webdriver包,解构需要的对象和方法
const {Builder, By, Key, until} = require('selenium-webdriver');

// 2. 将需要的代码包在一个自执行函数中
(async function example() {
    // 实例化 driver 对象, chrome 代表使用的浏览器
  let driver = await new Builder().forBrowser('chrome').build();

  try {
    // 需要打开的网站地址
    await driver.get('https://www.baidu.com/');

    // Key.RETURN enter回车
    // By.id('id') 百度查询滴输入内容
    // 找到元素 向里面发送一个关键字并按回撤
        await driver.findElement(By.id('kw')).sendKeys('酒店', Key.RETURN);

        // 等1秒之后,验证是否搜索成功
    // await driver.wait(until.titleIs('酒店_百度搜索'), 1000);
  } finally {
    // 关闭浏览器
    // await driver.quit();
  }
})();

爬取掘金小册数据

  • 实现的功能

    • 自动打开掘金页面的首页
    • 自动点击小册前端进行路由切换
    • 将前端的全部小册数据爬取
  • 注意点
    • 由于selenium内部都是基于promise进行的封装,所有的方法调用其实返回的都是一个promise对象,因此会大量的使用async语法

自动打开掘金页面的首页

一句话搞定自动打开掘金首页

// 自动打开掘金
await driver.get('https://juejin.im/timeline');

自动点击进行路由跳转

  1. 在浏览器中,查看页面的布局结构,找到小册的位置,若是使用jq进行dom选择,则是 $('.main-header-box .nav-item:nth-of-type(4)')

  1. selenium中的By拥有很多的选择,其使用规则和jq非常相似,By.css('.main-header-box .nav-item:nth-of-type(4)')便可以找到对应的元素,调用click事件就可以模拟自动点击
// 点击小册子的navBar 切换路由到小册
await driver
.findElement(By.css('.main-header-box .nav-item:nth-of-type(4)'))
.click();
await driver.sleep(1000)
  1. 当点击小册之后,会调用 await driver.sleep(1000),因为当页面点击之后,页面会进行重新渲染,此时防止接下来的操作,获取不到数据或者获取的数据不是期望值,增加一个延迟确保数据的准确性

将前端的全部小册数据爬取

  1. 根据driver.findElements(By.css('.list-wrap .books-list .item'))获取前端小册列表,需要注意的是,当页面点击navBar之后,页面会进行重新渲染,但是此时若是直接去获取小测列表将会存在风险,因为在页面没有渲染完成之前获取不到期望值,而代码也会异常终止程序的运行
  2. 进行迭代取出希望获取的数据,根据itemInfo.findElement(By.css('.info .title')).getText()
while (true) {
  let listViewError = true;

  try {
    // 获取小册列表
    let _li = await driver.findElements(By.css('.list-wrap .books-list .item'));
    console.log(_li.length);

    for (let i = 0, _len = _li.length; i < _len; i++) {
      const itemInfo = _li[i];
      const title = await itemInfo.findElement(By.css('.info .title')).getText()
      const desc = await itemInfo.findElement(By.css('.info .desc')).getText()
      let price = await itemInfo.findElement(By.css('.info .price-text')).getText()

      _result.push({
        title,
        desc,
        price
      })
    }

    console.log('_result',_result);

  } catch (error) {
    if (error) listViewError = false;
  } finally {
    if (listViewError) break;
  }
}

在获取列表的时候,为什么会在最外层增加一个while呢?在 try catch 中的处理又是起到什么作用?

  1. while能确保会不断的获取数据,直到页面渲染完成获取到期望的数据
  2. try catch 可以保证程序在遇到异常时不会直接终止程序,可以继续运行
  3. listViewError表示程序是否存在异常情况,若是存在则会进入 catch 中,这个时候 listViewError 为 false,finally 则不会走break,会继续执行while程序,直到能获取到数据finally才为true,这个时候 finally中则会break 整个while的循环,跳出循环继续执行

总结

几十行的代码便可以将掘金的小册数据全部爬到,还是简单和好用的

全部代码

/*
 * @Author: nordon-wang
 * @Date: 2019-08-13 11:05:36
 * @Description: 爬取掘金数据
 * @Email: nordon-wang@oyohotels.cn
 */

const { Builder, By, Key, until } = require('selenium-webdriver');
let _result = []; // 用来收集获取的数据

(async function start() {
  let driver = await new Builder().forBrowser('chrome').build();

  try {
    // 自动打开掘金
    await driver.get('https://juejin.im/timeline');

    // 点击小册子的navBar 切换路由到小册
    await driver
      .findElement(By.css('.main-header-box .nav-item:nth-of-type(4)'))
      .click();
    await driver.sleep(1000)

    // 点击二级菜单
    await clickViewNav(driver);
    await driver.sleep(1000)

    // 获取数据
    await getList(driver);

  } catch (error) {
    console.log(error);
  } finally {
    let timer = setTimeout(async () => {
      clearTimeout(timer);
      await driver.quit();
    }, 600000);
  }
})();

// 获取渲染完成的按钮
async function clickViewNav(driver) {
  while (true) {
    let viewNavError = true;

    try {
      await driver
        .findElement(By.css('.main-container .view-nav .nav-item:nth-of-type(2)'))
        .click();
    } catch (error) {
      if (error) viewNavError = false;
    } finally {
      if (viewNavError) break;
    }
  }
}

// 获取列表数据
// 页面在渲染完成之前无法获取到页面的元素
async function getList(driver) {
  while (true) {
    let listViewError = true;

    try {
      // 获取小册列表
      let _li = await driver.findElements(By.css('.list-wrap .books-list .item'));
      console.log(_li.length);

      for (let i = 0, _len = _li.length; i < _len; i++) {
        const itemInfo = _li[i];
        const title = await itemInfo.findElement(By.css('.info .title')).getText()
        const desc = await itemInfo.findElement(By.css('.info .desc')).getText()
        let price = await itemInfo.findElement(By.css('.info .price-text')).getText()

        _result.push({
          title,
          desc,
          price
        })
      }

      console.log('_result',_result);

    } catch (error) {
      if (error) listViewError = false;
    } finally {
      if (listViewError) break;
    }
  }
}

使用selenium进行爬取掘金前端小册的数据的更多相关文章

  1. [python爬虫] Selenium定向爬取PubMed生物医学摘要信息

    本文主要是自己的在线代码笔记.在生物医学本体Ontology构建过程中,我使用Selenium定向爬取生物医学PubMed数据库的内容.        PubMed是一个免费的搜寻引擎,提供生物医学方 ...

  2. Python3.x:Selenium+PhantomJS爬取带Ajax、Js的网页

    Python3.x:Selenium+PhantomJS爬取带Ajax.Js的网页 前言 现在很多网站的都大量使用JavaScript,或者使用了Ajax技术.这样在网页加载完成后,url虽然不改变但 ...

  3. selenium+phantomjs爬取京东商品信息

    selenium+phantomjs爬取京东商品信息 今天自己实战写了个爬取京东商品信息,和上一篇的思路一样,附上链接:https://www.cnblogs.com/cany/p/10897618. ...

  4. selenium+phantomjs爬取bilibili

    selenium+phantomjs爬取bilibili 首先我们要下载phantomjs 你可以到 http://phantomjs.org/download.html 这里去下载 下载完之后解压到 ...

  5. python3 爬取汽车之家所有车型数据操作步骤(更新版)

    题记: 互联网上关于使用python3去爬取汽车之家的汽车数据(主要是汽车基本参数,配置参数,颜色参数,内饰参数)的教程已经非常多了,但大体的方案分两种: 1.解析出汽车之家某个车型的网页,然后正则表 ...

  6. python3 爬取boss直聘职业分类数据(未完成)

    import reimport urllib.request # 爬取boss直聘职业分类数据def subRule(fileName): result = re.findall(r'<p cl ...

  7. selenium + PhantomJS 爬取js页面

    from selenium import webdriver import time _url="http://xxxxxxxx.com" driver = webdriver.P ...

  8. phantomjs+selenium实现爬取动态网址

    之前使用 selenium + firefox驱动浏览器来实现爬取动态网址,但是firefox经常更新,更新后时常会导致webdriver启动不来,所以改用phantomjs+selenium来改善一 ...

  9. [python爬虫] Selenium定向爬取海量精美图片及搜索引擎杂谈

    我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的.首先通过这篇文章,你能学到以下几点:        1.可以了解Python简单爬取图片的一些思路和方法 ...

  10. [python爬虫] Selenium定向爬取虎扑篮球海量精美图片

    前言: 作为一名从小就看篮球的球迷,会经常逛虎扑篮球及湿乎乎等论坛,在论坛里面会存在很多精美图片,包括NBA球队.CBA明星.花边新闻.球鞋美女等等,如果一张张右键另存为的话真是手都点疼了.作为程序员 ...

随机推荐

  1. LineNumberReader类

    开发人员常常会随手写一些类来读入一个简单的配置文件,或者用BufferedReader一行一行地读入特定格式的数据.这些随手写成的解析器往 往会提供基本的出错报告,但有时候它们会很难记录下出错的行号. ...

  2. php 计算本月第一天 本月最后一天 下个月第一天

    本文转载自   http://jin541223.blog.163.com/blog/static/1637398052011111233018533/ //本周第一天(星期日为一周开始) echo ...

  3. 应聘.net开发工程师常见的面试题(二)(转载)

    1.公司要求开发一个继承System.Windows.Forms.ListView类的组件,要求达到以下的特殊功能:点击ListView各列列头时,能按照点击列的每行值进行重排视图中的所有行 (排序的 ...

  4. unix c 01

    gcc编译器(代码的 预处理/汇编/编译/连接) C程序员一般写程序会定义 .c和.h两种文件 .c文件(源文件)中一般放代码的实现,.h文件(头文件)中放 各种声明和定义.   gcc -E __. ...

  5. Java虚拟机结构

    一.JVM主要的结构如下: 二.各个区域功能介绍 1).方法区(Method Area):         (1)用于存储虚拟机加载的类信息.常量.静态变量等,是各个线程共享的内存区域:       ...

  6. c# 构造tree下拉框,空格转化

    c#代码写的空格如何在html中的select中展示出来呢? var str = ""; //父级菜单不缩进 ; j < i; j++) { str += HttpUtili ...

  7. jatoolsprinter web打印控件直接打印不弹出

    1.功能 主要是实现页面点击按钮,不弹窗,直接打印. 可以指定某个打印机打印 可以使用默认打印机打印 2.版本 主要有:免费版跟付费版 免费版官网:http://printfree.jatools.c ...

  8. 学以致用十九-----shell脚本之引号

    shell脚本中引号也是有讲究的. 可以分为单引号‘ ’,双引号“ ”和 反引号 ` ` 具体区别来看一个例子 输出结果 可得出结论 1. 单引号括起来的字符都作为普通字符出现,如第4,7,10,13 ...

  9. 洛谷 P2783 有机化学之神偶尔会做作弊 解题报告

    P2783 有机化学之神偶尔会做作弊 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. &quo ...

  10. LISTVIEW显示JPEG缩略图

    http://www.ctsys.cn/files/SHOW_FILES.ASPX?ID=22 许多的JPEG图片浏览器(如由我设计的<JPEG浏览缩放器>),都可以将JPEG缩略图放置到 ...