Async, HtmlAgilityPack 및 XPath로 구문 분석

asynchronous c# html-agility-pack web-scraping xpath

문제

나는 이상한 문제를 겪었다. 설명하기가 매우 어렵 기 때문에 저와 함께하시기 바랍니다. 그러나 기본적으로 여기에 간단한 소개가 있습니다.

  • 비동기 프로그래밍을 처음 사용했지만 코드에서 문제를 찾을 수 없습니다.
  • 이전에 HtmlAgilityPack을 사용했지만 .NET 4.5 버전은 사용하지 않았습니다.
  • 이것은 학습 프로젝트이며, 나는 긁어 모으기 위해 노력하고 있지 않습니다.

기본적으로 일어나는 일은 다음과 같습니다. 인터넷에서 페이지를 가져 와서 스트림을 통해 HtmlDocument 로로드 한 다음 XPath 표현식을 사용하여 특정 HtmlNodes 를 검색합니다. 다음은 간단한 코드입니다.

            myStream = await httpClient.GetStreamAsync(string.Format("{0}{1}", SomeString, AnotherString);

            using (myStream)
            {
                myDocument.Load(myStream);
            }

HTML은 정확하게 검색되지만 XPath에서 추출한 HtmlNodes는 HTML을 엉망으로 처리합니다. 다음은 Fiddler에서 가져온 응답에서 얻은 HTML 샘플입니다.

                    <div id="menu">
   <div id="splash">
      <div id="menuItem_1" class="ScreenTitle"  >Horse Racing</div>
      <div id="menuItem_2" class="Title"  >Wednesday Racing</div>
      <div id="subMenu_2">
         <div id="menuItem_3" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361707-2-20181217-0-0-1-0-0-4020-0-36200255-1-0-0-0-0">21.51 Britannia Way</a></div>
         <div id="menuItem_4" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0">21.54 Britannia Way</a></div>
         <div id="menuItem_5" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361713-2-20181217-0-0-1-0-0-4020-0-36200261-1-0-0-0-0">21.57 Britannia Way</a></div>
         <div id="menuItem_6" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361716-2-20181217-0-0-1-0-0-4020-0-36200264-1-0-0-0-0">22.00 Britannia Way</a></div>
         <div id="menuItem_7" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361719-2-20181217-0-0-1-0-0-4020-0-36200267-1-0-0-0-0">22.03 Britannia Way</a></div>
         <div id="menuItem_8" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361722-2-20181217-0-0-1-0-0-4020-0-36200270-1-0-0-0-0">22.06 Britannia Way</a></div>
      </div>
   </div>
</div>

동일한 페이지의 브라우저에서 작동하기 때문에 내가 사용하고있는 XPath는 100 % 정확하지만, 여기에 이전에 표시된 페이지에서 검색 a 태그의 예가 있습니다.

<a href="./coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0"">1.54 Britannia Way</</a>

그리고 단순화를 위해 위에서 복사 한 원본은 다음과 같습니다.

<a href="../coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0">21.54 Britannia Way</a></div>

보시다시피, InnerText는 상당히 변경되었으므로 URL도 있습니다. 분명히 내 프로그램이 작동하지 않지만 어떻게해야할지 모르겠다. 무엇이 이것을 일으킬 수 있습니까? HtmlAgilityPack의 버그입니까? 제발 조언 해! 읽어 주셔서 감사합니다!

수락 된 답변

많은 시간을 짐작하고 디버깅 한 후에 문제는 내가 재사용하고있는 HtmlDocument 로 밝혀졌습니다. 나는 새로운 페이지를로드 할 때마다 동일한 HtmlDocument 를 사용하지 않고 새로운 HtmlDocument 를 생성하여 문제를 해결했다.

내가 잃어버린 시간을 절약 할 수 있기를 바랍니다.


인기 답변

브라우저에서 XPath식이 작동한다고 가정하지 마십시오 ( DOM 변환 후 AJAX로 데이터로드 가능). 이것은 내기 인용 부호를주는 사이트처럼 보이는데, 나는 그들이 몇몇 자바 스크립트 호출로 데이터를로드하고있는 것 같아요.

XPath 표현식이 페이지 소스 코드와 일치하는지 확인하십시오 (예 : wget 사용하여 가져 오거나 브라우저에서 "소스 코드보기"를 클릭하십시오.) - Firebug /를 사용하지 마십시오!

사이트가 AJAX를 사용하여 데이터를로드하는 경우 Firebug를 사용하여 페이지를로드하는 동안 가져올 리소스를 모니터링하여 운이 좋을 수도 있습니다. 대개 JSON 또는 XML 파일을 파싱하기 쉽고, HTML의 끔찍한 웹 사이트를 파싱하는 것보다 작업하기가 더 쉽습니다.

업데이트 : 이 특별한 경우 사이트는 Accept-Language 헤더를 보내지 않은 사용자를 언어 선택 페이지로 전달합니다. 브라우저가하는 것과 같은 내용을받을 수 있도록 헤더를 보내십시오. 말아 올리면 다음과 같이 보입니다.

curl -H "Accept-Language: en-US;q=0.6,en;q=0.4" https://mobile.bet365.com/sport/splash/Default.aspx?Sport


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.