赞
踩
大家好,我是石璞东。
我们在 大麦网抢票程序(一)之大麦网网站分析 一文中详细描述了本次项目案例的需求,并对其做了深入的分析,在本篇文章中,我们来讲解一下实现该案例所涉及的一些具体的技术栈,请看文章。
在文章开始之前,我先从两个角度回答一个问题:
为什么会选择使用selenium?
角度一: 我们知道,在爬虫的过程中,我们会经常遇到以下三种形式的网页:
第一种是在请求相应的网址之后,在网速等外部原因满足的条件下,即可得到网页的完整源代码,即浏览器所查看到的源代码就是网页实际的源代码,这种网站包括有 大麦网、中国研究生招生信息网 等;
第二种是那些通过 Ajax
渲染出来的页面,对于该种类型的网页,我们只需要直接去分析所请求的 Ajax
,然后借助 requests
或者 urllib
即可实现数据的爬取,这种网站包括 今日头条 等;
第三种是那些通过 JavaScript
计算生成的网页,这种网站包括 百度的Echarts 等。
角度二: 本系列文章中,我们是要通过自动化程序来抢德云社小园子的票,所以必须有用户亲自选择座位、票档等相关操作,这就解释了我们为什么没有使用 Chrome
的 Headless
模式或者 PhantomJS
。接下来,请看正文内容。
我们来考虑一个问题:假设中国的所有省份中每个省均只有一个接入互联网的网关,即只能通过该网关访问互联网资源,也就是说只有一个公网ip,假设这34个省每个省的所有用户每天都访问一次我的网站,请问24个小时之后,我网站的浏览量是所有用户的个数还是34,那独立ip的个数是多少呢?
首先,请看答案:网站的访问量是所有访问用户的总个数,独立IP是34,请看详细分析:
小伙伴们在阅读本小节内容之前,最好有一些关于搜索引擎的基本概念,这里我给大家找出了我2019年年底考完研之后写的一篇文章 移动支付&&搜索引擎。
以我的个人网站为例,给各位小伙伴看下主流搜索引擎对我网站词条的排名情况:
从关键词搜索的词条排名情况和词条数目也能反映出所用搜索引擎的某些优缺点,从爬虫速度来说: Google>搜狗>百度>360,搜狗应该算是爬虫速度频率比较高的了,百度对于我的网站的收录还有一些死链,360就不用说了,词条数和死链都是最少的。
网站流量的提高:
工欲善其事,必先利其器,在完成我们的案例之前,我们先来安装一下相关的环境配置。
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")
非常好,安装成功!这里我们在来看两个案例:
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()
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
的过程中,当我们想要获取某些节点时,我们当然可以使用 XPath
、css
选择器等进行获取,但是由于 selenium
已经为我们提供了一系列的方法,所以关于 XPath
、css
选择器等的方法,这里就不再赘述。
请看官网地址:
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秒内下图中 id
为 content_left
的 div
中的内容可以被加载出来,程序则会继续往下执行,最后会在控制台打印当前的网址;如果没有加载出来,则会抛出超时错误,请看官网解释:
请看控制台结果:
上述代码中关于 get()
方法等待加载的部分,这里不做过多讲解,请继续阅读本文。
更多关于查找节点的操作,这里不再进行一一赘述,官网中已经有足够详细的介绍和相关的例子,请读者自行学习了解,网址如下:
https://selenium-python.readthedocs.io/locating-elements.html
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
的所有内容,文中没有涉及到的内容,小伙伴们一定要到官网进行深入学习。
为方便读者了解更为详细的信息,我为小伙伴们提供了三个我的官方渠道:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。