C에서 간단한 웹 스크레이퍼 만들기#

웹 캡처는 많은 상황에서 유용한 기능을 제공할 수 있으며, 주로 사이트에서 특정한 데이터 집합을 얻어야 할 때이다.나는 이것이 통계 데이터나 특정한 키워드를 가진 문장 같은 데이터를 검색하는 데 가장 많이 사용된다고 생각한다.이 강좌에서, 나는 웹 사이트에서 다음 문장인 특정한 키워드가 있는 문장을 검색하는 방법을 가르쳐 줄 것이다.
시작하기 전에, 나는 웹 페이지 캡처와 그 한계성을 소개하고 싶다.웹 캡처는 웹 가져오기 또는 웹 데이터 추출이라고도 하는데 인터넷을 통해 사이트에서 자동으로 데이터를 추출하는 방법이다.제가 오늘 알려드리고자 하는 해석 방법은 HTML 해석입니다. 이것은 저희 웹 스크레이퍼가 페이지의 HTML 내용을 보고 우리가 검색하고 싶은 정보의 종류와 일치하는 정보를 추출한다는 것을 의미합니다. (이것이 의미가 없으면 걱정하지 마십시오. 제가 잠시 후에 상세하게 소개합니다!)이러한 웹 캡처 방법은 다음과 같은 사실의 제한을 받는다. 모든 사이트가 html에 모든 정보를 저장하는 것은 아니다. 우리가 오늘 본 많은 내용은 동적이고 페이지에 불러온 후에 구축된 것이다.이러한 정보를 보기 위해서는 더욱 복잡한 네트워크 파충류가 필요하다. 보통 자신의 네트워크 캐리어를 가지고 있는데, 이것은 본 강좌의 범위를 넘어선다.
대부분의 강좌는 Python으로 웹 스크레이퍼를 구축하기 때문에 C 언어로 웹 스크레이퍼를 구축하기로 했습니다.비록 이것은 이 일의 이상적인 언어일 수 있지만, 나는 그것이 C 언어로 완성할 수 있다는 것을 스스로에게 증명하고 싶다.나는 또한 C#webscraping 강좌(작성할 때까지)를 제공함으로써 다른 사람들이 자신의 웹 Scraper를 구축하는 것을 배우는 데 도움을 주기를 바란다.

웹 스크레이퍼 구축


