반응형
Selenium으로 특정페이지 특정요소(element)가 확인될때 까지 기다려야 되는 경우가 있습니다
이때 DotNetSeleniumExtras.WaitHelpers를 이용해 스레드를 만들수 있습니다.
WebDriverWait.Until은 요소를 찾을때 까지 스레드가 진행되는데 메인스레드(GUI)에서 사용하면 메인스레드가 블로킹 됩니다.
다행이 DotNETSeleniumExtras.WaitHelpers Until함수에 CancellationToken 옵션이 있어 비동기 처리(Task, await, async)를 이용해 메인스레드가 블로킹 안되고 찾고자 하는 요소를 기다릴수 있습니다.
- NuGET 패키지 설치
DotNetSeleniumExtras.WaitHelpers 3.11.0
Selenium.Support 4.6.0
Selenium.WebDriver 4.6.0
WebDriverManager 2.16.1 (ChromeDriver 버전 자동 관리)
- 소스
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// Selenium Library
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
// util
using System.IO;
using Microsoft.Win32;
using System.Diagnostics;
using SeleniumExtras.WaitHelpers;
using WebDriverManager;
using WebDriverManager.DriverConfigs.Impl;
using WebDriverManager.Helpers;
using System.Threading;
namespace ChromeHelper
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private CancellationTokenSource _cancelTokenSource = new CancellationTokenSource();
private IWebDriver _webDriver;
private async void btnRun_Click(object sender, EventArgs e)
{
CancellationToken token = _cancelTokenSource.Token;
try
{
await Run(token);
}
catch (Exception ex)
{
Trace.WriteLine(ex);
}
}
private async Task Run(CancellationToken _canceltoken)
{
_status = false;
new WebDriverManager.DriverManager().SetUpDriver(new ChromeConfig());
ChromeOptions _options = new ChromeOptions();
_options.AddArgument("--window-size=1024,768");
_options.AddArgument("disable-gpu");
_options.Proxy = null;
_webDriver = new ChromeDriver(_options);
_webDriver.Navigate().GoToUrl("https://www.google.com/");
System.TimeSpan timeToWait = new TimeSpan(0, 30, 0); // 30min waiting
WebDriverWait wait = new WebDriverWait(_webDriver, timeToWait);
await Task.Factory.StartNew(() => {
try
{
//cancellationToken을 넘김
var FoundElement = wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='찾고자하는요소']")), _canceltoken);
Trace.WriteLine("---------------찾고자하는요소-----------------");
Trace.WriteLine(FoundElement.Text);
}
// cancel이벤트 발생시
catch (OperationCanceledException ex) when (cancelTokenSource.IsCancellationRequested)
{
Trace.WriteLine("---------------CancellationToken event-----------------");
Trace.WriteLine(ex);
_webDriver.Quit();
}
// ChromeDriver강제종료시
catch (Exception ex)
{
Trace.WriteLine("---------------_webDriver종료-----------------");
Trace.WriteLine(ex);
_webDriver.Quit();
}
});
_status = true;
Trace.WriteLine("----------------------------------------------------");
Trace.WriteLine("Task 종료");
Trace.WriteLine("----------------------------------------------------");
}
private void btnCancel_Click(object sender, EventArgs e)
{
if (_status == true)
{
if (_webDriver != null)
{
_webDriver.Quit();
}
Trace.WriteLine("----------------------------------------------------");
Trace.WriteLine("_webDriver종료");
Trace.WriteLine("----------------------------------------------------");
}
else
{
cancelTokenSource.Cancel();
Trace.WriteLine("----------------------------------------------------");
Trace.WriteLine("cancelTokenSource.Cancel() 실행");
Trace.WriteLine("----------------------------------------------------");
}
}
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
if (_webDriver != null)
{
_webDriver.Quit();
}
}
}
}
'Windows' 카테고리의 다른 글
실시간 윈도우 이벤트 로그 리더(Real Time Event Log Reader) (0) | 2023.08.24 |
---|---|
Tesseract-OCR 학습방법 (0) | 2023.05.04 |
[C#] 근사값 구하기 (0) | 2022.02.06 |
c# 특정시간 기준으로 간격으로 두고 두번 실행하는 방법 (0) | 2021.12.17 |
PID를 알고 있을때 process kill 방법 (0) | 2021.12.16 |