selenium 原理应用 - 利用 requests 模拟 selenium 驱动浏览器
前言
selenium 是一个 Web 自动化测试的开源框架,它支持多语言:python/java/c#…
前面也有一篇文章说明了,selenium+ 浏览器的环境搭建。
selenium 支持多语言,是因为 selenium 与浏览器驱动之间是通过 http 协议进行通信的。只关心通信的数据是否能够正确解读 ,并不关心这个数据是从哪个客户端来。无论来自 python\java,还是 jmeter,postman 都没有问题。
本篇文章中,以 requests 做为客户端,跳过 selenium,直接与谷歌浏览器驱动(chromedriver)进行 http 通信,驱动 Chrome 浏览器去执行命令。
requests 库
先解释一下 requests 库:一个 python 的第三方库,是目前最好用的 http 请求库。
直接封装了 get 请求、post 请求。
只需要提供 请求 url、请求方法、请求内容即可。
以下为 request 库使用的简单示例(request 的详细使用可参看其它博主其它的博文):
import requestss = requests.session()
response = s.get("http://www.baidu.com") # 发起get请求
print(response.text) # 获取响应结果的 响应数据
res = response.json() # 将 响应数据 转换成python数据对象。
如果我要利用 requests 库,去向 chromedriver 发送请求。那么我必须得了解请求的类型、请求的数据、请求的内容是什么。
基于此,我们需要了解在 selenium 库当中,会有哪些请求?
需要解决的问题
- selenium 有哪些请求?
- 每一个请求的请求 url、请求类型如何获取?
- 每一个请求的请求数据又如何获取?
selenium - JSON wire protocol - 获取请求 url 和类型
要想解决以上 3 个问题,我们需要了解 selenium 的部分原理。
在 selenium 与驱动进行 http 通信的协议全称叫做:JSON wire protocol.
我们在使用 selenium 库驱动浏览器的时候,我们的操作有一部分大概是以下这样的:
- 打开 Chrome 浏览器;
- 访问某一个网址;
- 查找该网址中的某一个元素;
- 操作 3)中查找到的元素。
在 selenium 库看来,以上每一步操作都是一个 http 请求,也叫做命令(Command)。
chromedriver 在收到这个请求之后,再去驱动对 Chrome 浏览器执行对应的动作。
所以,在 selenium 库当中,存储了所有命令(Command)名称、命令对应的 http 请求类型、命令对应的请求 url。
首先,来看看 Command 的名称(选取几个大家熟知的操作):
访问网站命令(GET)对应的请求类型和请求 url 为:
从上图可以看出,GET 命令是 post 请求,请求地址只有一部分。
url 中有 3 个问题:
1)请求的 url 并不完整。
url 中,缺失中 base 地址。base 地址为,chromedriver 的 ip+ 端口号。因为,命令是发给 chromedriver 去执行的。
2)url 当中的 $sessionId 是什么?
在 selenium 当中,每开启一次与 chromedriver 的会话,都会生成一个会话 ID。sessionId 就是这个会话 ID。在很多的命令请求当中,在请求地址中,通过 sessionId 都绑定了当前的会话。
换句话说,我们要用 requests 与 chromedriver 进行通信,那么我们首先,得生成会话 ID,并得到这个 ID 值,才能够进一步的去访问网页,去发送更多的浏览器操作命令。
3)sessionId 从何而来?如何获取?
在 selenium 当中,通过 NEW_SESSION 请求来开启会话,chromedriver 在收到请求后,在响应数据中,返回本次会话的 sessionId
请求的参数如下(启动什么类型的浏览器、有什么配置参数):
params = {'capabilities': {'firstMatch': [{}],'alwaysMatch': {'browserName': 'chrome','platformName': 'any','goog:chromeOptions': {'extensions': [], 'args': []}}},'desiredCapabilities': {'browserName': 'chrome','version': '','platform': 'ANY','goog:chromeOptions': {'extensions': [], 'args': []}}}
chromedriver在正常收到请求之后,响应的数据如下(主要为sessionId):
{"sessionId": "ed76b48661b6fe58b9be6f56716531b7", # 本次会话的sessionId"status": 0,"value": {"acceptInsecureCerts": false,"acceptSslCerts": false,"applicationCacheEnabled": false,"browserConnectionEnabled": false,"browserName": "chrome","chrome": {"chromedriverVersion": "74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29})","userDataDir": "/var/folders/gm/k4pj0kf50vz9f3gznsp4cn340000gn/T/.com.google.Chrome.OPZURo"},"cssSelectorsEnabled": true,"databaseEnabled": false,"goog:chromeOptions": {"debuggerAddress": "localhost:63649"},"handlesAlerts": true,"hasTouchScreen": false,"javascriptEnabled": true,"locationContextEnabled": true,"mobileEmulationEnabled": false,"nativeEvents": true,"networkConnectionEnabled": false,"pageLoadStrategy": "normal","platform": "Mac OS X","proxy": {},"rotatable": false,"setWindowRect": true,"strictFileInteractability": false,"takesHeapSnapshot": true,"takesScreenshot": true,"timeouts": {"implicit": 0,"pageLoad": 300000,"script": 30000},"unexpectedAlertBehaviour": "ignore","version": "75.0.3770.100","webStorageEnabled": true}
}
ps: 可访问此网站了解详情:https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
selenium - 每一个命令函数 - 设置请求数据
以上我们获取到了每一个命令的请求地址和请求类型。那么请求数据从哪里获取 呢?
每一个命令的功能不一样,请求的数据也就不一样。在 selenium 当中,都是在命令对应的函数当中去设置请求数据的。
比如,访问网址操作命令,在 selenium 当中是 get 函数,那么我们去看 get 函数的源码:
在上图中的 execute 函数当中,第二个参数 params 对应的就是请求数据。所以 get 命令的请求体为:{"url":调用 get 函数传进来的 url 值}
再比如,查找元素命令,在selenium当中是find_element函数,那么我们去看find_element的源码:
所以 find_elment 命令的的请求体为:{"using":定位类型,"value":定位表达式}
利用 requests - 开启浏览器会话、访问百度首页、搜索柠檬班
- 启动本地电脑 上的 chromedriver 程序。双击即可。默认的服务端口为 9515
2. 通过requests库向chromedriver发起会话、并打开百度首页的代码如下:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Name: use_request_send_http_chromedriver
# Author: liyuan
# Time: 15:52# 1、base_url从哪里来的?如何确定?
# 2、命令的请求类型从哪里来的?请求地址从哪里来的?
# 3、请求参数从何获取。import requests# chromedriver服务的base地址。
base_url = "http://127.0.0.1:9515"
# 创建会话
s = requests.Session() # **************************向chromedriver发送的命令1:建立会话**************************# 创建与chromedriver会话的请求数据
params = {'capabilities': {'firstMatch': [{}],'alwaysMatch': {'browserName': 'chrome','platformName': 'any','goog:chromeOptions': {'extensions': [], 'args': []}}},'desiredCapabilities': {'browserName': 'chrome','version': '','platform': 'ANY','goog:chromeOptions': {'extensions': [], 'args': []}}}# 创建与chromedriver的会话。注意请求数据格式是application/json
res = s.request("POST",base_url+'/session',json=params)
# 获取sessionId值
sessionid = res.json()["sessionId"] # **************************向chromedriver发送的命令2:打开网址**************************# 请求数据
datas = {'url': "http://www.baidu.com"}
# 请求地址拼接
url = base_url + "/session/{}/url".format(sessionid)
# 发送打开百度首页的请求,注意请求数据格式是application/json
res = s.request("post",url,json=datas)# # **************************向chromedriver发送的命令3:找到搜索输入框**************************
# 请求数据
datas3 = {'using':"id","value":"kw"}
# 请求地址拼接
url3 = base_url + "/session/{}/element".format(sessionid)
# 发送打开百度首页的请求
res3 = s.request("post",url3,json=datas3)
# 返回结果类似:{"sessionId":"2dae661546b28cd481d84048310fb196","status":0,"value"{"ELEMENT":"0.899392980463724-1"}}
# 获取元素的id
ele_id = res3.json()["value"]["ELEMENT"]# *****************向chromedriver发送的命令4:在搜索框当中输入 柠檬班******************
# /session/$sessionId/element/$id/value
# 请求数据
datas4 = {'text': '柠檬班', 'value': ['柠', '檬', '班']}
# 请求地址拼接
url4 = base_url + "/session/{}/element/{}/value".format(sessionid,ele_id)
# 发送打开百度首页的请求
res4 = s.request("post",url4,json=datas4)
以上代码运行的结果如下:
selenium 原理应用 - 利用 requests 模拟 selenium 驱动浏览器相关推荐
- 爬虫实战(二)—利用requests、selenium爬取王者官网、王者营地APP数据及pymongo详解
概述 可关注微信订阅号 loak 查看实际效果. 代码已托管github,地址为:https://github.com/luozhengszj/LOLGokSpider ,包括了项目的所有代码. 本文 ...
- Linux下PHP使用selenium、chrome、chromedriver模拟无界面浏览器
1.安装chrome - 下载:wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm - 安装 ...
- 利用requests 模拟登陆csdn
环境:python3.6.1 + lxml4.0.0 + requests2.18.4 坑一:登陆时请求的网址需要构造,数据在form标签属性里, 坑二:表单数据的提取 坑三:登陆后的跳转,不然无法访 ...
- python+selenium获取cookie session_Python Selenium模拟登录成功后,使用此cookie、利用requests库进行get时,提示“非法登陆”。...
一. 步骤概述 a. 模拟登录学校选课系统(使用Selenium库登陆http://xk.suibe.edu.cn/xsxk/login.xk) b. 取得cookie后传入requests的sess ...
- chrome frame节点 取_爬虫3-下(利用Selenium + Chrome Driver模拟用户操作浏览器)
一.前言 前面利用request的方法爬取页面数据的操作,今天用另外一种方法:利用Selenium + Chrome Driver模拟用户操作浏览器,来爬取数据. 在此之前需要做一些准备工作:安装se ...
- python中webdriver_浅谈python中selenium库调动webdriver驱动浏览器的实现原理
最近学web自动化时用到selenium库,感觉很神奇,遂琢磨了一下,写了点心得. 当我们输入以下三行代码并执行时,会发现新打开了一个浏览器窗口并访问了百度首页,然而这是怎么做到的呢? 1 from ...
- python 模拟浏览器selenium 微信_Spider-Python爬虫之使用Selenium模拟浏览器行为
分析 他的代码比较简单,主要有以下的步骤:使用BeautifulSoup库,打开百度贴吧的首页地址,再解析得到id为new_list标签底下的img标签,最后将img标签的图片保存下来. header ...
- Jmeter模拟selenium操作浏览器
前言 selenium是一个web自动化测试的开源框架,它支持多语言:python/java/c#- selenium支持多语言,是因为selenium与浏览器驱动之间是通过http协议进行通信的.只 ...
- 利用python的selenium模块向Plant-mPLoc提交数据
利用python的selenium模块向Plant-mPLoc提交数据 流程一般步骤 1.对数据的预处理 2. 环境的配置 3.代码分析及流程思想 回顾和展望 流程一般步骤 首先我们对得到的序列预 ...
最新文章
- 3ds max 把模型放置到坐标系中心(原点)
- javascript 之 push方法
- JavaScript 正则表达式
- PHP 4 中对象的比较
- the first day
- js sort方法根据数组中对象的某一个属性值进行排序(实用方法)
- 前端请求接口post_接口自动化测试-WEB资讯专栏-DMOZ中文网站分类目录
- abap object-oriented–使用事件
- 内部推荐岗位信息201508
- 使用thinkadmin内置WeChatDeveloper发送公众号模板消息
- linux ps被替换文件,在linux下从jar中替换、修改文件
- mac卸载python3.7_工具安装-Mac 卸载python3
- 数字图像处理 - 什么是数字图像处理
- 使用了未经检查或不安全的操作
- 【C++】C++实战项目机房预约管理系统
- C语言——初识关键字、static、#define定义、指针
- c语言对编程对作用,c语言编程心得体会
- 511遇见易语言学习易语言常量
- NodeJS之child_process模块
- Emlog最新文章采集插件