우리가 정리할 사이트는 Ocean Networks Canada, 해양과 지구 정보를 전문적으로 제공하는 사이트이다.이 프로젝트를 이용하여 인터넷에서 글과 데이터를 검색하는 사람들은 이 사이트가 그들이 만날 많은 다른 사이트와 유사한 모델을 제공했다는 것을 발견할 수 있다.

  • Visual Studio를 시작하고 새 C#을 생성합니다.NET Windows 창 응용 프로그램.


  • 스크레이퍼를 시작하는 단추와 인쇄 결과가 있는 풍부한 텍스트 상자를 가진 기본 폼을 설계합니다.


  • 솔루션 브라우저에서 항목 이름을 마우스 오른쪽 버튼으로 클릭하고 "NuGet 패키지 관리"를 선택하여 NuGet 패키지 관리자를 엽니다.AngleSharp을 검색하고 설치를 클릭합니다.


  • 검색어 그룹을 추가하고 스크랩하기 위해 문서를 설정할 방법을 만듭니다.코드는 다음과 같습니다.
        private string Title { get; set; }
        private string Url { get; set; }
        private string siteUrl = "https://www.oceannetworks.ca/news/stories";
        public string[] QueryTerms { get; } = {"Ocean", "Nature", "Pollution"};
    
        internal async void ScrapeWebsite()
        {
              CancellationTokenSource cancellationToken = new CancellationTokenSource();
              HttpClient httpClient = new HttpClient();
              HttpResponseMessage request = await httpClient.GetAsync(siteUrl);
              cancellationToken.Token.ThrowIfCancellationRequested();
    
              Stream response = await request.Content.ReadAsStreamAsync();
              cancellationToken.Token.ThrowIfCancellationRequested();
    
              HtmlParser parser = new HtmlParser();
              IHtmlDocument document = parser.ParseDocument(response);
        }
    
    CancellationTokenSource 작업이나 스레드가 취소될 경우 영패를 제공합니다.
    HttpClient URI로 식별된 리소스에서 HTTP 요청 및 HTTP 응답 수신을 위한 기본 클래스 제공
    HttpResponseMessage 상태 코드와 데이터를 포함한 HTTP 응답 메시지를 나타냅니다.
    HtmlParser와 IHtmlDocument는 AngleSharp 클래스로 웹 사이트의 HTML 내용에서 문서를 구축하고 해석할 수 있습니다.

  • AngleSharp 문서에서 결과를 가져오고 표시하는 또 다른 방법을 만듭니다.여기에서 문서를 분석하고 QueryTerms와 일치하는 모든 글을 검색합니다.두 사이트에서 같은 HTML 이름 규약을 사용하지 않기 때문에 곤란할 수 있습니다. - "article Link"LINQ를 정확하게 조회하려면 몇 가지 반복적인 실험이 필요할 수 있습니다.
        private void GetScrapeResults(IHtmlDocument document)
        {
              IEnumerable<IElement> articleLink;
    
              foreach (var term in QueryTerms)
              {
                    articleLink = document.All.Where(x => x.ClassName == "views-field views-field-nothing" && (x.ParentElement.InnerHtml.Contains(term) || x.ParentElement.InnerHtml.Contains(term.ToLower())));
              }
    
              if (articleLink.Any())
              {
                    // Print Results: See Next Step
              }
        }
    
    여기서 무슨 일이 일어났는지 확실하지 않으면, 우리는 모든 검색 항목 (해양, 자연, 오염) 을 순환하고 있으며, "views field views field nothing"과 Parent Element의 모든 실례를 찾기 위해 문서를 해석하고 있습니다.InnerHtml에는 현재 질의에 대한 용어가 포함되어 있습니다.
    웹 페이지의 HTML을 보는 방법에 익숙하지 않으면 원하는 URL로 이동하여 페이지의 모든 위치를 마우스 오른쪽 단추로 클릭하고 "페이지 원본 보기"를 선택하여 찾을 수 있습니다.일부 페이지는 소량의 HTML이 있고, 다른 페이지는 수만 줄이 넘는다.글의 제목이 저장된 위치를 찾은 다음 저장된 클래스를 확인하기 위해 이 모든 것을 선별해야 합니다.내가 사용하는 기교 중 하나는 문장 제목의 일부분을 검색한 후에 몇 줄을 위로 옮기는 것이다.


  • 현재, 만약 우리의 조회 조건이 유리하다면, 우리는 몇 개의 HTML 집합의 목록을 가지고 있어야 한다. 그 중에서 우리의 문장 제목과 URL을 포함해야 한다.결과를 Rich Textbox에 인쇄하는 새로운 방법을 만듭니다.
        public void PrintResults(string term, IEnumerable<IElement> articleLink)
        {
              // Clean Up Results: See Next Step
    
              resultsTextbox.Text = $"{Title} - {Url}{Environment.NewLine}";
        }
    

  • 만약 우리가 원래대로 결과를 인쇄한다면, 그것들은 HTML 표지처럼 보일 것이다. 모든 표지, 괄호 및 기타 비인간적인 우호 항목을 포함한다.우리는 결과를 표에 인쇄하기 전에 결과를 정리하는 방법을 삽입해야 한다. 5단계와 마찬가지로 표시는 사이트에 따라 다르다.
        private void CleanUpResults(IElement result)
        {
              string htmlResult = result.InnerHtml.ReplaceFirst("        <span class=\"field-content\"><div><a href=\"", "https://www.oceannetworks.ca");
              htmlResult = htmlResult.ReplaceFirst("\">", "*");
              htmlResult = htmlResult.ReplaceFirst("</a></div>\n<div class=\"article-title-top\">", "-");
              htmlResult = htmlResult.ReplaceFirst("</div>\n<hr></span>  ", "");
    
              // Split Results: See Next Step
        }
    
    그럼 여기서 무슨 일이 일어났어요?네, 들어갈 결과 대상의 InnerHtml을 검사해서 제가 진정으로 표시하고자 하는 내용에서 어떤 추가 내용-제목과 URL을 삭제해야 하는지 보았습니다.왼쪽에서 오른쪽으로, 나는 단지 하나의 빈 문자열이나'nothing'으로 모든 html 내용 블록을 교체한 다음, URL과 제목 사이의 블록을'*'로 바꾸어 자리 표시자로 삼아 나중에 문자열을 분할할 수 있도록 한다.이러한 ReplaceFirst () 의 모든 사용법은 사이트마다 다를 수 있으며, 심지어 특정 사이트의 모든 문장에서 완벽하게 작업할 수 없을 수도 있다.너는 계속해서 새로운 대체품을 추가할 수 있거나, 만약 그것들이 충분히 보기 드물다면, 그것들을 무시할 수 있다.

  • 나는 당신이 지난번에 우리가 깨끗한 결과를 텍스트 상자에 인쇄할 수 있기 전에 마지막 방법을 추가해야 한다는 것을 알아차렸다고 확신합니다.이제 결과 문자열을 정리했습니다. "*"자리 표시자를 사용하여 제목과 URL 두 문자열로 분할할 수 있습니다.
        private void SplitResults(string htmlResult)
        {
              string[] splitResults = htmlResult.Split('*');
              Url = splitResults[0];
              Title = splitResults[1];
        }
    

  • 마지막으로, 우리는 깨끗하고 인성화된 결과를 얻었다.만약 모든 것이 순조롭고 본문을 작성한 이래로 문장에 중대한 변화가 일어나지 않는다면 실행 코드는 다음과 같은 결과를 제공할 것이다 (더 많은...더 많은!)애플리케이션이 Ocean Networks에서 다음 항목을 제거했습니다.

  • 나는 이 강좌가 너로 하여금 웹 페이지가 캡처한 세계에 대해 이해하게 할 수 있기를 바란다.만약 충분한 흥미가 있다면, 나는 이 시리즈를 계속하고, 응용 프로그램을 설정하고, 특정한 시간 간격으로 새로운 스크랩을 하고, 당신에게 시사 통신식 전자메일과 하루나 일주일의 결과를 보내는 방법을 가르쳐 줄 수 있다.
    만약 당신이 소셜 미디어에서 나를 찾고 싶다면, 나를 찾거나 찾아서 인사하세요!

    좋은 웹페이지 즐겨찾기