前言

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 requests

s = requests.session()
response = s.get("http://www.baidu.com") # 发起get请求
print(response.text) # 获取响应结果的 响应数据
res = response.json() # 将 响应数据 转换成python数据对象。

如果我要利用requests库,去向chromedriver发送请求。那么我必须得了解请求的类型、请求的数据、请求的内容是什么。

基于此,我们需要了解在selenium库当中,会有哪些请求?

需要解决的问题

1、selenium有哪些请求?

2、每一个请求的请求url、请求类型如何获取?

3、每一个请求的请求数据又如何获取?

selenium - json wire protocol - 获取请求url和类型

要想解决以上3个问题,我们需要了解selenium的部分原理。

在selenium与驱动进行http通信的协议全称叫做:json wire protocol.

我们在使用selenium库驱动浏览器的时候,我们的操作有一部分大概是以下这样的:

1)打开chrome浏览器;

2)访问某一个网址;

3)查找该网址中的某一个元素;

4)操作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 - 开启浏览器会话、访问百度首页、搜索柠檬班

1、启动本地电脑 上的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驱动浏览器的更多相关文章

  1. 浏览器行为模拟之requests、selenium模块

    requests模块 前言: 通常我们利用Python写一些WEB程序.webAPI部署在服务端,让客户端request,我们作为服务器端response数据: 但也可以反主为客利用Python的re ...

  2. 利用Python与selenium自动化模拟登陆12306官网!

    近年来,12306的反爬越来越来严重,从一年前的 获取tk参数后到现在增加了 JS.CSS等加密方式! 目前大部分人利用的登陆方式都是利用selenium ,此文也不例外. 环境:        Wi ...

  3. 浅谈python中selenium库调动webdriver驱动浏览器的实现原理

    最近学web自动化时用到selenium库,感觉很神奇,遂琢磨了一下,写了点心得. 当我们输入以下三行代码并执行时,会发现新打开了一个浏览器窗口并访问了百度首页,然而这是怎么做到的呢? from se ...

  4. Selenium WebDriver原理(二):Selenium是如何操纵浏览器的?

    前言 上一篇文章<selenium webdriver 是怎么运行的>用了一个简单的例子--搭出租车,形象地讲解selenium webdriver 是如何运行的,而这一篇文章可以理解为深 ...

  5. python利用requests库模拟post请求时json的使用

    我们都见识过requests库在静态网页的爬取上展现的威力,我们日常见得最多的为get和post请求,他们最大的区别在于安全性上: 1.GET是通过URL方式请求,可以直接看到,明文传输. 2.POS ...

  6. 爬虫模块介绍--selenium (浏览器自动化测试工具,模拟可以调用浏览器模拟人操作浏览器)

    selenium主要的用途就是控制浏览器,模仿真人操作浏览器的行为 模块安装:pip3 install selenium 需要控制的浏览器 from selenium import webdriver ...

  7. web自动化:selenium原理和元素定位(一)

    一. Selenium2 WebDriver 当Selenium2.x提出了WebDriver的概念后,它提供了完全另外的一种方式与浏览器交互 那就是利用浏览器原生的API,封装成一套更加面向对象的S ...

  8. # Python3微博爬虫[requests+pyquery+selenium+mongodb]

    目录 Python3微博爬虫[requests+pyquery+selenium+mongodb] 主要技术 站点分析 程序流程图 编程实现 数据库选择 代理IP测试 模拟登录 获取用户详细信息 获取 ...

  9. selenium:能够模拟人类打开浏览器的爬虫利器

    介绍 selenium相当于是一个机器人,可以模拟人类登陆浏览器的行为,比如点击.填充数据.删除cookie等等.Chromedriver是一个驱动Chrome的程序,使用它才可以驱动浏览器,其实Ch ...

随机推荐

  1. HDU2833-WuKong(求不同起点,终点最短路的交点最多数量)

    Liyuan wanted to rewrite the famous book "Journey to the West" ("Xi You Ji" in C ...

  2. UVA-136Ugly numbers

    Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9 ...

  3. 导出excel时,跳转新空白页,不要跳转怎么改

    导出excel的时候,偶尔会出现跳转到一个新页面再导出excel js中用window.open()做跳转 不想让它跳转到新页面,需要加一个隐藏的iframe <iframe name=&quo ...

  4. 【CSS】352- 有趣的CSS弹跳动画

    点击上方"前端自习课"关注,学习起来~ 这是只用了一个div来做的小动画,纯粹利用CSS3的animation来完成,就像是一个正方形在地上弹跳,碰到地面的时候尖角还会压缩变圆,阴 ...

  5. 第一个boot项目

    一.打开网址https://start.spring.io/ 进去springboot官网,根据自己实际情况选择所需组件,点击生成. 二.导入maven项目,但是pom.xml报Line1未知错误,检 ...

  6. UWP 使用SSL证书,保证数据安全

    事情是这样的,我们后端的小伙伴升级了用户会员系统,使用了全新的GraphQL登录机制,并且采用SSL加密的方式来实现阻止陌生客户端请求的案例. GraphQL在UWP端的实现,以后有时间会单独写一篇文 ...

  7. linux目录的读(r)、写(w)、执行(x)权限说明

    linux目录的读.写.执行权限说明 1.可读r #表示具有浏览目录下面文件及子目录的权限.即ls dir 1)如果没有x权限,不能进到目录里,即无法 cd dir 2)如果没有x权限,ls列表可以看 ...

  8. 2019 The Preliminary Contest for ICPC China Nanchang National Invitational(A 、H 、I 、K 、M)

    A. PERFECT NUMBER PROBLEM 题目链接:https://nanti.jisuanke.com/t/38220 题意: 输出前五个完美数 分析: 签到.直接百度完美数输出即可 #i ...

  9. 使用 API 网关构建微服务-2

    「Chris Richardson 微服务系列」使用 API 网关构建微服务 Posted on 2016年5月12日 编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第二篇,本文将探讨: ...

  10. Provider模式应用demo

    参考ObjectPool对象池设计原理还原一个简易的Provider模式. using System; using System.Dynamic; using System.Reflection.Me ...