Selenium 是一个强大的网络数据采集工具,其最初是为网站自动化测试而开发的。近几年,它还被广泛用于获取精确的网站快照,因为它们可以直接运行在浏览器上。Selenium 可以让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。

Selenium 自己不带浏览器,它需要与第三方浏览器结合在一起使用。例如,如果你在 Firefox 上运行 Selenium,可以直接看到一个 Firefox 窗口被打开,进入网站,然后执行你在代码中设置的动作。虽然这样可以看得更清楚,但是我更喜欢让程序在后台运行,所以我用一个叫 PhantonJS 的工具代替真实的浏览器。

PhantomJS 是一个“无头”(headles)浏览器。它会把网站加载到内存并执行页面上的 JavaScript,但是它不会向用户展示网页的图形界面。把 Selenium 和 PhantomJS 结合在一起,就可以运行一个非常强大的网络爬虫了,可以处理 cookie、JavaScript、header、以及任何你需要做的事情。

你可以从 PyPI 网站 下载 Selenium 库,也可以用第三方管理器(像 pip)用命令行安装。

PhantomJS 也可以从它的官方网站下载。因为 PhantomJS 是一个功能完善(虽然无头)的浏览器,并非一个 Python 库,所以它不需要像 Python 的其他库一样安装,也不能用 pip 安装。

虽然有很多页面都用 Ajax 加载数据(尤其是Google),我们找到了一个页面全部是由 JavaScript 生成的,同时也是一个 PWA 应用,应用名称是 SMS America,来测试我们的爬虫。这个页面上一些电话号码,与短信内容,所有内容都是 JavaScript 生成的。如果我们传统的方法采集这个页面,只能获取加载前的页面,而我们真正需要的信息(Ajax 执行之后的页面)却抓不到。

Selenium 库是一个在 WebDriver 上调用的 API。 WebDriver 有点儿像可以加载网站的浏览器,但是它也可以像 BeautifulSoup 对象一样用来查找页面元素,与页面上的元素进行交互(发送文本、点击等),以及执行其他动作来运行网络爬虫。

下面的代码可以获取 Ajax “墙”后面的内容:

import os
from dotenv import load_dotenv
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import WebDriverExceptionfrom config import logger_configclass TestWebDriver(object):def __init__(self):load_dotenv()logger_name = 'Web Scraping to SMS America'self._logger_write_file = logger_config.LoggingConfig().init_logging(logger_name)self._chrome_path_file = os.getenv('CHROME_PATH')def get_asn_content(self, link):driver = webdriver.Chrome(executable_path=os.getenv('CHROME_PATH'))driver.get(link)try:WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.ID, "prefixes")))get_content = driver.find_element(By.TAG_NAME, "app-home").textexcept (WebDriverException, UnboundLocalError) as e:self._logger_write_file.error(f'处理 app-home 的时候出现错误,具体错误内容:{e},地址:{link}')return Falsefinally:driver.quit()return get_contentdef main(self):link = "https://america.storytrain.info/home"self.get_asn_content(link)if __name__ == '__main__':TestWebDriver().main()

上面代码使用 webDriver 和 Chrome 浏览器的方式,首先 Chrome 库创建了一个新的 Selenium WebDriver,首先用 WebDriver 加载页面,然后暂停执行 10 秒钟,再查看页面获取(希望已经加载完成的)内容。

依据你的 Chrome 安装位置,在创建新的 Chrome WebDriver 的时候,你需要在 Selenium 的 WebDriver 接入点指明 Chrome 可执行文件的路径:

driver = webdriver.Chrome(executable_path=os.getenv('CHROME_PATH'))

由于 Selenium 升级到 v4.0.0 以上使用上面代码会出现警告,所以我们重新修改代码为如下:

import os
from dotenv import load_dotenv
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import WebDriverException
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManagerfrom config import logger_configclass TestWebDriver(object):def __init__(self):load_dotenv()logger_name = 'Web Scraping to SMS America'self._logger_write_file = logger_config.LoggingConfig().init_logging(logger_name)self._chrome_path_file = os.getenv('CHROME_PATH')def get_asn_content(self, link):driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))driver.get(link)try:WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, "home-page-card-container")))get_content = driver.find_element(By.CLASS_NAME, "title-phone-number").textexcept (WebDriverException, UnboundLocalError) as e:self._logger_write_file.error(f'处理 app-home 的时候出现错误,具体错误内容:{e},地址:{link}')return Falsefinally:driver.quit()print(get_content)return get_contentdef main(self):link = "https://america.storytrain.info/home"self.get_asn_content(link)if __name__ == '__main__':TestWebDriver().main()

如果程序都配置正确,上面的程序会在几分钟之后显示下面的结果:

7743186342

虽然这个方法奏效了,但是效率还不够高,在处理规模较大的网站时还是可能会出问题。页面的加载时间是不确定的,具体依赖于服务器某一毫秒的负载情况,以及不断变化的网速。虽然这个页面加载可能只需要花两秒多的时间,但是我们设置了十秒的等待时间以确保页面完全加载成功。一种更加有效的方法是让 Selenium 不断地检查某个元素是否存在,以此确定页面是否已经完全加载,如果页面加载成功就执行后面的程序。

下面的程序用 class 是 home-page-card-container 的页面内容检查页面是不是已经完全加载:

WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, "home-page-card-container")))

程序里新导入了一些新的模块,最需要注意的就是 WebDriverwait 和 expected_conditions,这两个模块组合起来构成了Selenium 的隐式等待(implicit wait)。

隐式等待与显式等待的不同之处在于:隐式等待是等 DOM 中某个状态发生后再继续运行代码(没有明确的等待时间,但是有最大等待时限,只要在时限内就可以),而显式等待明确设置了等待时间。在隐式等待中,DOM 触发的状态是用 expected_conditions 定义的(这里导入后用了别名 EC,是经常使用的简称)。在 Selenium 库里面元素被触发的期望条件(expected condition)有很多种,包括:

  • 弹出一个提示框

  • 一个元素被选中(比如文本框)

  • 页面的标题改变了,或者某个文字显示在页面上或者某个元素里

  • 一个元素在 DOM 中变成可见的,或者一个元素从 DOM 中消失了

当然,大多数的期望条件在使用前都需要你先指定等待的目标元素。元素用定位器(locator)指定。注意,定位器与选择器是不一样的(请看前面关于选择器的介绍)。定位器是一种抽象的查询语言,用 By 对象表示,可以用于不同的场合,包括创建选择器。

在下面的示例代码中,一个选择器被用来查找 class 是 title-phone-number 的文本内容:

get_content = driver.find_element(By.CLASS_NAME, "title-phone-number").text

总结

这篇文章主要讲解了在 Python 中使用 Selenium 配合 Chrome 浏览器对 JavaScript 生成的内容进行获取,同时如何处理内容是否已经加载的相关问题,最后讲解了 Selenium 如何选择热面元素等相关内容。

通过上面的文章,我们应该能够处理一些由 JavaScript 生成的页面内容。

