C# Selenium WEB自动化工具的使用 -如何避免登录时总是要验证

使用Selenium

1、创建一个c#控制台程序

2、使用Nuget搜索以下依赖库,需要引用的核心库是Selenium.RC,Selenium.Support,Selenium.WebDriver

然后再需要引用 浏览器驱动库,这里我以IE浏览器为例,Chrome使用方式跟IE是一样的,程序包名称为Selenium.WebDriver.ChromeDriver。

3、在Main函数中输入以下代码

这里使用用了using(){},表示执行完{}里面的代码之后会自动释放括号内的代码资源。

 (用于连接数据库的多,这样的话就可以不用写代码去关闭数据库连接了)

static void Main(string[] args)
        {
            using (IWebDriver driver = new OpenQA.Selenium.IE.InternetExplorerDriver())
            {
                driver.Navigate().GoToUrl("http://www.baidu.com");  //driver.Url = "http://www.baidu.com"是一样的

                var source = driver.PageSource;

                Console.WriteLine(source);
            }
        }

运行,会弹出IE浏览器,网页加载完成后,浏览器会自动关闭。控制台输入结果如下

这样我们就可以轻松的获取动态渲染页面的源码。

基本用法:

通过id获取元素

1 //by id 
2 //<div id="cards"></div>
3 var byID = driver.FindElement(By.Id("cards")); 

通过类名获取元素

1 //by class name 
2 //<div class="menu"></div>
3 var byClassName = driver.FindElements(By.ClassName("menu")); 

通过标签名获取元素

1 //by tag name 
2 //<iframe></iframe>
3 var byTagName = driver.FindElement(By.TagName("iframe")); 

通过名字(name属性)获取元素

1 //by name
2 //<div name="__VIEWSTATE"></DIV>
3 var byName = driver.FindElement(By.Name("__VIEWSTATE")); 

通过链接文本获取元素

1 //by linked text  
2 //<a href="http://www.google.com">linkedtext</a>>  
3 var byLinkText = driver.FindElement(By.LinkText("linkedtext")); 

通过部分链接文本获取元素

1 //是模糊查找。比如百度网页中的关于 参数写“关”就可以了,不用写*这种符号
2 //<a href="http://www.google.com">linkedtext</a>>
3 var byPartialLinkText = driver.FindElement(By.PartialLinkText("text")); 

通过CSS选择器获取元素

通过CSS选择器获取元素 

1 //by css
2 var byCss = driver.FindElement(By.CssSelector("#header .content .logo")); 

通过XPath来获取元素

通过XPath来获取元素 

1  //by xpath
2  var byXPath = driver.FindElements(By.XPath("//div"));

在浏览器上打开开发者工具,然后点击要查看xpath的元素

点击后会自动定位到元素代码,选中右键 -->点击Copy,复制需要的相应内容,我这里用的谷歌,不同浏览器可能复制xpath的位置会不同

模拟鼠标点击元素

1 driver.FindElement(By.Id("copyright")).Click();
2 或者
3 IWebElement eles = driver.FindElement(By.LinkText("关于百度"));
4 Actions actionsObj = new Actions(driver);
5 actionsObj.Click(eles).Perform();

鼠标双击控件

1 IWebElement eles=driver.FindElement(By.Id("id"));

2 Actions actionsObj = new Actions(driver);

3 actionsObj.DoubleClick(eles).Perform();

鼠标单击拖动

下面的代码演示的是从第1个控件单击并拖动至第4个控件,并选中这4个控件,如下所示(点击长按 -->拖动 --> 松手 )

driver.Url = "http://www.jqueryui.org.cn/demo/5640.html";
Thread.Sleep(1000);
driver.Manage().Window.Maximize();
ReadOnlyCollection<IWebElement> items = driver.FindElements(By.XPath("//ol[@id='selectable']/li"));
Assert.AreEqual<int>(7, items.Count);
Actions actionsObj = new Actions(driver);
actionsObj.ClickAndHold(items[0]).ClickAndHold(items[4]).Release().Perform();

移动鼠标到指定控件

1 IWebElement eles=driver.FindElement(By.Id("id"));
2 Actions actionsObj = new Actions(driver);
3 actionsObj.MoveToElement(eles).Perform(); 

鼠标拖放

拖放操作因操作简单易懂,在Web页面中应用也越来越广,特别是一些银行页面中。以下代码演示如何通过Selenium API来完成操作

1、方法一:通过方法DragAndDrop()实现

driver.Url = "http://www.jqueryui.org.cn/demo/5622.html";

Thread.Sleep(1000);

driver.Manage().Window.Maximize();

IWebElement soureEle = driver.FindElement(By.Id("draggable"));

IWebElement targetEle = driver.FindElement(By.Id("droppable"));

Actions actionObj = new Actions(driver);

actionObj.DragAndDrop(soureEle, targetEle).Perform();

IWebElement textEle = driver.FindElement(By.XPath("//div[@id='droppable']/p"));

Assert.IsTrue(textEle.Text.Contains("Dropped!"));

2、方法二:通过方法MoveToElement()实现

driver.Url = "http://www.jqueryui.org.cn/demo/5622.html";

Thread.Sleep(1000);

driver.Manage().Window.Maximize();

IWebElement soureEle = driver.FindElement(By.Id("draggable"));

IWebElement targetEle = driver.FindElement(By.Id("droppable"));

Actions actionObj = new Actions(driver);

actionObj.ClickAndHold(soureEle).MoveToElement(targetEle).Release(targetEle).Perform();

IWebElement textEle = driver.FindElement(By.XPath("//div[@id='droppable']/p"));

Assert.IsTrue(textEle.Text.Contains("Dropped!"));

3、方法三:通过方法MoveByOffset()实现

driver.Url = "http://www.jqueryui.org.cn/demo/5622.html";

Thread.Sleep(1000);

driver.Manage().Window.Maximize();

IWebElement soureEle = driver.FindElement(By.Id("draggable"));

IWebElement targetEle = driver.FindElement(By.Id("droppable"));

Actions actionObj = new Actions(driver);

actionObj.ClickAndHold(soureEle).MoveByOffset(100, 0).Perform();

IWebElement textEle = driver.FindElement(By.XPath("//div[@id='droppable']/p"));

Assert.IsTrue(textEle.Text.Contains("Dropped!"));

拖动进度条或滑块

driver.Url = "http://demo.lanrenzhijia.com/2015/drag1218/";

Thread.Sleep(1000);

driver.Manage().Window.Maximize();

IWebElement origianlValueEle = driver.FindElement(By.Id("title"));

Assert.AreEqual("0", origianlValueEle.Text);

IWebElement sliderEle = driver.FindElement(By.Id("btn"));

Actions actionsObj = new Actions(driver);

actionsObj.DragAndDropToOffset(sliderEle, 100, 0).Perform();

Assert.AreEqual("51%", origianlValueEle.Text);

单击鼠标右键菜单

这种情况Selenium API提供一种方法ContextClick()方法

driver.Url = "http://www.helloweba.com/demo/2017/basicContext/";

Thread.Sleep(1000);

driver.Manage().Window.Maximize();

IWebElement btnEle = driver.FindElement(By.XPath("//button[contains(@class,'btn-success context')]"));

Actions actionsObj = new Actions(driver);

actionsObj.ContextClick(btnEle).Perform();//点击右键菜单

IWebElement rightMenu = driver.FindElement(By.XPath("//div[@class='basicContext']/table/tbody/tr[2]"));

rightMenu.Click();//选择菜单

IAlert alert = driver.SwitchTo().Alert();

string alertText = alert.Text;

alert.Accept();

Assert.AreEqual<string>("Item clicked!",alertText);

弹框处理

类似下图所示的警告框,无法通过前端工具定位,需要跳转到弹框,然后再对其操作

  3种弹框:

  •   警告类弹框,Alert():一个按钮

  •   确认类弹框,Confirmation:一个确认,一个取消

  •   消息类弹框,Prompt:一个输入框, 一个确认,一个取消

  跳转到弹框:

  •   SwitchTo().Alert()

  常用的弹框处理方法:

  •   Text 获取警告框的内容

  •   Accept() 相当于点击确认按钮

  •   Dismiss() 相当于点击取消按钮

  •   SendKeys() 向警告框输入值

1 IAlert alert = driver.SwitchTo().Alert();//获取警告框
2 string alertText = alert.Text;//获取警告框中的内容
3 alert .Accept();//接受(确认) 

执行JS

1 //execute javascript
2 var jsReturnValue = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript("jsfunname");

当点击的元素包含href跳转的时候可以使用JavaScript来进行点击操作

(IJavaScriptExecutor)driver.ExecuteScript("arguments[0].click();", 
driver.FindElement(By.XPath("/html/body/div[2]/div/div[2]/div[2]/div[1]/h3/a"))); 

获取元素的值和属性

3 var byIDText = byID.Text; 
4 var byIDAttributeText = byID.GetAttribute("id");

页面导航

//Navigation()方法 摘要:指示驱动程序将将来的命令发送到不同的框架或窗口。说明:就是对对象进行进一些基本操作,比如刷新,打开,回退,向前
driver.Navigate().Forward(); //向前
driver.Navigate().Back();  //返回4 driver.Navigate().Refrsh();//刷新当前打开的页面5 driver.Close();//关闭当前选中的浏览器窗口,如果是最后一个窗口就退出浏览器6 driver.Quit();//退出,关闭测试其对象,也会退出所有关联的窗口 7 driver.Manage().Window.Maximize();//浏览器最大化  8 .GoToUrl(Uri url)和 GoToUrl(string Url) //打开链接,在Navigate()方法后调用,将对象定位到指定的URL中去。如果是第一次调用,新打开一个浏览器窗体。和Open()方法一样

模拟键盘 SendKeys.SendWait()用法

1 SendKeys.SendWait("{F5}");          //发送F5按键
 2 SendKeys.SendWait("^s");       //发送 Ctrl + s 键
 3 SendKeys.SendWait("%{F4}");      // 发送 Alt + F4 键
 4 
 5 //按键 代码
 6 //BACKSPACE {BACKSPACE}, {BS}, 或 {BKSP} 
 7 //BREAK {BREAK} 
 8 //CAPS LOCK {CAPSLOCK} 
 9 //DEL or DELETE {DELETE} 或 {DEL} 
10 // DOWN ARROW {DOWN} 
11 //END {END} 
12 //ENTER  {ENTER}或 ~ 
13 //ESC {ESC} 
14 //HELP {HELP} 
15 //HOME {HOME} 
16 //INS or INSERT {INSERT} 或 {INS} 
17 //LEFT ARROW {LEFT} 
18 //NUM LOCK {NUMLOCK} 
19 //PAGE DOWN {PGDN} 
20 //PAGE UP {PGUP} 
21 //PRINT SCREEN {PRTSC} 
22 //RIGHT ARROW {RIGHT} 
23 
24 //为了指定重复键,使用 {key number} 的形式。必须在 key 与 number 之间放置一个空格。例如,{LEFT 42} 意指 42 次按下 
25 //LEFT ARROW 键;{h 10} 则是指 10 次按下 H 键。
//为弹出windows文件选择框写入地址                Thread.Sleep(1000);                SendKeys.SendWait(@path);//path是传入的路径                Thread.Sleep(1000);                SendKeys.SendWait(@"{Enter}");

获取table中tr的数据

1  var ssoTr = driver.FindElement(By.XPath("/html/body/div[2]/div/div[2]/div[2]/div[3]/div[1]/table/tbody")).FindElements(By.TagName("tr"));
2  var toDayTr = ssoTr.Where(x => x.Text.Contains(DateTime.Now.ToString("yyyy-MM-dd"))).ToList();

iFrame的切换

//如果要取的元素显示报错找不到,其中一个原因可能是被iframe标签包裹住了,这个时候就要切换到iframe中,然后再取元素。

//注意,切换到iframe中就不可以继续操作主文档中的元素,如果要操作主文档的元素就需要切回到主文档

var iframe = driver.FindElement(By.Id("login-iframe-2019"));//找到ifram元素

driver.SwitchTo().Frame(iframe);//切换到ifram

driver.switch_to.default_content();//切回主文档

嵌套的iFrame操作

1 <html>
2     <iframe id="frame1">
3         <iframe id="frame2" / >
4     </iframe>
5 </html>
//从主文档切到frame2,一层层切进去
  driver.SwitchTo().Frame("rame1)
  driver.SwitchTo().Frame("rame2)
//从frame2再切回frame1,这里selenium给我们提供了一个方法能够从子frame切回到父frame,而不用我们切回主文档再切进来。
  driver.SwitchTo().ParentFrame()  // 如果当前已是主文档,则无效果

//补充:之前曾看到过用点分法来切入嵌套frame的方法,但我没有试过不知道额能否成功
//切到 “frame1” 下的 “第一个frame” 下的 “frame3” 中。
  driver.SwitchTo().Frame("frame1.0.frame1");

鼠标滚动

IJavaScriptExecutor js = (IJavaScriptExecutor)driver;

js.ExecuteScript("window.scrollTo(0,100)");//滚动鼠标位置到100
js.ExecuteScript("window.scrollTo(0,0)");//滚动鼠标至顶部
js.ExecuteScript("window.scrollTo(0,document.body.scrollHeight)'");//滚动鼠标至底部-这个我用报错了,暂时还没研究是啥问题 知道的小伙伴可以留言告诉我~

避免登录时总是需要手机号验证

Selenium启动浏览器时,默认是打开一个新用户,不会加载原有的配置以及插件,所以每次都需要登录,有的可能识别出时自动而是软件还会需要手机号验证码。

两种解决办法(我这里以谷歌浏览器为例):

1、加载浏览器配置文件(我试了这个方法没有效果,有尝试成功过的欢迎分享~)

  ①打开谷歌浏览器,输入chrome://version/,得到个人资料路径地址

②这里打开阿里云,但是打开之后还是需要输入账号密码登录,没有加载浏览器配置文件,百度到有人说登录进入之后就不需要再次登录了,但是我试过没有效果(执行脚本时需要关掉谷歌浏览器,不然可能会报错)

1 var option = new ChromeOptions();
2 option.AddArgument(@"个人资料路径地址,地址截取到User Data 即可,路径后面的Default不需要,不然还是打开一个新用户");
3 driver = new ChromeDriver(option);
4 driver.Url = "https://account.aliyun.com/login/login.htm?spm=5176.19720258.J_8058803260.35.e9392c4aykXZ6w&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F"; 

还有一种方式,打开时指定chrome驱动

  ①右键谷歌 ---》 属性,复制起始位置中的地址

  

  ②配置本地谷歌环境变量;

   此电脑 --》 右键属性 --》点击高级系统设置 --》环境变量 --》选中Path,点击编辑 --》点击新建,将刚刚复制的路径粘贴上去一路点击确认下来即可

   最后打开刚刚复制的路径,将下载的谷歌驱动 chromedriver.exe粘贴

  

  

  

  

  

var option = new ChromeOptions();

option.AddArgument(@"个人资料路径地址,地址截取到User Data 即可,路径后面的Default不需要,不然还是打开一个新用户");

driver = new ChromeDriver(@"C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe", option);

driver.Url = "https://account.aliyun.com/login/login.htm?spm=5176.19720258.J_8058803260.35.e9392c4aykXZ6w&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F";

这里我一直报C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe路径不存在,但是这个是有的

var option = new ChromeOptions();
            option.AddArgument(@"个人资料路径地址,地址截取到User Data 即可,路径后面的Default不需要,不然还是打开一个新用户");
            driver = new ChromeDriver(@"C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe", option);
            driver.Url = "https://account.aliyun.com/login/login.htm?spm=5176.19720258.J_8058803260.35.e9392c4aykXZ6w&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F";

2、使用Debug方式启动浏览器,使用Selenium连接到一个已打开的浏览器

chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\selenum\AutomationProfile

// chrome:表示启动chrome浏览器
// remote-debugging-port:表示执行浏览器端口
// 9222为个人设置的端口
// --user-data-dir="C:\selenum\AutomationProfile":表示新建一个浏览器配置信息,地址自己定义
//先打开一个网页或者直接win+r打开cmd,输入命令行chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\selenum\AutomationProfile",端口号可以自己定义;
Process proc = new Process();
proc.StartInfo.FileName = @"C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe";
proc.StartInfo.Arguments = "https://vod.console.aliyun.com/?spm=5176.12818093.ProductAndService--ali--widget-home-product-recent.dre0.419916d0LZyB0A#/media/video/list --new-window --remote-debugging-port=9222 --user-data-dir=E:\\selenum"; proc.Start();

//将selenium连接到已经打开的浏览器,创建WebDriver并将浏览器的连接地址和端口作为参数传递给WebDriver
ChromeOptions options = new ChromeOptions();
options.DebuggerAddress = "127.0.0.1:9222";
driver = new ChromeDriver(options);

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值