大麦网抢票程序之Selenium的使用

简介: 大麦网抢票程序之Selenium的使用

大家好,我是石璞东。

我们在 大麦网抢票程序之大麦网网站分析 一文中详细描述了本次项目案例的需求,并对其做了深入的分析,在本篇文章中,我们来讲解一下实现该案例所涉及的一些具体的技术栈,请看文章。

在文章开始之前,我先从两个角度回答一个问题:

  • 为什么会选择使用selenium?

角度一: 我们知道,在爬虫的过程中,我们会经常遇到以下三种形式的网页:

 - 第一种是在请求相应的网址之后,在网速等外部原因满足的条件下,即可得到网页的完整源代码,即浏览器所查看到的源代码就是网页实际的源代码,这种网站包括有 [大麦网](https://www.damai.cn/)、[中国研究生招生信息网](https://yz.chsi.com.cn/) 等;

在这里插入图片描述

 - 第二种是那些通过 `Ajax` 渲染出来的页面,对于该种类型的网页,我们只需要直接去分析所请求的 `Ajax`,然后借助 `requests` 或者 `urllib` 即可实现数据的爬取,这种网站包括 [今日头条](https://www.toutiao.com/) 等;

在这里插入图片描述

 - 第三种是那些通过 `JavaScript` 计算生成的网页,这种网站包括 [百度的Echarts](https://echarts.apache.org/zh/index.html) 等。

在这里插入图片描述

**角度二:** 本系列文章中,我们是要通过自动化程序来抢德云社小园子的票,所以必须有用户亲自选择座位、票档等相关操作,这就解释了我们为什么没有使用 `Chrome` 的 `Headless` 模式或者 `PhantomJS`。接下来,请看正文内容。

网站流量的计算及区别介绍

  • 浏览量(page view):用户每次打开一个网站页面就被记录一次。用户多次打开同一页面,浏览量累计;
  • 访客数(user view): 一天之内网站的独立访客数(以cookie为依据),一天之内同一访客多次访问同一网站只计算为1个访客;
  • 访问次数:记录所有访客1天内访问了多少次我的网站,相同的访客有可能多次访问我的网站;
  • IP数:一天之内访问网站的独立IP;
  • 新访客数:一天的独立访客中,历史第一次访问网站的访客数;
  • 新访客比率:新访客数/访客数
  • 跳出率: 只浏览了一个页面便离开了网站的访问次数占总的访问次数的百分比;
  • 平均访问时长: 访客在一次访问中,平均打开网站的时长。即每次访问中,从打开第一个页面到关闭最后一个页面的平均时间;
  • 转化次数: 访客到达转化目标页面的次数

我们来考虑一个问题:假设中国的所有省份中每个省均只有一个接入互联网的网关,即只能通过该网关访问互联网资源,也就是说只有一个公网ip,假设这34个省每个省的所有用户每天都访问一次我的网站,请问24个小时之后,我网站的浏览量是所有用户的个数还是34,那独立ip的个数是多少呢?

首先,请看答案:网站的访问量是所有访问用户的总个数,独立IP是34,请看详细分析:

  • 网站浏览量计算的是用户打开网站页面的次数,跟用户所使用的IP没有关系,就算用户使用一个固定IP访问我的网站它的浏览量也会改变的;
  • 每个省分配一个公网IP,独立IP数为34, 在每个省的 局域网 环境下,又有很多的局域网IP,之所以这样分配是为了解决IPV4地址不够用的问题,这些局域网IP去访问互联网资源必须通过网关,即对外显示是通过该省的公网IP访问的,也就是说通过34个独立的IP实现了全国人的访问。

刷网站流量

小伙伴们在阅读本小节内容之前,最好有一些关于搜索引擎的基本概念,这里我给大家找出了我2019年年底考完研之后写的一篇文章 。

以我的个人网站为例,给各位小伙伴看下主流搜索引擎对我网站词条的排名情况:

  • Google

在这里插入图片描述

  • 百度

在这里插入图片描述

  • 搜狗

在这里插入图片描述

从关键词搜索的词条排名情况和词条数目也能反映出所用搜索引擎的某些优缺点,从爬虫速度来说: Google>搜狗>百度>360,搜狗应该算是爬虫速度频率比较高的了,百度对于我的网站的收录还有一些死链,360就不用说了,词条数和死链都是最少的。

网站流量的提高:

  • 访问网站用户数的增加(建立在优质的网站资源基础上);
  • 通过爬虫程序提高网站页面的权重;
  • 通过站长工具去做SEO(SEO的过程是比较漫长的,涉及到网站页面的代码格式、关键词、网站的运行时间、外链内链等等);
  • 花钱做竞价排名

selenium安装

工欲善其事,必先利其器,在完成我们的案例之前,我们先来安装一下相关的环境配置。

1. windows下安装selenium

首先,请确保你已经安装好了Python和Chrome浏览器,接着请查看你的Chrome版本:
在这里插入图片描述

然后,请根据如下网址中的 Chrome 浏览器版本与 Chromedriver 版本的对应信息去安装对应的 Chromedriver,请看网址:
http://chromedriver.storage.googleapis.com/index.html
在这里插入图片描述
在这里插入图片描述
下载完成之后,对其进行解压,并将其放在 Chrome 文件夹下:
在这里插入图片描述

完成 Chromedriver 的安装之后,我们来进行最后一步操作:通过 pip 包来安装 selenium

pip install selenium

完成上述所有操作之后,我们来看一个例子:通过自动化程序打开我的个人网站:

from selenium import webdriver
browser=webdriver.Chrome('C:\Program Files(x86)\Google\Chrome\Application\chromedriver.exe')
browser.get("https://www.shipudong.com")

「注」:我们可以通过配置环境变量直接使用 webdriver.Chrome() 来声明一个浏览器对象,也可以通过 webdriver.Chrome('C:\Program Files(x86)\Google\Chrome\Application\chromedriver.exe')直接来进行模拟。

2. mac下安装selenium

mac下的安装与windows下的安装步骤大概一致,这里不再赘述,我们来看一下需要注意的地方

大家完成mac下正确版本的 Chromedriver 下载之后,就可以将下载好的可执行文件移动到 /usr/local/bin 目录中,我们通过快捷键 Command + Shift + G 输入 /usr/local/bin 即可进入相应文件夹,接着我们将可执行文件拖入到该目录中;
在这里插入图片描述
完成上述操作之后,我们通过 terminal 进入到上述目录的终端页面,输入 chromedriver 查看相关信息:
在这里插入图片描述
在这里插入图片描述
安装完成 Chromedriver 之后,我们通过 pip 包来安装 selenium 即可,这里不再赘述。

我们来看一个演示案例,请看代码:

from selenium import webdriver
browser=webdriver.Chrome()
browser.get("https://www.shipudong.com")

在这里插入图片描述
非常好,安装成功!这里我们在来看两个案例:

  • 循环执行以下操作:间隔5s打开一次浏览器并访问指定的网站,5s之后又关闭网站
from selenium import webdriver
import time
def controlBrowser():
    driver = webdriver.Chrome()
    driver.maximize_window()
    time.sleep(5)
    print("5秒后我就要访问石璞东的网站咯")
    driver.get("https://www.shipudong.com")
    time.sleep(5)
    print("5秒后我就要关闭浏览器咯")
    print("============================");
    driver.close()
if __name__=="__main__":
    while 1:
        controlBrowser()
  • 循环执行以下操作:间隔一段时间点击一次刷新按钮
from selenium import webdriver
import time
def controlBrowser():
    driver = webdriver.Chrome()
    driver.get("https://www.shipudong.com")
    time.sleep(5)
    driver.refresh()
if __name__ == "__main__":
    while 1:
        controlBrowser()

selenium的使用

1. 声明浏览器对象并访问页面

Selenium可以支持非常多的浏览器,包括Chrome、Firefox、Edge等,本文仅以Chrome为例进行讲解,首先我们来初始化浏览器对象,请看代码:

from selenium import webdriver
browser = webdriver.Chrome()

我们通过上述代码完成了浏览器对象的初始化,并将其赋值给 browser 对象,接下来我们就可以通过调用 browser 对象来模拟浏览器的各种操作了,请看代码:

from selenium import webdriver
browser = webdriver.Chrome()
browser.get("https://www.shipudong.com")
print(browser.page_source)
browser.close()

我们通过 get() 方法访问了 我的个人网站,并在控制台输出网页源代码之后关闭了我们通过自动程序打开的浏览器选项卡。
在这里插入图片描述

2. 查找节点

我们知道,对于整个爬虫来说,我们要做的无非就是三件事:

    
 - 通过`requests`、`urllib`等库进行网页请求;
 - 通过`re`、`XPath`、`Beautiful Soup`、`pyquery`等库解析源代码;
 - 通过`txt`、`json`、`csv`、`SQL`等进行数据存储

因此,在使用 selenium 的过程中,当我们想要获取某些节点时,我们当然可以使用 XPathcss 选择器等进行获取,但是由于 selenium 已经为我们提供了一系列的方法,所以关于 XPathcss 选择器等的方法,这里就不再赘述。

请看官网地址:
https://selenium-python.readthedocs.io/locating-elements.html

请看代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
browser.get("https://www.baidu.com")
input = browser.find_element_by_id("kw")
input.send_keys("石璞东")
input.send_keys(Keys.ENTER)
wait = WebDriverWait(browser,1)
wait.until(EC.presence_of_element_located((By.ID,'content_left')))
print(browser.current_url)

上述代码中,我们首先通过 get() 方法访问百度首页,接着我们通过 find_element_by_id() 方法来获取到百度首页的输入框,并通过 send_keys() 方法输入关键词 石璞东,然后我们通过指定 send_keys() 方法的参数为 Keys.ENTER 来模拟点击 Enter 键实现 百度一下 的功能。

点击搜索按钮之后,我们通过 WebDriverWait 函数指定加载时间为1秒,如果在1秒内下图中 idcontent_leftdiv 中的内容可以被加载出来,程序则会继续往下执行,最后会在控制台打印当前的网址;如果没有加载出来,则会抛出超时错误,请看官网解释:
在这里插入图片描述在这里插入图片描述
请看控制台结果:
在这里插入图片描述

上述代码中关于 get() 方法等待加载的部分,这里不做过多讲解,请继续阅读本文。

更多关于查找节点的操作,这里不再进行一一赘述,官网中已经有足够详细的介绍和相关的例子,请读者自行学习了解,网址如下:
https://selenium-python.readthedocs.io/locating-elements.html
在这里插入图片描述

3. 节点交互

我们继续以百度为例,请看需求:

  • 在输入框中输入石璞东
  • 3秒之后,清空输入框;
  • 在输入框中重新输入 淘宝,并点击 百度一下 按钮提交所输入的搜索关键词

请看代码:

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get("https://www.baidu.com")
input = browser.find_element_by_id("kw")
input.send_keys("石璞东")
time.sleep(3)
input.clear()
input.send_keys("淘宝")
sub_keywords = browser.find_element_by_id("su")
sub_keywords.click()

上述代码中,我们都是对特定的节点进行交互操作的,不管是按钮还是输入框都有其特定的一些方法,那么对于那些没有特定执行对象的操作(像是鼠标拖拽等)我们该如何去处理呢?

我们再来看一个案例,该案例所用到的演示网址如下:
https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable
在这里插入图片描述
案例很简单,用户拖拽标有 请拖拽我! 字样的 div,当拖拽至标有 请放置到这里! 字样的 div 标签的一定范围内,会弹出 dropped 的提示框。

接下来我们通过 selenium 来完成上述通过用户进行拖拽的操作,请看代码:

from selenium import webdriver
from selenium.webdriver import ActionChains

browser = webdriver.Chrome()
browser.get("https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
browser.switch_to.frame("iframeResult")
source_div = browser.find_element_by_id("draggable")
target_div = browser.find_element_by_id("droppable")
actions = ActionChains(browser)
actions.drag_and_drop(source_div,target_div)
actions.perform()

在这里插入图片描述
在这里插入图片描述
仔细分析上述案例所用到的源代码,我们可以发现:整个页面的主要内容可以分为左右两部分,我们从源代码中可以获知其布局采用 栅格布局,关于布局的更多内容,请参考如下网址:
https://code.z01.com/v4/layout/grid.html

我们通过分析源代码可以知道,网页中拖拽操作的演示部分被嵌套在一个iframe 标签中,因此我们在对相关元素操作之前,首先要做的就是根据 id 把定位器切换到 iframe上,这就是上述代码中我们使用browser.switch_to.frame("iframeResult") 一行代码跳转至 iframe 的具体实现。
在这里插入图片描述
更多关于节点操作的内容,请大家继续深入官网进行学习,请看官网地址:
https://selenium-python.readthedocs.io/navigating.html

4. 延时等待

我们知道,get() 方法会在网页框架渲染完成之后终止执行,此时我们如果通过 page_source 属性来获取网页源代码,很有可能得到的源代码不是最终加载完成之后的代码,因为大部分页面都会有额外的 Ajax 请求,这里我们就需要通过等待一段时间来确保所有节点的完全加载。
一般来讲,等待加载的方式主要包括两种,隐式等待(Implicit Waits)和显式等待(Explicit Waits)

关于隐式等待,这里我们不做过多赘述,大家看官网即可。
在这里插入图片描述

在隐式等待中,我们只规定了一个固定时间,超过固定时间之后会进行后续的相关操作,然而网页的加载受到网络条件等的影响,所以如果出现超时之后并没有加载出来的情况,隐式等待的效果就显的不那么友好了。

接下来,我们来看一下显示等待:
在这里插入图片描述
相比隐式等待,显示等待有两个明显的优点:

  • 可以通过代码指定预期条件;
  • 网页超时之后若没有成功加载,会自动抛出错误;

下面是官网中列出的一些预期条件:
在这里插入图片描述

上述内容中,我们结合selenium官方文档和我们的案例对节点操作、定位元素、延时等待等内容进行了介绍,关于cookies、浏览器前进后退等知识点,请小伙伴们自行阅读官网进行学习。
在这里插入图片描述

以上就是我们关于 Selenium 的所有内容,文中没有涉及到的内容,小伙伴们一定要到官网进行深入学习。

写在最后

为方便读者了解更为详细的信息,我为小伙伴们提供了三个我的官方渠道:

  • hahaCoder(微信公众号)
  • hahaAI(微信小程序)
  • hahaWebsite. (个人网站)
相关文章
|
2月前
|
测试技术 数据安全/隐私保护 Python
大麦网抢票攻略:使用Python Selenium实现
大麦网抢票攻略:使用Python Selenium实现
|
4月前
|
Web App开发 前端开发 测试技术
Web应用程序测试工具Selenium用法详解
Web应用程序测试工具Selenium用法详解
89 0
|
21天前
|
Web App开发 机器学习/深度学习 测试技术
软件测试中的自动化策略:以Selenium为例
【8月更文挑战第31天】在软件开发周期中,测试环节扮演着至关重要的角色。随着敏捷开发的兴起,自动化测试成为提升效率和确保产品质量的关键手段。本文将介绍如何利用Selenium工具实现软件的自动化测试,从搭建环境到编写测试脚本,再到执行和分析结果,我们将一步步揭示自动化测试的全过程。文章旨在通过具体示例,帮助读者理解并运用自动化测试技术,提高测试工作的效率和效果。
|
11天前
|
Web App开发 Java 测试技术
自动化测试的利器:Selenium WebDriver入门与实践
【9月更文挑战第8天】在软件开发的海洋中,测试是确保我们不会溺水的那根救生索。Selenium WebDriver,作为自动化测试的明星工具,让这根救生索更加结实可靠。本文将带你快速上手Selenium WebDriver,从基础设置到实际操作,再到实战演练,让你的开发之旅更加平稳顺畅。
|
6天前
|
敏捷开发 Java 测试技术
探索自动化测试的奥秘:从Selenium到Appium
【9月更文挑战第14天】软件测试,这个看似枯燥乏味却至关重要的领域,正经历着一场革命。随着技术的进步,自动化测试工具如Selenium和Appium已成为质量保证的利器。本文将带你一探这些工具的神秘面纱,了解它们如何简化测试流程、提升效率,并确保软件产品的质量。准备好,我们将深入自动化测试的世界,解锁其背后的原理和实践技巧。
|
7天前
|
敏捷开发 测试技术 持续交付
自动化测试之美:如何用Selenium和Python打造高效测试脚本
【9月更文挑战第13天】在软件开发的海洋中,自动化测试是那抹不可或缺的亮色。它不仅提升了测试效率,还保障了产品质量。本文将带你领略使用Selenium和Python构建自动化测试脚本的魅力所在,从环境的搭建到脚本的编写,再到问题的排查,每一步都是对软件质量把控的深刻理解和实践。让我们开始这段探索之旅,解锁自动化测试的秘密吧!
9 0
|
7天前
|
JavaScript 前端开发 测试技术
Selenium2Library实现基于GUI的测试
Selenium2Library实现基于GUI的测试
15 0
|
20天前
|
Web App开发 Java 测试技术
自动化测试的新篇章:使用Selenium WebDriver进行高效测试
【8月更文挑战第31天】 在软件开发的海洋中,自动化测试犹如一艘航船,带领着质量保证团队驶向效率与精准的彼岸。本文将揭开Selenium WebDriver的神秘面纱,通过实际案例引导您掌握这一强大的自动化测试工具。我们将从Selenium WebDriver的基础概念出发,逐步深入到代码示例,最后探讨其在现实项目中的应用场景和优势,旨在为您的软件测试之旅提供清晰的指南。
|
20天前
|
Web App开发 测试技术 持续交付
探索自动化测试:以Selenium和Python为例
【8月更文挑战第31天】自动化测试在现代软件开发中扮演着不可或缺的角色。本文将通过一个简化的示例,展示如何使用Selenium和Python进行Web应用的自动化测试。我们将从安装必要的工具开始,逐步构建一个简单的测试脚本,并执行它来验证其功能。通过这个过程,我们旨在揭示自动化测试的价值,并激励读者深入探索这一领域。
|
20天前
|
Web App开发 IDE 测试技术
自动化测试的利器:Selenium 框架深度解析
【8月更文挑战第31天】在软件开发的世界中,自动化测试是提高产品质量和开发效率不可或缺的一环。本文将深入探讨Selenium这一强大的自动化测试工具,从其架构、优势到实战应用,一步步揭示如何利用Selenium框架提升软件测试的效率和准确性。通过具体的代码示例,我们将展示Selenium如何简化测试流程,帮助开发者快速定位问题,确保软件的稳定性和可靠性。无论你是测试新手还是资深开发者,这篇文章都将为你打开一扇通往高效自动化测试的大门。