Анализ с помощью Async, HtmlAgilityPack и XPath

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

Вопрос

Я столкнулся с довольно странной проблемой. Это очень сложно объяснить, поэтому, пожалуйста, несите меня, но в основном вот краткое введение:

  • Я новичок в программировании Async, но не смог найти проблему в своем коде
  • Раньше я использовал HtmlAgilityPack, но никогда не использовал версию .NET 4.5.
  • Это учебный проект, я не пытаюсь царапать или что-то в этом роде.

В основном, происходит следующее: я извлекаю страницу из Интернета, загружая ее через поток в HtmlDocument , а затем HtmlNodes из нее определенные HtmlNodes используя выражения XPath . Вот фрагмент упрощенного кода:

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

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

HTML вернется правильно, но HtmlNodes, извлеченные XPath, вызывают искажение HTML. Вот пример фрагмента HTML, который я получил в ответе от Fiddler:

                    <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% правильно , так как он работает в браузере на той же странице, но вот пример тег , который он retreiving от ранее показанной странице: 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, ...). Кажется, сайт дает котировки ставок, я бы предположил, что они загружают данные с помощью некоторых javascript-вызовов.

Убедитесь, что выражение XPath соответствует исходному коду страниц (например, с помощью wget или нажатием «Просмотр исходного кода» в вашем браузере - не используйте Firebug / ... для этого!

Если сайт использует AJAX для загрузки данных, вам может быть повезло, используя Firebug, чтобы отслеживать, какие ресурсы извлекаются во время загрузки страницы. Часто это JSON- или XML-файлы, которые очень легко анализировать, и с ними даже легче работать, чем анализировать веб-сайт ужасных беспорядков HTML.

Обновление. В этом специальном случае сайт перенаправляет пользователей, не отправляя заголовок Accept-Language на страницу выбора языка. Отправьте такой заголовок, чтобы получить то же содержимое, что и браузер. В curl это выглядело бы так:

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


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему