溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#如何使用selenium實現爬蟲

發(fā)布時間:2022-06-08 13:47:13 來源:億速云 閱讀:440 作者:iii 欄目:開發(fā)技術

本文小編為大家詳細介紹“C#如何使用selenium實現爬蟲”,內容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“C#如何使用selenium實現爬蟲”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

    一、介紹:

    Selenium 是一個用于Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。

    1、Selenium Webdriver(也就是Selenium2,Selenium3)和Selenium RCSelenium 1)一樣提供了web自動化的各種語言調用接口庫。相比Selenium RC,Selenium WebDriver的編程接口更加直觀易懂,也更加簡練。

    但是和Selenium RC不同的是,Selenium Webdriver是通過各種瀏覽器的驅動(web driver)來驅動瀏覽器的,而不是通過注入JavaScript的方式。

    我們的代碼運行起來是一個進程,里面調用Selenium WebDriver的庫和各個瀏覽器的驅動進程 進行交互,傳遞Selenium命令 給它們,并且獲取命令執(zhí)行的結果,返回給我們的代碼進行處理。

    2、Selenium WebDriver目前包括兩個版本Selenium 2Selenium 3。這兩個版本從開發(fā)代碼調用接口上來看,幾乎沒什么區(qū)別。區(qū)別在于庫的實現和web driver的實現。

    Selenium2Selenium組織幫各種瀏覽器寫web driver的,而Selenium 3里面的web driver是由各個瀏覽器廠商(Apple,Google,Microsoft,Mozilla)自己提供的。所以Selenium 3的自動化效率更高,成功率也更高。

    3、Selenium WebDriver 支持瀏覽器眾多:

    • Google Chrome

    • Microsoft Internet Explorer 7,8,9,10,11在 Windows Vista,Windows 7,Windows 8,Windows 8.1.

    • Microsoft Edge

    • Firefox

    • Safari

    • Opera

    利用它可以驅動瀏覽器執(zhí)行特定的動作,如點擊、下拉等操作,同時還可以獲取瀏覽器當前呈現的頁面的源代碼 ,做到可見即可爬。

    所以Selenium現在被廣泛用于Python爬蟲。查了下資料,發(fā)現這個工具確實強大,最重要的是,C#也是可以調用的。

    官方支持Java,C#,Python,Ruby,PHP,Perl,Javascript等語言

    官方文檔(有C#示例):https://www.selenium.dev/documentation/en/

    安裝Selenium:

    1、我們新建一個C#控制臺程序

    2、使用Nuget搜索以下依賴庫

    需要引用的核心庫是Selenium.RC,Selenium.Support,Selenium.WebDriver

    然后再需要引用瀏覽器驅動庫,這里我以新版Edge瀏覽器為例,新版Edge使用方式跟Chrome是一樣的,程序包名稱為Selenium.WebDriver.MSEdgeDriver。

    C#如何使用selenium實現爬蟲

    備注:也可以在微軟WebDriver官網下載Edge (Chromium)的webdriver,需要和當前瀏覽器版本一致。然后下載放置到項目可執(zhí)行文件的目錄。

    如果使用Chrome:

    先查下本機Chrome的版本

    C#如何使用selenium實現爬蟲

    然后去Nuget搜索Selenium.WebDriver.ChromeDriver進行下載安裝。

    注意:webdriver版本只需要和當前瀏覽器主版本一致即可。

    C#如何使用selenium實現爬蟲

    3、在Main函數中輸入以下代碼

    using OpenQA.Selenium;
    using OpenQA.Selenium.Edge;
    using System;
    using System.Windows.Forms;
    
    namespace WinForm2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                var service = EdgeDriverService.CreateDefaultService(@".", "msedgedriver.exe");
                using (IWebDriver driver = new OpenQA.Selenium.Edge.EdgeDriver(service))
                {
                    driver.Navigate().GoToUrl("http://www.baidu.com");  //driver.Url = "http://www.baidu.com"是一樣的
                    var source = driver.PageSource;
                    this.textBox1.Text = source;
                }
            }
        }
    }

    如果是Chrome瀏覽器,可以這樣:

    IWebDriver driver = new OpenQA.Selenium.Chrome.ChromeDriver();
    driver.Navigate().GoToUrl("http://www.baidu.com");

    運行,會彈出IE瀏覽器,網頁加載完成后,瀏覽器會自動關閉??刂婆_輸入結果如下

    C#如何使用selenium實現爬蟲

    這樣我們就可以輕松的獲取動態(tài)渲染頁面的源碼。

    二、等待

    常用的等待分為顯示等待WebDriverWait()、隱式等待ImplicitlyWait()、強制等待sleep()三種,下面我們就分別介紹一下這三種等待的區(qū)別

    • Sleep(): 強制等待,設置固定休眠時間。

    • ImplicitlyWait():隱式等待,也叫智能等待,是 webdirver 提供的一個超時等待。隱的等待一個元素被發(fā)現,或一個命令完成。如果超出了設置時間的則拋出異常。

    • WebDriverWait():顯示等待,同樣也是 webdirver 提供的方法。在設置時間內,默認每隔一段時間檢測一次當前頁面元素是否存在,如果超過設置時間檢測不到則拋出異常。默認檢測頻率為0.5s,默認拋出異常為:NoSuchElementException

    1、隱式等待:ImplicitlyWait

    用到Timeouts對象。這個對象是用來對設置器進行一些設置的。

    • ImplicitlyWait:設置腳步在查找(定位)元素時最大的超時時間。如FindElement()方法在一些超大網頁中進行定位時的超時時間。

    • PageLoad:設置頁面操作超時時間(不是頁面加載時間)。是在頁面進行跳轉操作或刷新操作時的等待時間。如Navigation對象的各種操作方法,以及在頁面上進行某種操作后的等待時間。

    • AsynchronousJavaScript: 設置腳步異步執(zhí)行的超時時間。

    代碼如下:

    driver.Navigate().GoToUrl("http://www.baidu.com");
    ITimeouts timeouts = driver.Manage().Timeouts();
    
    //設置查找元素最大超時時間為30秒
    timeouts.ImplicitWait = new TimeSpan(0, 0, 30);
    //設置頁面操作最大超時時間為30秒
    timeouts.PageLoad = new TimeSpan(0, 0, 30);
    //設置腳本異步最大超時時間為30秒
    timeouts.AsynchronousJavaScript = new TimeSpan(0, 0, 30);

    2、顯示等待:WebDriverWait()

    //等待頁面元素加載完成
    //默認等待100秒
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(100));
    //等待頁面上ID屬性值為submitButton的元素加載完成
    IWebElement myElement = wait.Until((d) =>
    {
        return d.FindElement(By.Id("submitButton"));
    });

    三、查找(定位對象)

    通過FindElement()這個方法來查找的。然后把參數傳遞過去。

    driver.FindElement(By.Id ("kw")).SendKeys("搜索關鍵字");
    driver.FindElement(By.Id( "su")).Click();

    其中By.id("su")就是定位參數,傳遞一個對象過去。有8種定位方式。

    注意:其中PartialLinkText是模糊查找。比如百度網頁中的關于 參數寫“關”就可以了,不用寫*這種符號。

    //通過ID獲取元素
    var byID = driver.FindElement(By.Id("cards"));
    
    //通過類名獲取元素by class name
    var byClassName = driver.FindElements(By.ClassName("menu"));
    
    // 通過標簽名獲取元素by tag name 
    var byTagName = driver.FindElement(By.TagName("iframe"));
    
    // 通過名字獲取元素
    var byName = driver.FindElement(By.Name("__VIEWSTATE"));
    
    // 通過鏈接文本獲取元素by linked text  <a href="https://www.cnblogs.com/springsnow/p/%3C/span%3E%3Cspan%20external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"   target="_blank">http://www.google.com</a><a href="https://www.cnblogs.com/springsnow/p/%3C/span%3E%3Cspan%20external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"   target="_blank">">linkedtext</a>>  
    var byLinkText = driver.FindElement(By.LinkText("linkedtext"));
    
    // 通過部分鏈接文本獲取元素by partial link text  :<a href="https://www.cnblogs.com/springsnow/p/%3C/span%3E%3Cspan%20external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"   target="_blank">http://www.google.com</a><a href="https://www.cnblogs.com/springsnow/p/%3C/span%3E%3Cspan%20external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"   target="_blank">">linkedtext</a>>
    var byPartialLinkText = driver.FindElement(By.PartialLinkText("text"));
    
    //通過CSS選擇器獲取元素by css
    var byCss = driver.FindElement(By.CssSelector("#header .content .logo"));
    
    //  通過XPath來獲取元素(by xpath
    var byXPath = driver.FindElements(By.XPath("//div"));

    各方法使用優(yōu)先原則:

    優(yōu)先使用id,name,classname,link;次之使用CssSelector();最后使用Xpath();

    因為Xpath()方法的性能和效率最低下。

    四、獲取頁面元素和元素內容

    1.Title:標題

    Console.WriteLine(driver.Title);//輸出標題名

    2.Url:鏈接

    Console.WriteLine(driver.Url);//輸出鏈接

    3.Text:元素的文本值

    Console.WriteLine(web.Text);//輸出元素標記中文本的信息

    4.Selected勾選情況、TagName標記名標、Enabled編輯狀態(tài)、Displayed顯示狀態(tài)

    5.GetAttribute()獲取標簽的屬性

    var byIDAttributeText = byID.GetAttribute("id");

    6.彈出對話框的處理

    首先,要先了解三種對話框:Alert、Confirmation以及Prompt。測試網頁test.html:

    <html>
        <head>
             <title>這是標題</title>
         </head>
    
        <body>
             <input type="button" onclick="alert('這是Alert');" value="Alert" /><br/>
             <input type="button" onclick="confirm('這是confirm');" value="confirm" /><br/>
             <input type="button" onclick="prompt('這是Prompt');" value="prompt" /><br/>
         </body>
    
    
     </html>

    下面進行測試:

    var service = EdgeDriverService.CreateDefaultService(@".", "msedgedriver.exe");
    IWebDriver driver = new OpenQA.Selenium.Edge.EdgeDriver(service);
    
    driver.Navigate().GoToUrl("file:///C:/Users/bobin.yang/Source/Repos/WinForm2/bin/Debug/HTMLPage1.html");
    
    IWebElement web = driver.FindElement(By.XPath("//input[1]"));
    web.Click();
    
    
    WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,2));
     //Wait for the alert to be displayed
     wait.Until(ExpectedConditions.AlertIsPresent());
    
    Console.WriteLine(driver.SwitchTo().Alert().Text);//在接收消息前輸出
    System.Threading.Thread.Sleep(1000);
    driver.SwitchTo().Alert().Accept();
    
    
    IWebElement web2 = driver.FindElement(By.XPath("//input[2]"));
    web2.Click();
    WebDriverWait wait2 = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    wait2.Until(ExpectedConditions.AlertIsPresent());
    Console.WriteLine(driver.SwitchTo().Alert().Text);//在接收消息前輸出
    System.Threading.Thread.Sleep(1000);
    driver.SwitchTo().Alert().Accept();
    
    
    IWebElement web3 = driver.FindElement(By.XPath(@"html/body/input[3]"));
    web3.Click();
    System.Threading.Thread.Sleep(1000);
    Console.WriteLine(driver.SwitchTo().Alert().Text);//在接收消息前輸出
    driver.SwitchTo().Alert().SendKeys("這是輸入的內容");
    driver.SwitchTo().Alert().Accept();

    五、操作元素對象WebElement

    主要是進行Click和SendKeys操作,如圖。其它的自己查看定義就知道了。 

    C#如何使用selenium實現爬蟲

    1、模擬鼠標點擊元素

    driver.FindElement(By.Id("copyright")).Click();
    • SenKeys就是在定位到輸入框后,把參數text賦值進去

    • Click就是進行鼠標點擊操作,比如點擊按鈕等。和IDE上一樣的。單選、復選都是通過這個方法這點擊的。

    • Clear方法:是用于清空輸入框的值,和SendKeys正好的作用正好相反。自己測試時,建議先給輸入框賦值,再用Thread.Sleep(3000)來暫停一下,再用Clear方法,不然你還沒看到效果時,程序已經完成了。

    • Submit:特殊之處在于,當定位的是Form表單中任何一個元素,當操作完之后,直接調用那個Submit方法就能對整個Form表單完成提交。不用再返回重新查找表單元素。

    Selenium中在指定的文本框中輸入指定的字符串

    //在文本框中輸入指定的字符串sendkeys()
    Driver.FindElement(By.Id("tranAmtText")).SendKeys(“123456”);

    2、下拉列表框Select的操作

    driver.Navigate().GoToUrl("http://tieba.baidu.com/f/search/adv");
    IList listOption = driver.FindElement(By.Name("sm")).FindElements(By.TagName("option"));
    string targetStr = "按相關性排序";
    
    foreach (var option in listOption)
    {
        if (option.Text == targetStr)  // if (option.GetAttribute("value").Equals(targetStr))
            option.Click();
    }

    3、執(zhí)行JS

    var jsReturnValue = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript("jsfunname");

    4、頁面導航

    driver.Navigate().Forward();
    driver.Navigate().Back();

    Selenium中移動光標到指定的元素上

    //移動光標到指定的元素上perform
    Actions action=new Actions(driver);
    action.MoveToElement(Find(By.XPath("//input[@id='submit' and @value='確定']"))).Perform();

    5、拖拽操作(可以實現滑動驗證碼的驗證)

    var element = driver.FindElement(By.Name("source"));
    IWebElement target = driver.FindElement(By.Name("target"));
    (new Actions(driver)).DragAndDrop(element, target).Perform();

    6、模擬鼠標晃動

    //模擬光標晃動movebyoffset()
    Actions action = new Actions(driver);
    action.MoveByOffset(2, 4);

    7、截圖功能

    //WebDriver中自帶截圖功能
    Screenshot screenShotFile = ((ITakesScreenshot)driver).GetScreenshot();
    screenShotFile.SaveAsFile("test", ImageFormat.Jpeg);

    8、selenium操作滾輪滑動到底部

    driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")

    六、獲得窗口標識WindowHandles

    要在不同的瀏覽器窗口之間切換,必須獲得不同的窗口(標簽)的標識符。用一個集合來保存這些數據。當需要到新窗口里進行操作時,需要將測試器前往新的窗口。開始創(chuàng)建的測試器是對窗口來的,所以當我們需要切換窗口時。需要調用 測試器.SwitchTo().window(獲得標識) 這個方法來返回一個新的測試器對象。新的對象是代表的是切換的窗口。代碼如下:

    var service = EdgeDriverService.CreateDefaultService(@".", "msedgedriver.exe");
    IWebDriver driver = new OpenQA.Selenium.Edge.EdgeDriver(service);
    
    driver.Navigate().GoToUrl("http://tieba.baidu.com/f/search/adv");
    //找到注冊元素
    IWebElement register = driver.FindElement(By.XPath(@".//*[@id='com_userbar']/ul/li[5]/div/a"));
    register.Click();
    
    //顯示所有標識
    IList<string> listHand = driver.WindowHandles;//拿到所有標識
    foreach (string item in listHand)
    {
        Console.WriteLine(item);
    }
    
    /*這里一會插入代碼*/
    
    Console.ReadKey();
    driver.Quit();

    效果如下:

    C#如何使用selenium實現爬蟲

    下面切換到新打開的窗口后,輸入一個12345來表示我們成功了 
    在上面的代碼基礎下 添加下面代碼

    //切換到注冊窗口再輸入12345
    driver.SwitchTo().Window(listHand[1]);
    driver.FindElement(By.Name("userName")).SendKeys("12345");

    結果如圖:

    C#如何使用selenium實現爬蟲

    1、關閉多個子Browser窗口

    //獲取所有的WindowHandle,關閉所有子窗口
    string oldwin = driver.CurrentWindowHandle;
    ReadOnlyCollection<string> windows = driver.WindowHandles;
    foreach (var win in windows)
    {
        if (win != oldwin)
        {
            driver.SwitchTo().Window(win).Close();
        }
    }
    driver.SwitchTo().Window(oldwin);

    2、對iframe中元素的定位

    1、切換焦點到id為固定值的iframe上

    進入頁面后,光標默認焦點在DefaultContent中,若想要定位到iframe 需要轉換焦點

    driver.SwitchTo().DefaultContent();
    //切換焦點到mainFrame
    driver.SwitchTo().Frame("mainFrame");

    需要注意的是:切換焦點之后若想切換焦點到其他iframe上 需要先返回到defaultcontent,再切換焦點到指定的iframe上。

    2、切換焦點到id值為動態(tài)值的iframe上

    有時候 頁面上浮出層的id為動態(tài)值,此時需要先獲取所有符合記錄的iframe放置在數組中,然后遍歷數組切換焦點到目標iframe上。

    如下方法:

    protected string bizFrameId = string.Empty;
    protected string bizId = string.Empty;
    //獲取動態(tài)iframe的id值
    protected void SetIframeId()
    {
        ReadOnlyCollection els = driver.FindElements(By.TagName("iframe"));
        foreach (var e in driver.FindElements(By.TagName("iframe")))
        {
            string s1 = e.GetAttribute("id");
            if (s1.IndexOf("window") >= 0 && s1.IndexOf("content") >= 0)
            {
                bizFrameId = e.GetAttribute("id");
                string[] ss = s1.Split(new char[] { '_' });
                bizId = ss[1];
            }
        }
    }

    七、Cookies

    在C#中,通過Cookies屬性來獲取當前的Cookie集合,然后進行增刪改查操作。

    Cookie由5個部分組成:名稱、值、所在域、路徑和過期時間。

    下面我們進入百度首頁,然后獲取cookie,并讓它變動一下來看到效果。 代碼如下:

    var service = EdgeDriverService.CreateDefaultService(@".", "msedgedriver.exe");
    IWebDriver driver = new OpenQA.Selenium.Edge.EdgeDriver(service);
    
    driver.Navigate().GoToUrl("http://www.baidu.com");
    
    
    //獲取Cookie
    ICookieJar listCookie = driver.Manage().Cookies;
    // IList listCookie = driver.Manage( ).Cookies.AllCookies;//只是顯示 可以用Ilist對象
    //顯示初始Cookie的內容
    Console.WriteLine("--------------------");
    Console.WriteLine($"當前Cookie集合的數量:\t{listCookie.AllCookies.Count}");
    for (int i = 0; i < listCookie.AllCookies.Count; i++)
    {
    
        Console.WriteLine($"Cookie的名稱:{listCookie.AllCookies[i].Name}");
        Console.WriteLine($"Cookie的值:{listCookie.AllCookies[i].Value}");
        Console.WriteLine($"Cookie的所在域:{listCookie.AllCookies[i].Domain}");
        Console.WriteLine($"Cookie的路徑:{listCookie.AllCookies[i].Path}");
        Console.WriteLine($"Cookie的過期時間:{listCookie.AllCookies[i].Expiry}");
        Console.WriteLine("-----");
    }
    
    
    //添加一個新的Cookie
    Cookie newCookie = new Cookie("新Cookie", "新值", "", DateTime.Now.AddDays(1));
    
    listCookie.AddCookie(newCookie);
    Console.WriteLine("--------------------");
    Console.WriteLine($"當前Cookie集合的數量:\t{listCookie.AllCookies.Count}");
    for (int i = 0; i < listCookie.AllCookies.Count; i++)
    {
    
        Console.WriteLine($"Cookie的名稱:{listCookie.AllCookies[i].Name}");
        Console.WriteLine($"Cookie的值:{listCookie.AllCookies[i].Value}");
        Console.WriteLine($"Cookie的所在域:{listCookie.AllCookies[i].Domain}");
        Console.WriteLine($"Cookie的路徑:{listCookie.AllCookies[i].Path}");
        Console.WriteLine($"Cookie的過期時間:{listCookie.AllCookies[i].Expiry}");
        Console.WriteLine("-----");
    }
    
    //刪除這個Cookie并再次顯示總數
    listCookie.DeleteCookieNamed(newCookie.Name);
    
    Console.WriteLine($"當前Cookie集合的數量:\t{listCookie.AllCookies.Count}");
    
    
    Console.ReadLine();
    driver.Quit();

    運行效果如下:

    C#如何使用selenium實現爬蟲

    八、Window窗口控制

    這個屬性是可以對當前的窗口進行簡單的控制。如獲取坐標和大小,還可以將其最大化。下面我們用過示例代碼來試試效果。 
    下面的代碼是先打開網頁,打印坐標和大小,再控制它最大化,再次打印坐標和大小。

    var service = EdgeDriverService.CreateDefaultService(@".", "msedgedriver.exe");
    IWebDriver driver = new OpenQA.Selenium.Edge.EdgeDriver(service);
    
    driver.Navigate().GoToUrl("http://www.baidu.com");
    
    //打印現在的坐標和大小
    IWindow window = driver.Manage().Window;
    Console.WriteLine("第一次打印");
    Console.WriteLine($"坐標X為{window.Position.X}\tY為{window.Position.Y}");
    Console.WriteLine($"大小長為{window.Size.Width}\t寬為{window.Size.Height}");
    Console.WriteLine("-------------");
    
    //控制最大化
    window.Maximize();
    
    //再次打印數據
    Console.WriteLine("第二次打印");
    Console.WriteLine($"坐標X為{window.Position.X}\tY為{window.Position.Y}");
    Console.WriteLine($"大小長為{window.Size.Width}\t寬為{window.Size.Height}");
    Console.WriteLine("-------------");
    
    Console.ReadLine();
    driver.Quit();

    效果如下:

    C#如何使用selenium實現爬蟲

    這里有兩個奇怪的地方:
    1.我的屏幕是1080P的,輸出后的數據中,長只有1936.如果減去16的話到正好是1920.但是寬應該是1080,如果任務欄的寬度是24的話,到也能說得過去。只是數據和我們要的有點偏差,這里需要注意一下。
    2.window屬性居然只有位置、大小和最大化方法。居然沒有最小化或還原(退出最大化狀態(tài))方法。

    九、事件

    首先是準備好要添加的事件,然后再掛接。這里可以使用C#的語法糖。在+=后面直接按兩次tab鍵,然后再移動到事件區(qū)編輯。

    eventDriver.Navigating += EventDriver_Navigating;//導航前
    eventDriver.Navigated += EventDriver_Navigated;//導航后
    eventDriver.FindingElement += EventDriver_FindingElement;//查找元素前
    eventDriver.FindElementCompleted += EventDriver_FindElementCompleted;//查找元素后
    eventDriver.ElementClicking += EventDriver_ElementClicking;//元素單擊前
    eventDriver.ElementClicked += EventDriver_ElementClicked;//元素單擊后
    eventDriver.ElementValueChanging += EventDriver_ElementValueChanging;//元素值改變前
    eventDriver.ElementValueChanged += EventDriver_ElementValueChanged;//元素值改變后
    eventDriver.ExceptionThrown += EventDriver_ExceptionThrown;//異常發(fā)生后事件

    掛接事件:

    #region 事件區(qū)
    
    /// 
    /// 導航前發(fā)生的事件
    /// 
    /// 
    /// 
    private void EventDriver_Navigating(object sender, WebDriverNavigationEventArgs e)
    {
        this.listMeassage.Add("-----------------------------------------");
        this.listMeassage.Add($"即將要跳轉到的URL為:{e.Driver.Url}");
    }
    
    /// 
    /// 導航后發(fā)生的事件
    /// 
    /// 
    /// 
    private void EventDriver_Navigated(object sender, WebDriverNavigationEventArgs e)
    {
        this.listMeassage.Add("-----------------------------------------");
        this.listMeassage.Add($"跳轉到的URL為:{e.Driver.Url}");
    }
    
    /// 
    /// 查找元素前發(fā)生
    /// 
    /// 
    /// 
    private void EventDriver_FindingElement(object sender, FindElementEventArgs e)
    {
        this.listMeassage.Add("-----------------------------------------");
    
        this.listMeassage.Add($"即將查找的元素為:{e.FindMethod.ToString()}");
    }
    
    /// 
    /// 查找元素后發(fā)生
    /// 
    /// 
    /// 
    private void EventDriver_FindElementCompleted(object sender, FindElementEventArgs e)
    {
        this.listMeassage.Add("-----------------------------------------");
        this.listMeassage.Add($"找到元素,條件為:{e.FindMethod.ToString()}");
    }
    
    /// 
    /// 單擊元素前發(fā)生
    /// 
    /// 
    /// 
    private void EventDriver_ElementClicking(object sender, WebElementEventArgs e)
    {
        this.listMeassage.Add("-----------------------------------------");
        this.listMeassage.Add($"要單擊的元素的value屬性為:{e.Element.GetAttribute("value")}");
    }
    
    /// 
    /// 單擊元素后發(fā)生
    /// 
    /// 
    /// 
    private void EventDriver_ElementClicked(object sender, WebElementEventArgs e)
    {
        System.Threading.Thread.Sleep(3 * 1000);//暫停3秒
        this.listMeassage.Add("-----------------------------------------");
        this.listMeassage.Add($"單擊元素后,現在的URL為:{e.Driver.Url}");
    }
    
    /// 
    /// 單擊元素前發(fā)生
    /// 
    /// 
    /// 
    private void EventDriver_ElementValueChanging(object sender, WebElementEventArgs e)
    {
        this.listMeassage.Add("-----------------------------------------");
        this.listMeassage.Add($"元素更改前的值為:{e.Element.GetAttribute("value")}");
    }
    
    /// 
    /// 單擊元素后發(fā)生
    /// 
    /// 
    /// 
    private void EventDriver_ElementValueChanged(object sender, WebElementEventArgs e)
    {
        this.listMeassage.Add("-----------------------------------------");
        this.listMeassage.Add($"元素更改后的值為:{e.Element.GetAttribute("value")}");
    }
    
    /// 
    /// 異常(保存截圖到本地)
    /// 
    /// 
    /// 
    private void EventDriver_ExceptionThrown(object sender, WebDriverExceptionEventArgs e)
    {
        //地址
        string strPath = $@"D:\Desktop\{DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss")}.png";
    
        //保存截圖
        Screenshot screen = (sender as EventFiringWebDriver).GetScreenshot();
        screen.SaveAsFile(strPath, System.Drawing.Imaging.ImageFormat.Png);
    
        //輸出保存信息
        this.listMeassage.Add("-----------------------------------------");
        this.listMeassage.Add($"發(fā)生異常,截圖已保存到:{strPath}");
    }

    十、關閉瀏覽器

    有下面兩種:

    • Close():關閉WedDriver對象所在的窗口; 
      第一個是關閉一個窗口,一個wedDriver對象是可以有多個窗口的(之前的窗口切換也是提到過),需要關閉時要保證當前激活的窗口。比如一個wedDriver對象里有好多個窗口,你要關閉第2個窗口,就要用SwitchTo().Window()方法切換到第2個窗口才能關閉,不能直接關閉第幾個窗口的。

    • Quit():關閉所有相關窗口; 
      第二個關閉和這個webDriver對象所有相關的窗口。當然,一個腳本是可以有多個webDriver對象

    下面代碼的代碼展示這了兩個方法的用法和用途。 
    1.打開百度首頁,單擊“注冊”超級鏈接。 
    2.在彈出的窗口(百度賬戶注冊)中,調用Close()方法,關閉新彈出的頁面 
    3.再一次點擊“注冊”超級鏈接,調用Quit()方法來結束測試。

    var service = EdgeDriverService.CreateDefaultService(@".", "msedgedriver.exe");
    IWebDriver driver = new OpenQA.Selenium.Edge.EdgeDriver(service);
    
    //導航到百度首頁
    driver.Navigate().GoToUrl("http://www.baidu.com");
    
    //進行點擊
    Console.WriteLine("-------------------");
    Console.WriteLine("進行點擊");
    driver.FindElement(By.LinkText("登錄")).Click();
    System.Threading.Thread.Sleep(3 * 1000);
    driver.FindElement(By.LinkText("立即注冊")).Click();
    
    //獲取窗口句柄
    IList<string> listHand = driver.WindowHandles;
    
    //切換到注冊窗口并關閉
    Console.WriteLine("-------------------");
    Console.WriteLine("切換到注冊窗口");
    driver.SwitchTo().Window(listHand[1]);
    System.Threading.Thread.Sleep(3 * 1000);
    Console.WriteLine("-------------------");
    Console.WriteLine("關閉注冊窗口");
    driver.Close();
    System.Threading.Thread.Sleep(3 * 1000);
    
    //切換到主窗口并結束測試
    Console.WriteLine("-------------------");
    Console.WriteLine("切換到主窗口并結束測試");
    driver.SwitchTo().Window(listHand[0]);
    driver.FindElement(By.LinkText("立即注冊")).Click();
    System.Threading.Thread.Sleep(3 * 1000);
    driver.Quit();
    
    Console.ReadLine();

    讀到這里,這篇“C#如何使用selenium實現爬蟲”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI