닷넷/C#

C# 웹크롤링 selenium 사용기

FreeBear 2020. 1. 8. 22:42
반응형

쿠팡사이트를 크롤링하려는데 단순히 웹브라우저나 WebClient 통해서 html을 가져오는 것으로는 브라우저에 보이는 그대로 크롤링을 할 수가 없었다.
(이는 해당 사이트에서 오른쪽마우스를 클릭해 페이지 소스보기했을 때 나오는 것과 같다.)

selenium은 chrome 브라우저를 열어서 크롤링을 하는 부분이라 사이트에서 F12를 눌렀을 때 보이는 것과 같아 내가 원하는 것을 딱딱 크롤링할 수가 있었다.

 

프로젝트에서 selenium을 사용하려면 먼저,

비주얼스튜디오에 도구> NuGet 패키지 관리자> 솔루션용 NuGet 패키지 순으로 클릭한다.

찾아보기 탭을 클릭하고, selenium으로 검색한다.

그 중에서 Selenium.WebDriver, Selenium.WebDriver.ChromeDriver, Selenium.Chrome.WebDriver

세 가지를 설치한다.

 

그 다음 코드를 작성하여 사용한다.


코드 사용 예)

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


private void GetCoupangProduct(string _site, out string _productinfo, out string _mainimage, out string[] _image, out string _tag)
{
    string productinfo = "", tag = "", mainimage = "";
    string[] image = { };

   // 크롬드라이버 사용
    using (IWebDriver driver = new ChromeDriver())
    {
        driver.Navigate().GoToUrl(_site);
        driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(10);
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);

        // 태그에 있는 id로 검색할 때
        //   .FindElement(By.ID("어떤 태그의 ID"))
        
        //   태그내부 텍스트
        //     .Text        
        string sss = driver.FindElement(By.Id("breadcrumb")).Text;
        sss = sss.Replace("  >", "").Replace("/", "#").Replace("\r\n", "#");
        sss = sss.Replace(" ", "").Replace("#", " #");
        tag = sss.Replace("쿠팡홈", "");
		
        
        // 태그에 있는 class로 검색할 때
        //   .FindElement(By.ClassName("어떤 태그의 class"));
        
        //   해당 태그에 속해 있는 attribute(속성)을 검색
        //     .GetAttribute("속성이름")        
        string img = driver.FindElement(By.ClassName("prod-image__detail")).GetAttribute("src");
        mainimage = GetFileName(img);        


        // 해당 클래스이름을 가진 태그가 있는지 체크하기        
        if (IsElementPresent(driver, By.ClassName("product-item__table")) == true)
        {
            var element = driver.FindElement(By.ClassName("product-item__table"));
            
            // 해당 클래스를 가진 html을 가져올 때            
            // element.GetAttribute("innerHTML")            
            var tempinfo = element.GetAttribute("innerHTML");
            
            
            // 필요없는 부분은 split으로 쪼개서 버리기..            
            string[] ss = tempinfo.Split(new string[] { "<p class=\"essential-info-more\">" }, StringSplitOptions.None);
            productinfo = ss[0];
        }

        if(IsElementPresent(driver, By.ClassName("subType-IMAGE")) == true)
        { 
        	// 똑같은 class 명을 가진 태그가 여러가지이며 전부 검색할 때
            // .FindElemnts(By.ClassName("어떤 태그의 class))            
            var productimage = driver.FindElements(By.ClassName("subType-IMAGE"));
            int imageindex = 0;
            image = new string[productimage.Count];
            
            // 컬렉션이기 때문에 각각을 검색할 땐 foreach를 사용
            foreach (var item in productimage)
            {
                var sub = item.FindElement(By.TagName("img")).GetAttribute("src");
                image[imageindex] = GetFileName(sub);
                imageindex++;
            }
        }
    }
            

    _productinfo = productinfo;
    _mainimage = mainimage;
    _image = image;
    _tag = tag;

}


// 해당 정보를 가진 태그가 있는지 없는지 확인 
private bool IsElementPresent(IWebDriver _driver, By _by)
{
    try
    {
        _driver.FindElement(_by);
        return true;
    }
    catch (NoSuchElementException)
    {
        return false;
    }
}

 

 

반응형