C# 利用Selenium实现浏览器自动化操作的示例代码
程序员文章站
2022-06-24 21:46:34
概述selenium是一款免费的分布式的自动化测试工具,支持多种开发语言,无论是c、 java、ruby、python、或是c# ,你都可以通过selenium完成自动化测试。本文以一个简单的小例子,...
概述
selenium是一款免费的分布式的自动化测试工具,支持多种开发语言,无论是c、 java、ruby、python、或是c# ,你都可以通过selenium完成自动化测试。本文以一个简单的小例子,简述c# 利用selenium进行浏览器的模拟操作,仅供学习分享使用,如有不足之处,还请指正。
涉及知识点
要实现本例的功能,除了要掌握html ,javascript,css等基础知识,还涉及以下知识点:
- log4net:主要用于日志的记录和存储,本例采用log4net进行日志记录,便于过程跟踪和问题排查,关于log4net的配置和介绍,之前已有说明,本文不做赘述。
- queue:队列,先进先出模式,本文主要用于将日志信息保存于队列中,然后再显示到页面上,其中enqueue用于添加内容到结尾处,dequeue用于返回并移除一个位置的对象。
- iwebdriver:浏览器驱动接口,所有的关于浏览器的操作都可以通过此接口进行,不同浏览器有不同的实现类,如:ie浏览器(internetexplorerdriver)chrome浏览器(chromedriver)等。
- backgroundworker:后台工作线程,区别于主线程,通过事件触发不同的状态。
selenium安装
本例开发工具为vs2019,通过nuget进行需要的软件包的安装与管理,如下所示:
示例效果图
本例采用chrome浏览器,用于监控某一个网站并获取相应内容,如下所示:
selenium示例介绍
定义一个webdriver,如下所示:
//谷歌浏览器 chromeoptions options = new chromeoptions(); this.driver = new chromedriver(options);
通过id获取元素并填充内容和触发事件,如下所示:
this.driver.findelement(by.id("email")).sendkeys(username); this.driver.findelement(by.id("password")).sendkeys(password); //# 7. 点击登录按钮 this.driver.findelement(by.id("sign-in")).click();
通过xpath获取元素,如下所示:
string xpath1 = "//div[@class=\"product-list\"]/div[@class=\"product\"]/div[@class=\"price-and-detail\"]/div[@class=\"price\"]/span[@class=\"nostock\"]"; string txt = this.driver.findelement(by.xpath(xpath1)).text;
核心代码
主要的核心代码,就是浏览器的元素定位查找和事件触发,如下所示:
using openqa.selenium; using openqa.selenium.ie; using openqa.selenium.chrome; using system; using system.collections.generic; using system.linq; using system.text; using system.threading; using system.threading.tasks; namespace aismoking.core { public class smoking { /// <summary> /// 是否正在运行 /// </summary> private bool running = false; /// <summary> /// 驱动 /// </summary> private iwebdriver driver = null; /// <summary> /// # 无货 /// </summary> private string no_stock = "currently out of stock"; /// <summary> /// # 线程等待秒数 /// </summary> private int wait_sec = 2; private dictionary<string, string> cfg_info; private string work_path = string.empty; /// <summary> /// 构造函数 /// </summary> public smoking() { } /// <summary> /// 带参构造函数 /// </summary> /// <param name="cfg_info"></param> /// <param name="work_path"></param> public smoking(dictionary<string, string> cfg_info,string work_path) { this.cfg_info = cfg_info; this.work_path = work_path; this.wait_sec = int.parse(cfg_info["wait_sec"]); //# 如果小于2,则等于2 this.wait_sec = (this.wait_sec < 2 ? 2 : this.wait_sec); this.wait_sec = this.wait_sec * 1000; } /// <summary> /// 开始跑 /// </summary> public void startrun() { //"""运行起来""" try { this.running = true; string url = this.cfg_info["url"]; string username = this.cfg_info["username"]; string password = this.cfg_info["password"]; string item_id = this.cfg_info["item_id"]; if (string.isnullorempty(url) || string.isnullorempty(username) || string.isnullorempty(password) || string.isnullorempty(item_id)) { loghelper.put("配置信息不全,请检查config.cfg文件是否为空,然后再重启"); return; } if (this.driver == null) { string explorer = this.cfg_info["explorer"]; if (explorer == "chrome") { //谷歌浏览器 chromeoptions options = new chromeoptions(); this.driver = new chromedriver(options); } else { //默认ie var options = new internetexploreroptions(); //options.addadditionalcapability.('encoding=utf-8') //options.add_argument('accept= text / css, * / *') //options.add_argument('accept - language= zh - hans - cn, zh - hans;q = 0.5') //options.add_argument('accept - encoding= gzip, deflate') //options.add_argument('user-agent=mozilla/5.0 (windows nt 10.0; wow64; trident/7.0; rv:11.0) like gecko') //# 2. 定义浏览器驱动对象 this.driver = new internetexplorerdriver(options); } } this.run(url, username, password, item_id); } catch (exception e) { loghelper.put("运行过程中出错,请重新打开再试"+e.stacktrace); } } /// <summary> /// 运行 /// </summary> /// <param name="url"></param> /// <param name="username"></param> /// <param name="password"></param> /// <param name="item_id"></param> private void run(string url, string username, string password, string item_id) { //"""运行起来""" //# 3. 访问网站 this.driver.navigate().gotourl(url); //# 4. 最大化窗口 this.driver.manage().window.maximize(); if (this.checkisexists(by.linktext("账户登录"))) { //# 判断是否登录:未登录 this.login(username, password); } if (this.checkisexists(by.partiallinktext("欢迎回来"))) { //# 判断是否登录:已登录 loghelper.put("登录成功,下一步开始工作了"); this.working(item_id); } else { loghelper.put("登录失败,请设置账号密码"); } } /// <summary> /// 停止运行 /// </summary> public void stoprun() { //"""停止""" try { this.running = false; //# 如果驱动不为空,则关闭 //self.close_browser_nicely(self.__driver) if (this.driver != null) { this.driver.quit(); //# 关闭后切要为none,否则启动报错 this.driver = null; } } catch (exception e) { //print('stop failure') } finally { this.driver = null; } } private void login(string username, string password) { //# 5. 点击链接跳转到登录页面 this.driver.findelement(by.linktext("账户登录")).click(); //# 6. 输入账号密码 //# 判断是否加载完成 if (this.checkisexists(by.id("email"))) { this.driver.findelement(by.id("email")).sendkeys(username); this.driver.findelement(by.id("password")).sendkeys(password); //# 7. 点击登录按钮 this.driver.findelement(by.id("sign-in")).click(); } } /// <summary> /// 工作状态 /// </summary> /// <param name="item_id"></param> private void working(string item_id) { while (this.running) { try { //# 正常获取信息 if (this.checkisexists(by.id("string"))) { this.driver.findelement(by.id("string")).clear(); this.driver.findelement(by.id("string")).sendkeys(item_id); this.driver.findelement(by.id("string")).sendkeys(keys.enter); } //# 判断是否查询到商品 string xpath = "//div[@class=\"specialty-header search\"]/div[@class=\"specialty-description\"]/div[@class=\"gt-450\"]/span[2] "; if (this.checkisexists(by.xpath(xpath))) { int count = int.parse(this.driver.findelement(by.xpath(xpath)).text); if (count < 1) { thread.sleep(this.wait_sec); loghelper.put("没有查询到item id =" + item_id + "对应的信息"); continue; } } else { thread.sleep(this.wait_sec); loghelper.put("没有查询到item id2 =" + item_id + "对应的信息"); continue; } //# 判断当前库存是否有货 string xpath1 = "//div[@class=\"product-list\"]/div[@class=\"product\"]/div[@class=\"price-and-detail\"]/div[@class=\"price\"]/span[@class=\"nostock\"]"; if (this.checkisexists(by.xpath(xpath1))) { string txt = this.driver.findelement(by.xpath(xpath1)).text; if (txt == this.no_stock) { //# 当前无货 thread.sleep(this.wait_sec); loghelper.put("查询一次" + item_id + ",无货"); continue; } } //# 链接path1 string xpath2 = "//div[@class=\"product-list\"]/div[@class=\"product\"]/div[@class=\"imgdiv\"]/a"; //# 判断是否加载完毕 //# this.waiting((by.class_name, "imgdiv")) if (this.checkisexists(by.xpath(xpath2))) { this.driver.findelement(by.xpath(xpath2)).click(); thread.sleep(this.wait_sec); //# 加入购物车 if (this.checkisexists(by.classname("add-to-cart"))) { this.driver.findelement(by.classname("add-to-cart")).click(); loghelper.put("加入购物车成功,商品item-id:" + item_id); break; } else { loghelper.put("未找到加入购物车按钮"); } } else { loghelper.put("没有查询到,可能是商品编码不对,或者已下架"); } thread.sleep(this.wait_sec); } catch (exception e) { thread.sleep(this.wait_sec); loghelper.put(e); } } } /// <summary> /// 判断是否存在 /// </summary> /// <param name="by"></param> /// <returns></returns> private bool checkisexists(by by) { try { int i = 0; while (this.running && i < 3) { if (this.driver.findelements(by).count > 0) { break; } else { thread.sleep(this.wait_sec); i = i + 1; } } return this.driver.findelements(by).count > 0; } catch (exception e) { loghelper.put(e); return false; } } } }
关于日志帮助类,代码如下:
using system; using system.collections.generic; using system.linq; using system.text; using system.threading.tasks; using log4net; [assembly: log4net.config.xmlconfigurator(watch = true)] namespace aismoking.core { /// <summary> /// 日志帮助类 /// </summary> public static class loghelper { /// <summary> /// 日志实例 /// </summary> private static ilog loginstance = logmanager.getlogger("smoking"); private static queue<string> queue = new queue<string>(2000); public static void put(string msg) { queue.enqueue(msg); writelog(msg, loglevel.info); } public static void put(exception ex) { writelog(ex.stacktrace, loglevel.error); } public static string get() { if (queue.count > 0) { return queue.dequeue(); } else { return string.empty; } } public static void writelog(string message, loglevel level) { switch (level) { case loglevel.debug: loginstance.debug(message); break; case loglevel.error: loginstance.error(message); break; case loglevel.fatal: loginstance.fatal(message); break; case loglevel.info: loginstance.info(message); break; case loglevel.warn: loginstance.warn(message); break; default: loginstance.info(message); break; } } } public enum loglevel { debug = 0, error = 1, fatal = 2, info = 3, warn = 4 } }
作者:alan.hsiang
出处:http://www.cnblogs.com/hsiang/
以上就是c# 利用selenium实现浏览器自动化操作的示例代码的详细内容,更多关于c# 实现浏览器自动化操作的资料请关注其它相关文章!
推荐阅读
-
selenium+python实现基本自动化测试的示例代码
-
利用Selenium添加cookie实现自动登录的示例代码(fofa)
-
selenium python 实现基本自动化测试的示例代码
-
C# 利用Selenium实现浏览器自动化操作的示例代码
-
Node使用Selenium进行前端自动化操作的代码实现
-
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
-
C# 利用Selenium实现浏览器自动化操作的示例代码
-
selenium python 实现基本自动化测试的示例代码
-
利用Selenium添加cookie实现自动登录的示例代码(fofa)
-
selenium+python实现基本自动化测试的示例代码