爬虫系列:在 Python 中用 Selenium 执行 Javascript相关推荐

  1. 在Python中用Selenium执行JavaScript

    Selenium自己不带浏览器, 需要与第三方浏览器结合在一起使用.例如在Firefox上运行Selenium. PhantomJS是一个"无头"浏览器. 它会把网站加载到内存并执 ...

  2. python网络爬虫系列教程——Python+PhantomJS +Selenium组合应用

    全栈工程师开发手册 (作者:栾鹏) python教程全解 Selenium 是什么?一句话,自动化测试工具.它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器. 理 ...

  3. python网络爬虫系列教程——python网络数据爬虫误区,让你的爬虫更像人类

    1 前言 近期,有些朋友问我一些关于如何应对反爬虫的问题.由于好多朋友都在问,因此决定写一篇此类的博客.把我知道的一些方法,分享给大家.博主属于小菜级别,玩爬虫也完全是处于兴趣爱好,如有不足之处,还望 ...

  4. Selenium 执行JavaScript语句

    Selenium 提供了两种执行 JavaScript 脚本的方法: execute_script:同步执行--常用 execute_async_script:异步执行 应用场景1:时间输入框 有些时 ...

  5. python网络爬虫系列(七)——selenium的介绍 selenium定位获取标签对象并提取数据 selenium的其它使用方法

    一.selenium的介绍 知识点: 了解 selenium的工作原理 了解 selenium以及chromedriver的安装 掌握 标签对象click点击以及send_keys输入 1. sele ...

  6. 【Python爬虫系列教程 40-100】selenium结合拖拽实现极验验证码破解

    文章目录 前言 1. 破解极验验证码思路 2. B站登录界面 3. 极验缺口图和原始图的截取 4. 对比缺陷图和原始图的像素,确定拖拽的像素 5. 拖拽轨迹 6. 执行以上所有代码,实现破解B站极验验 ...

  7. 【爬虫系列】Python 爬虫入门(2)

    接上篇,继续梳理 Python 爬虫入门的知识点.这里将重点说明,如何识别网站反爬虫机制及应对策略,使用 Selenium 模拟浏览器操作等内容,干货满满,一起学习和成长吧. 1.识别反爬虫机制及应对 ...

  8. Python调用并执行javascript代码——使用Naked库

    背景 在python环境下想要执行js文件一般主要是用execjs.js2py.selenium等第三方库来实现,最近在运行一段包含特殊字符的js代码时,把所有这些主流的js执行库都试了一遍,但无论如 ...

  9. python中用Selenium驱动Edge浏览器的方法

    当我们需要用到webdriver.Edge(),如果没有安装相应的驱动,就会运行错误,显示: 'edgedriver' executable needs to be in PATH. 这是我们需要来到 ...

最新文章

  1. 独家 | 最新NLP架构的直观解释:多任务学习– ERNIE 2.0(附链接)
  2. 6行Python实现验证码识别,太稳了!
  3. 前端性能优化:使用Data URI代替图片SRC
  4. android camera捕捉,通过android camera2 API捕捉4:3相机图片与16:9传感器阵列相机
  5. C++socket编程(五):5.1 创建tcpclient项目
  6. python 基础复习
  7. Matter-JS Composites 混合材料 · 上
  8. pku 2976 Dropping tests 01分数规划
  9. android auto 墙纸,AA壁纸(Android Auto车载系统壁纸)
  10. 倍福--控制步进电机
  11. win10中鼠标点右键或者重命名文件夹系统卡顿解决方法
  12. python语言turtle库画图代码示例_5分钟轻松搞定,Python开发之turtle库的基本操作...
  13. Java最佳学习途径
  14. 动态域名ddclient
  15. android极光推送sequence,极光推送接入
  16. iSCSI网络SCSI接口
  17. 高级前端工程师和低级前端工程师的区别
  18. python开发小程序拼团_微信小程序新功能,正合适开发拼团类小程序|明智科技...
  19. 2019年7月31日18:57:48
  20. OpenCV实践:去除票据中的红色印章

热门文章

  1. 新入口 新方案——中企动力机械行业解决方案
  2. STC51单片机学习笔记
  3. ssm+java计算机毕业设计齐市疫苗管理系统w80jw(程序+lw+源码+远程部署)
  4. 设备软件控制平台会是什么样子?
  5. python连接mt4_软件开发公司_软件外包_项目外包平台外汇交易软件MT4的Python接口程序的BUG修改...
  6. DEDECMS织梦内容管理系统安全设置(防范网站注入挂马)
  7. 报错:Gradle build failed.See the Console for details.(已解决)
  8. typecho模板ajax,【完善版】Typecho不使用插件实现Ajax评论功能
  9. google 地图 API 参考 .
  10. 在Win10系统中使用独立浏览器 Internet Explorer 11 的解决方案(原创)