概述WebDriver协议基于HTTP使用JSON进行数据传输定义了client与driver之间的通信标准。无论client的实现语言如Java或C#都能通过协议中的endpoints准确指示driver执行各种操作覆盖了Selenium的所有功能。这些endpoints详细列出了所有可用的功能点。目标msedgedriver下载启动msedgedriver.exe --port8080 --remote-allow-origins* - --verbose -allow-insecure-localhost --allowed-origins* --allowed-ips[127.0.0.1] --headless --disable-gpu示例#include webdriver.h int main() { WebDriver m_driver; m_driver.NavigateTo(https://www.hao123.com/); qDebug() m_driver.getPageSource(); }效果webdriver.h#ifndef WEBDRIVER_H #define WEBDRIVER_H #include QNetworkAccessManager #include QNetworkReply class WebDriver : public QObject { Q_OBJECT public: WebDriver(); ~WebDriver(); void getStatus(); void getTimeout(); void setTimeOut(int implicit, long long pageLoad, long long script); void NavigateTo(const QString url); QString getCurrentUrl(); void historyBack(); void historyForward(); void refresh(); QString getTitle(); QString showWindow(); void closeWindow(); void getWindowHandles(); void createWindow(); QString getPageSource(); signals: void response(const QByteArray bytes); private: void connectToServer(const QUrl url); private: void post(const QByteArray bytes); void get(); void deleteRes(); private: void waitFinish(); private: QString m_host; QNetworkAccessManager m_networkManger; QNetworkRequest m_client; std::string m_sessionID; std::string m_elementID; QByteArray m_responseCache; }; #endif // WEBDRIVER_Hwebdriver.cpp#include webdriver.h #include QElapsedTimer #include QApplication #include QJsonDocument #include QJsonObject #include webDriverResponseJson.h #include webDriverRequestJson.h WebDriver::WebDriver() : m_host(http://127.0.0.1:8080){ connectToServer(QUrl(m_host /session)); } WebDriver::~WebDriver() { if (m_sessionID.empty()) return; m_client.setUrl(QUrl(m_host QString(/session/) QString::fromStdString(m_sessionID))); deleteRes(); waitFinish(); } void WebDriver::connectToServer(const QUrl url) { m_client.setUrl(url); m_client.setHeader(QNetworkRequest::ContentTypeHeader, application/json; charsetutf-8); m_client.setHeader(QNetworkRequest::UserAgentHeader, Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0); m_client.setRawHeader(Cache-Control, no-cache); REQ::Options options; options.capabilities.browserName edge; std::string json JS::serializeStruct(options, JS::SerializerOptions(JS::SerializerOptions::Compact)); post(QString::fromStdString(json).toLocal8Bit()); waitFinish(); // 反序列 RES::MSEdgeRoot response; JS::ParseContext parseContext(m_responseCache.data()); auto error parseContext.parseTo(response); if (JS::Error::NoError ! error) { std::string errorStr parseContext.makeErrorString(); fprintf(stderr, Error parsing struct %s\n, errorStr.c_str()); } m_sessionID response.value.sessionId; } void WebDriver::NavigateTo(const QString url) { m_client.setUrl(QUrl(m_host QString(/session/) QString::fromStdString(m_sessionID) /url)); REQ::NavigateTo nav; nav.url url.toStdString(); std::string json JS::serializeStruct(nav, JS::SerializerOptions(JS::SerializerOptions::Compact)); post(QString::fromStdString(json).toLocal8Bit()); waitFinish(); QJsonParseError jsonError; QJsonDocument doucment QJsonDocument::fromJson(m_responseCache, jsonError); // 转化为 JSON 文档 if (!doucment.isNull() (jsonError.error QJsonParseError::NoError)) { // 解析未发生错误 if (doucment.isObject()) { // JSON 文档为对象 QJsonObject object doucment.object(); // 转化为对象 if (object.contains(value)) { // 包含指定的 key QJsonValue value object.value(value); // 获取指定 key 对应的 value qDebug() NavigateTo (value.isNull() ? Success : Fail); } } } } QString WebDriver::getPageSource() { m_client.setUrl(QUrl(m_host QString(/session/) QString::fromStdString(m_sessionID) /source)); get(); waitFinish(); QJsonParseError jsonError; QJsonDocument doucment QJsonDocument::fromJson(m_responseCache, jsonError); // 转化为 JSON 文档 if (!doucment.isNull() (jsonError.error QJsonParseError::NoError)) { // 解析未发生错误 if (doucment.isObject()) { // JSON 文档为对象 QJsonObject object doucment.object(); // 转化为对象 if (object.contains(value)) { // 包含指定的 key QJsonValue value object.value(value); // 获取指定 key 对应的 value if (value.isString()) return value.toString(); } } } return QString::fromStdString(m_responseCache.toStdString()); } void WebDriver::waitFinish() { QEventLoop loop; connect(this, WebDriver::response, loop, QEventLoop::quit); loop.exec(); } void WebDriver::post(const QByteArray bytes) { auto reply m_networkManger.post(m_client, bytes); connect(reply, QNetworkReply::finished, [this, reply]() { m_responseCache reply-readAll(); qDebug() finish: m_responseCache; emit response(m_responseCache); }); } void WebDriver::get() { auto reply m_networkManger.get(m_client); connect(reply, QNetworkReply::finished, [this, reply]() { m_responseCache reply-readAll(); qDebug() finish: m_responseCache; emit response(m_responseCache); }); } void WebDriver::deleteRes() { auto reply m_networkManger.deleteResource(m_client); connect(reply, QNetworkReply::finished, [this, reply]() { emit response(m_responseCache); }); }example.pyimport requests import json session_url http://localhost:8080/session session_pars {capabilities: {browserName: edge}} r_session requests.post(session_url,jsonsession_pars) print(json.dumps(r_session.json(),indent2))参考使用 WebDriver 自动执行 Microsoft Edge - Microsoft Edge Developer documentation | Microsoft Learn WebDriverselenium ,webdriver 运行原理与机制-腾讯云开发者社区-腾讯云C/C JSON ORM 之 structs 数据结构相互嵌套定义-CSDN博客创作不易小小的支持一下吧
企业数字化 ERP 产品动态
相关推荐
C++函数调用耗时采集 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 12:55:04
C++几何运算库GEOS /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/7 19:10:47
C++安全密码生成与强度检测 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/7 3:37:04
电工证不复审会作废保姆级教程 电工证不复审会作废保姆级教程 证书过期了不知道怎么复审延期?别慌,今天就给你讲明白电工证不复审会作废的真相,还有保姆级教程带你一步步搞定复审和续期,避免被查、被罚、被限制从业。 为什么电工证不复审会作废? 电工证… · 2026/11/7 19:10:38
将乐电工证怎么考通过率揭秘:证书过期了不知道怎么复审延期? 将乐电工证怎么考通过率揭秘:证书过期了不知道怎么复审延期? 证书过期了不知道怎么复审延期?这是很多从事电工行业的朋友最头疼的问题之一。尤其是像将乐这样的地方,电工证不仅关系到你的职业发展,更是关系到你能否继续从事相关工作。但很多人在证书快到… · 2026/11/7 19:10:38
电工证年审要培训,官方回应来了,工地太忙根本没时间复习考试 电工证年审要培训,官方回应来了,工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这是很多特种作业人员,特别是电工证持有者的普遍焦虑。尤其是涉及到 电工证年审要培训 的问题,不少人都在问: 年审真的要参加培训吗?… · 2026/11/7 19:10:38
国网公司电工证考试千万别踩坑,证书过期了不知道怎么复审延期 国网公司电工证考试千万别踩坑,证书过期了不知道怎么复审延期 证书过期了不知道怎么复审延期,这事儿真不是小问题,尤其是在国网公司电工证考试这种对流程和细节要求极高的行业。很多人都因为一个疏忽,导致证书失效,不仅影响工作,还可能面临罚款甚至被追… · 2026/11/7 19:10:38
电工作业防护服要求通过率揭秘:信阳浉河区水利从业者必看 电工作业防护服要求通过率揭秘:信阳浉河区水利从业者必看 怕考不过白交培训费?电工作业防护服要求是特种作业考试中最容易被忽视但又最容易扣分的部分。尤其在信阳浉河区水利工程项目上,不少电工因为防护服穿戴不当直接被判定考试不合格。今天就来揭秘电工… · 2026/11/7 19:10:38
苏州市电工证怎么查内部消息全公开 电工证过期了别慌 苏州市电工证怎么查内部消息全公开 电工证过期了别慌 证书过期了不知道怎么复审延期?你不是一个人。现在苏州市电工证的审核和复审流程正在收紧,很多人因为不了解最新规定,白白丢了工作机会,甚至被单位辞退。尤其是像安阳房建工程这类经常涉及电气作业的… · 2026/11/7 19:09:37
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/7 11:25:08
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/7 12:02:18
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 10:29:23
澳洲水电工证考试:证书过期了不知道怎么复审延期?电子证书怎么弄? 澳洲水电工证考试:证书过期了不知道怎么复审延期?电子证书怎么弄? 证书过期了不知道怎么复审延期?别慌,很多人在拿到【澳洲水电工证考试】的电子证书后,一不小心就忽略了复审时间,结果证书失效,工作受阻,甚至被单位追责。今天就从【澳洲水电工证考试… · 2026/11/7 0:00:41
电工作业提示版通过率揭秘:怎么考才能一次过? 电工作业提示版通过率揭秘:怎么考才能一次过? 怕考不过白交培训费?别急,今天我就从驻马店应届工程类毕业生的视角,带你全面了解电工作业提示版的考试流程、备考要点和真实通过率,帮你少走弯路、提高一次通过率。… · 2026/11/7 0:00:41
电工证年审报名千万别踩坑 外省证转过来要搞清这几点 电工证年审报名千万别踩坑 外省证转过来要搞清这几点 之前考的证在外省能不能转过来?这个问题是很多电工从业者最关心的,特别是像你这样在商丘从事公路工程的人员,经常需要跨省流动,证书的 有效性 和 可迁移性… · 2026/11/7 0:00:41
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/7 11:25:08
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/7 12:02:18
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 10:29:23