[robot]selenium+chrome以headless無痕方式執行

  • 1155
  • 0
  • 2018-04-16

[robot]selenium+chrome以headless無痕方式執行

1.下載webdriver.dll+webdriver.support.dll的3.2版本 + chromedriver.exe的2.33版本懶人包
2.新增console專案,把step1的dll都加入參考,System.Management也加入參考,然後把ChromeDriver資料夾複製到應用程式的bin\Debug路徑下
3.貼上以下程式碼,專案名稱改成當下自己的:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.PhantomJS;
using OpenQA.Selenium.Remote;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading;

namespace ESportDataCollector
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Console.WriteLine("start...");
            //每次執行前先刪除之前掛掉沒在用的chrome, chromedriver的process
            KillUncontrollerBrowser();
            IWebDriver driver;
            //隱藏chromedriver.exe視窗
            ChromeOptions chromeBrowserOptions = new ChromeOptions();
            var driverService = ChromeDriverService.CreateDefaultService(@"ChromeDriver");
            driverService.HideCommandPromptWindow = true;
            
            //chrome有時候容易因為sandbox的封裝環境導致掛點,因此要no-sandbox
            //headless可以隱藏chrome(chromedriver.exe版本需2.29以上)            
            chromeBrowserOptions.AddArguments(new List<string>() { "no-sandbox", "headless", "disable-gpu", "window-size=1904x1500" });

            driver = new ChromeDriver(driverService, chromeBrowserOptions);
            driver.Navigate().GoToUrl("https://tw.yahoo.com");
            Thread.Sleep(30000);
        }

        #region 自訂函數

        public static void KillUncontrollerBrowser()
        {
            string str = "chrome";
            foreach (var item in str.Split(';'))
            {
                KillUncontrollerProcess(item);
            }
        }
        /// <summary>
        /// kill有 ParentID 的process
        /// </summary>
        /// <param name="ProcessName">傳入要檢查的exe名稱(ex: firefox,chrome,phantomjs)</param>
        private static void KillUncontrollerProcess(string ProcessName)
        {
            
            Process[] ProcList = Process.GetProcessesByName(ProcessName);

            
            foreach (Process proc in ProcList)
            {
                try
                {
                    ManagementObject managementObject = new ManagementObject(string.Format("win32_process.handle='{0}'", proc.Id));
                    managementObject.Get();
                    int parentId = Convert.ToInt32(managementObject["ParentProcessId"]);

                    try
                    {
                        if(parentId == 0)
                        {
                            continue;
                        }
                        Process parentProc = Process.GetProcessById(parentId);
                        if (parentProc.ProcessName == "chromedriver")
                        {
                            //先刪除此process的parent process                            
                            parentProc.Kill();
                            //再刪除自己
                            proc.Kill();
                        }
                        
                        
                    }
                    catch
                    {

                        
                        continue;
                    }
                }
                catch
                {

                    continue;
                }

               
            }
			
			//難免會有之前執行沒刪除乾淨的chromedriver.exe
			foreach (var process in Process.GetProcessesByName("chromedriver"))
			{
				try
				{
					process.Kill();
				}
				catch
				{
					SpinWait.SpinUntil(()=>false,5000);
					return;
				}
				
			}


        }

        #endregion
    }
}


4.done

ps.一般都是無窮迴圈執行,如有需要開開關關selenium,請參考
[robot]每次執行完畢需關閉Selenium節省資源
https://dotblogs.com.tw/kevinya/2018/03/19/150450