大麦网抢票程序之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. (个人网站)
相关文章
|
4月前
|
测试技术 数据安全/隐私保护 Python
大麦网抢票攻略:使用Python Selenium实现
大麦网抢票攻略:使用Python Selenium实现
|
6月前
|
Web App开发 前端开发 测试技术
Web应用程序测试工具Selenium用法详解
Web应用程序测试工具Selenium用法详解
122 0
|
1月前
|
Web App开发 前端开发 JavaScript
探索Python科学计算的边界:利用Selenium进行Web应用性能测试与优化
【10月更文挑战第6天】随着互联网技术的发展,Web应用程序已经成为人们日常生活和工作中不可或缺的一部分。这些应用不仅需要提供丰富的功能,还必须具备良好的性能表现以保证用户体验。性能测试是确保Web应用能够快速响应用户请求并处理大量并发访问的关键步骤之一。本文将探讨如何使用Python结合Selenium来进行Web应用的性能测试,并通过实际代码示例展示如何识别瓶颈及优化应用。
99 5
|
1月前
|
Java 测试技术 C#
自动化测试之美:从Selenium到Appium
【10月更文挑战第3天】在软件开发的海洋中,自动化测试如同一艘航船,引领着质量保证的方向。本文将带你领略自动化测试的魅力,从Web端的Selenium到移动端的Appium,我们将一探究竟,看看这些工具如何帮助我们高效地进行软件测试。你将了解到,自动化测试不仅仅是技术的展示,更是一种提升开发效率和产品质量的智慧选择。让我们一起启航,探索自动化测试的世界!
|
1月前
|
JavaScript 前端开发 测试技术
精通Selenium:从基础到高级的网页自动化测试策略
【10月更文挑战第6天】随着Web应用变得越来越复杂,手动进行功能和兼容性测试变得既耗时又容易出错。自动化测试因此成为了现代软件开发不可或缺的一部分。Selenium是一个强大的工具集,它支持多种编程语言(包括Python),允许开发者编写脚本来模拟用户与Web页面的交互。本文将带领读者从Selenium的基础知识出发,逐步深入到高级的应用场景,通过丰富的代码示例来展示如何高效地进行网页自动化测试。
248 5
|
1月前
|
Web App开发 IDE 测试技术
自动化测试的利器:Selenium 框架深度解析
【10月更文挑战第2天】在软件开发的海洋中,自动化测试犹如一艘救生艇,让质量保证的过程更加高效与精准。本文将深入探索Selenium这一强大的自动化测试框架,从其架构到实际应用,带领读者领略自动化测试的魅力和力量。通过直观的示例和清晰的步骤,我们将一起学习如何利用Selenium来提升软件测试的效率和覆盖率。
|
15天前
|
Web App开发 设计模式 JavaScript
自动化测试之美:如何利用Selenium实现Web应用的高效测试
【10月更文挑战第29天】在软件开发的世界中,测试是确保产品质量的关键步骤。本文将带你了解如何使用Selenium这一强大的自动化测试工具,提高Web应用测试的效率和准确性。通过实际案例,我们将探索Selenium的核心功能及其在现代软件开发中的应用,旨在帮助读者掌握自动化测试的精髓,从而提升软件测试工作的整体效能。
12 0
|
1月前
|
Web App开发 缓存 Linux
高效Selenium测试技巧:轻松控制已开启的浏览器
【10月更文挑战第13天】在进行Selenium测试时,通常会启动新浏览器实例,但有时需要控制已开启的浏览器,以节省时间并更真实地模拟用户行为。这可通过设置Chrome为可远程控制并使用`Remote WebDriver`连接实现。需在启动Chrome时添加`--remote-debugging-port`参数,并通过Python脚本中的`webdriver.Remote`连接至指定端口。此外,还可利用会话ID(Session ID)重新连接浏览器,提高测试灵活性。需要注意浏览器版本兼容性及元素定位稳定性等问题,确保测试准确性和一致性。
250 1
|
1月前
|
测试技术 数据安全/隐私保护 开发者
自动化测试的奥秘:如何用Selenium和Python提升软件质量
【9月更文挑战第35天】在软件开发的海洋中,自动化测试是那艘能引领我们穿越波涛的帆船。本文将揭开自动化测试的神秘面纱,以Selenium和Python为工具,展示如何构建一个简单而强大的自动化测试框架。我们将从基础出发,逐步深入到高级应用,让读者能够理解并实现自动化测试脚本,从而提升软件的质量与可靠性。
|
2月前
|
Web App开发 JavaScript Java
自动化测试的利剑:Selenium WebDriver入门与实践
【9月更文挑战第21天】在软件开发的海洋中,自动化测试犹如一艘船,帮助开发者们快速航行至质量保证的彼岸。本文将作为你的罗盘,指引你了解和掌握Selenium WebDriver这一强大的自动化测试工具。通过深入浅出的方式,我们将探索Selenium WebDriver的基本概念、安装过程以及编写简单测试脚本的方法。无论你是刚接触自动化测试的新手,还是希望提升测试技能的开发者,这篇文章都将为你提供有价值的指导。