Selenium 脑洞小开-selenium,动态运行日常调试代码 (python 篇)

yuan · 2017年08月31日 · 最后由 upengfei 回复于 2018年11月12日 · 2500 次阅读
本帖已被设为精华帖!

最近一直苦恼怎么动态调试已经打开了的浏览器!!,苦思冥想之后,想到了这个折中的办法~~
简单地说,就是程序之间的通讯来实现对已经打开的浏览器进行动态的调试!!
废话不多说,直接上代码
服务端:创建一个WebDriver实例:drive;reload(rpcclient)就是重新加载模块,主要是通过rpcclient里面的get函数来实现动态调试

# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# rpcserver.py
import pickle

from selenium.webdriver.chrome.webdriver import WebDriver
from multiprocessing.connection import Listener
from threading import Thread

drive = WebDriver(executable_path="C:\chromedriver\chromedriver")


def rpc_server(handler, address, authkey):
sock = Listener(address, authkey=authkey)
while True:
client = sock.accept()
t = Thread(target=handler.handle_connection, args=(client,))
t.daemon = True
t.start()


class RPCHandler(object):
def __init__(self):
# rpc functions map
self._functions = {}

def register_function(self, func):
self._functions[func.__name__] = func

def handle_connection(self, connection):
try:
while True:
# 接收到一条消息, 使用pickle协议编码
func_name, args, kwargs = pickle.loads(connection.recv())
# rpc调用函数,并返回结果
try:
r = self._functions[func_name](*args, **kwargs)
print(type(r))
connection.send(pickle.dumps(r))
except Exception as e:
connection.send(pickle.dumps(e))
except EOFError:
pass


if __name__ == '__main__':
# 写几个测试方法
def add():
reload(rpcclient)
rpcclient.get(drive)


# 新建一个handler类实例, 并将add方法注册到handler里面
import rpcclient
from imp import reload

rpc_handler = RPCHandler()
rpc_handler.register_function(add)

# 运行server
rpc_server(rpc_handler, ('localhost', 17001), authkey=b'tab_space')


客户端:里面的get方法,可以随时修改调试代码后进行运行

# -*- coding: utf-8 -*-

import pickle


class RPCProxy(object):
def __init__(self, connection):
self._connection = connection

def __getattr__(self, name):
# 通过name,得到一个函数
def do_rpc(*args, **kwargs):
self._connection.send(pickle.dumps((name, args, kwargs)))
result = pickle.loads(self._connection.recv())
if isinstance(result, Exception):
raise result
return result

return do_rpc


def get(driver):
driver.find_elements_by_xpath("//span[contains(text(), '添加部门/单位')]")[0].click()

# 远程连接并且调用
if __name__ == '__main__':
from multiprocessing.connection import Client

rpc_client = Client(('localhost', 17000), authkey=b'tab_space')
proxy = RPCProxy(rpc_client)
b = proxy.add()

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 12 条回复 时间 点赞

你这个是实现了动态调试 chromedriver 吧?

恒温 将本帖设为了精华贴 09月01日 09:55

有意思的脑洞

yuan #4 · 2017年09月01日 作者
恒温 回复

感谢恒温大大的赞赏!!

有意思

—— 来自TesterHome官方 安卓客户端

selenium 是有session的 其实应该是可以共享的

yuan #7 · 2017年09月01日 作者
心向东 回复

session目测是不共享的

yuan 我的 selenium日常调试 中提及了此贴 09月04日 15:44

赞赞赞!!!

浏览器启动了,无法打开对应网页,浏览器空白显示。过一会报如下错误:
Traceback (most recent call last):
File "E:\workplace\learn_python\Test1\rpcclient.py", line 37, in
rpc_client = Client(('127.0.0.1', 17000), authkey=b'tab_space')
File "D:\Python27\lib\multiprocessing\connection.py", line 169, in Client
c = SocketClient(address)
File "D:\Python27\lib\multiprocessing\connection.py", line 308, in SocketClient
s.connect(address)
File "D:\Python27\lib\socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 10061]
不知道原因在哪?哪位遇到了请指教,谢谢
重新启动elipse把服务器与客户端端口号修改为一致解决了。上面代码的C与S端口号不一致

这个跟Chrome的Devtools协议的想法差不多,但是Chrome用的是Websocket,你用的RPC

单例模式是不是也可以?

yuan #14 · 2018年11月09日 作者
upengfei 回复

你想表达什么意思?单例模式,和这里的动态调试好像没关系吧?

yuan 回复

没啥意思,理解错误。。。你的做法确实很赞!

simple 专栏文章:[精华帖] 社区历年精华帖分类归总 中提及了此贴 12月13日 20:49
simple [精彩盘点] TesterHome 社区 2018年 度精华帖 中提及了此贴 01月07日 12:08
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册