728x90
반응형
웹 이벤트를 자동(batch)수행하기 위해 Selenium기반으로 C#으로 접근해 보았습니다.
기능하고자 한 것은
1. 신문사의 특정 기사에 접근
2. Tag를 찾아내서 그 하이퍼링크된 주소를 클릭
3. 새창으로 열린 창으로 접근
4. 특정 iframe을 찾기 및 iframe 선택
5. Javascript 구문을 수행하기
6. PageSource에 접근하여 내용 수정
7. 페이지 코드를 파일로 저장
728x90
ChromdeDriver를 생성하여 그 인터페이스(Interface)를 사용합니다.
IWebDriver driver = new ChromeDriver(options)
크롬 웹브라우저를 열 URL을 지정합니다. 반환값은 처리한 URL입니다. 즉, 그대로 출력합니다.
string strResult = driver.Url = "https://www.etnews.com/20230331000229"; // implicitly wait until the load is complete.
Console.WriteLine(strResult);
제대로 URL이 열렸는지는 Title 값을 활용하여 Heuristic하게 프로그래밍 했습니다.
if (driver.Title.IndexOf("missing.html") == -1)
특정 태그('a')를 찾아 그 이름이 "Englisth"일 경우, 그 하이퍼링크 URL을 호출(click)합니다.
IList<IWebElement> links = driver.FindElements(By.TagName("a"));
//Console.WriteLine(links[0].Text);
//links.First(element => element.Text == "English").Click();
foreach (var link in links)
{
Console.WriteLine(link.Text);
if (link.Text == "English")
{
Console.WriteLine(link.GetAttribute("href"));
link.Click();
break;
}
}
'새창'으로 열렸기 때문에, 제어권을 '새창'으로 옮깁니다.(SwitchTo)
string originWindow = driver.CurrentWindowHandle;
Console.WriteLine(originWindow);
foreach (string window in driver.WindowHandles)
{
//새창을 찾는다.
if (originWindow != window)
{
Console.WriteLine(window);
driver.SwitchTo().Window(window);
break;
}
}
특정 iFrame 요소를 찾습니다.
List<IWebElement> frames = new List<IWebElement>(driver.FindElements(By.TagName("iframe")));
Console.WriteLine("Number of Frames: " + frames.Count);
var bFoundResultPage = 0;
for (int i = 0; i < frames.Count; i++)
{
Console.WriteLine("frame[" + i + "]: " + frames[i].GetAttribute("id").ToString());
if (frames[i].GetAttribute("id").ToString() == "CSLiResulPage")
{
bFoundResultPage = 1;
}
}
특정 iFrame을 사용합니다.
driver.SwitchTo().Frame("CSLiResultPage");
JavaScript를 수행하여, 속성을 바꾸어 봅니다.
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
//js.ExecuteScript("window.open()");
js.ExecuteScript("document.getElementsByTagName(\"html\")[0].setAttribute(\"lang\",\"en\") ");
웹페이지소스코드의 내용을 수정해 봅니다.
string aaa = driver.PageSource.ToString();
string bbb = aaa.Replace("https://trans.etnews.com", "http://klaud.between.io");
//Console.WriteLine(bbb);
전체 소스코드는 아래와 같습니다.
( 메모리 최적화 delete , sleep 대신에 await 등 처리 대기 등은 더 최적화 되어야 합니다.^^)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium;
namespace WebCrawler
{
static class Program
{
static void Main(string[] args)
{
// ChomeDriver 인스턴스 생성
ChromeOptions options = new ChromeOptions();
options.AddArguments("--test-type");
options.AddArguments("--ignore-certificate-errors");
using ( IWebDriver driver = new ChromeDriver(options) )
{
// URL로 접속
string strResult = driver.Url = "https://www.etnews.com/20230331000229"; // implicitly wait until the load is complete.
Console.WriteLine(strResult);
if (driver.Title.IndexOf("missing.html") == -1)
{
// 대기 설정. (find로 객체를 찾을 때까지 검색이 되지 않으면 대기하는 시간 초단위)
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
Thread.Sleep(1000);
IList<IWebElement> links = driver.FindElements(By.TagName("a"));
foreach (var link in links)
{
Console.WriteLine(link.Text);
if (link.Text == "English")
{
Console.WriteLine(link.GetAttribute("href"));
link.Click();
break;
}
}
// 5초 기다린다.
Thread.Sleep(5000);
// 기존창 대신에 새창에서 열린다.
string originWindow = driver.CurrentWindowHandle;
Console.WriteLine(originWindow);
foreach (string window in driver.WindowHandles)
{
//새창을 찾는다.
if (originWindow != window)
{
Console.WriteLine(window);
driver.SwitchTo().Window(window);
break;
}
}
// iFrame 찾기
List<IWebElement> frames = new List<IWebElement>(driver.FindElements(By.TagName("iframe")));
Console.WriteLine("Number of Frames: " + frames.Count);
var bFoundResultPage = 0;
for (int i = 0; i < frames.Count; i++)
{
Console.WriteLine("frame[" + i + "]: " + frames[i].GetAttribute("id").ToString());
if (frames[i].GetAttribute("id").ToString() == "CSLiResulPage")
{
bFoundResultPage = 1;
}
}
if (bFoundResultPage == 1)
{
driver.SwitchTo().Frame("CSLiResultPage");
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("document.getElementsByTagName(\"html\")[0].setAttribute(\"lang\",\"en\") ");
string aaa = driver.PageSource.ToString();
string bbb = aaa.Replace("https://trans.etnews.com", "http://klaud.between.io");
//Console.WriteLine(bbb);
File.WriteAllText("C:\\UsersDownloads\\PageSource.html", bbb);
//File.WriteAllText("C:\\UsersDownloads\\PageSource.html", driver.PageSource);
// 5초 기다린다.
Thread.Sleep(1000);
}
}
driver.Quit();
}
// 아무 키나 누르면 종료
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
}
728x90
반응형
'프로그램언어 C C++' 카테고리의 다른 글
편미분 연쇄법칙 확장 (0) | 2023.05.23 |
---|---|
Dot Product of Matrix (0) | 2023.05.23 |
NumPy - 파이썬 라이브러리( C 코드, 수행속도, 다차원/배열 처리) (0) | 2023.04.16 |
멀티바이트 vs. 유니코드 (0) | 2023.01.30 |
c# List Dictionary ContainsKey TryGetValue (0) | 2023.01.25 |