C # - лучший подход к анализу веб-страницы? - PullRequest
19 голосов
/ 19 ноября 2008

Я сохранил html всей веб-страницы в строку, и теперь Я хочу получить значения "href" из ссылок, желательно с возможностью позже сохранить их в разных строках. Какой лучший способ сделать это?

Я пытался сохранить строку в формате XML-документа и проанализировать ее с помощью навигатора XPathDocument, но (неожиданно для удивления) он не слишком хорошо перемещается по документу, который не является действительно XML-документом.

Являются ли регулярные выражения лучшим способом достижения того, чего я пытаюсь достичь?

Ответы [ 8 ]

45 голосов
/ 19 ноября 2008

Я могу порекомендовать HTML Agility Pack . Я использовал его в нескольких случаях, когда мне нужно было разобрать HTML, и он прекрасно работает. Загрузив в него свой HTML, вы можете использовать выражения XPath для запроса документа и получения якорных тегов (а также всего, что там есть).

HtmlDocument yourDoc = // load your HTML;
int someCount = yourDoc.DocumentNode.SelectNodes("your_xpath").Count;
10 голосов
/ 19 ноября 2008

Регулярные выражения - один из способов сделать это, но это может быть проблематично.

Большинство HTML-страниц не могут быть проанализированы с использованием стандартных методов HTML, потому что, как вы выяснили, большинство не проверяют.

Вы могли бы потратить время на интеграцию HTML Tidy или аналогичного инструмента, но было бы намного быстрее просто создать необходимое регулярное выражение.

UPDATE

На момент этого обновления я получил 15 повышений и 9 понижений. Я думаю, что, возможно, люди не читают вопрос или комментарии к этому ответу. Все, что хотел сделать ОП - это получить значения href. Вот и все. С этой точки зрения, простое регулярное выражение просто прекрасно. Если бы автор хотел разобрать другие элементы, я бы не рекомендовал регулярное выражение, как я уже говорил в начале, в лучшем случае это проблематично.

5 голосов
/ 19 ноября 2008

Для работы с HTML всех форм и размеров я предпочитаю использовать пакет HTMLAgility @ http://www.codeplex.com/htmlagilitypack, который позволяет вам писать XPath для нужных вам узлов и получать их в коллекции.

2 голосов
/ 19 ноября 2008

Всегда лучше, если возможно, не заново открыть колесо. Существует несколько хороших инструментов, которые либо преобразуют HTML в правильно сформированный XML, либо действуют как XmlReader:

Вот три хороших инструмента:

  1. TagSoup , программа с открытым исходным кодом, представляет собой инструмент на основе Java и SAX, разработанный John Cowan . Это SAX-совместимый синтаксический анализатор, написанный на Java, который вместо синтаксического анализа правильно сформированного или корректного XML анализирует HTML так, как он встречается в дикой природе: плохой, неприятный и грубый, хотя довольно часто далеко не короткий. TagSoup предназначен для людей, которые должны обрабатывать эти вещи, используя некое подобие рационального дизайна приложения. Предоставляя интерфейс SAX, он позволяет применять стандартные инструменты XML даже к худшему HTML. TagSoup также включает в себя процессор командной строки, который читает файлы HTML и может генерировать либо чистый HTML, либо правильно сформированный XML, близкий к XHTML.
    Taggle - это коммерческий порт C ++ TagSoup.

  2. SgmlReader - это инструмент, разработанный Microsoft Крис Ловетт .
    SgmlReader - это API XmlReader поверх любого документа SGML (включая встроенную поддержку HTML). Также предоставляется утилита командной строки, которая выводит правильно сформированный результат XML.
    Загрузите ZIP-файл, включая автономный исполняемый файл и полный исходный код: SgmlReader.zip

  3. Выдающимся достижением является чистый XSLT 2.0 парсер HTML , написанный Дэвидом Карлайлом .

Чтение его кода было бы отличным учебным упражнением для каждого из нас.

Из описания:

"* * д тысяча пятьдесят четыре: htmlparse (строка)
д: htmlparse (строка, пространство имен, HTML-режим)

Форма с одним аргументом эквивалентна)
d: htmlparse (строка, 'http://ww.w3.org/1999/xhtml',true()))

Разбирает строку как HTML и / или XML, используя некоторую встроенную эвристику, чтобы:
контроль подразумевает открытие и закрытие элементов.

Он не обладает полным знанием HTML DTD, но имеет полный список
пустые элементы и полный список определений сущностей. HTML-сущности и
все десятичные и шестнадцатеричные ссылки на символы принимаются. Примечание html-лица
распознаются, даже если html-mode = false ().

Имена элементов в нижнем регистре (если html-mode имеет значение true ()) и помещаются в
пространство имен, указанное в параметре пространства имен (которое может быть "" для обозначения
no-namespace, если у входа нет явных объявлений пространства имен, в
в этом случае они будут выполнены.

Имена атрибутов в нижнем регистре, если html-mode = true ()"

Более подробное описание здесь .

Надеюсь, это помогло.

Приветствия

Димитр Новатчев.

2 голосов
/ 19 ноября 2008

Вероятно, вы хотите что-то вроде парсера Majestic: http://www.majestic12.co.uk/projects/html_parser.php

Есть несколько других опций, которые также могут работать с нестабильным HTML. Html Agility Pack стоит посмотреть, как кто-то еще упомянул.

Я не думаю, что регулярные выражения являются идеальным решением для HTML, поскольку HTML не является контекстно-свободным. Вероятно, они дадут адекватный, хотя и неточный результат; даже детерминистическая идентификация URI - сложная проблема.

1 голос
/ 19 ноября 2008

Я согласен с Крисом Лайвли, потому что HTML часто не очень хорошо сформирован, вам, вероятно, лучше всего использовать регулярное выражение для этого.

href=[\"\'](http:\/\/|\.\/|\/)?\w+(\.\w+)*(\/\w+(\.\w+)?)*(\/|\?\w*=\w*(&\w*=\w*)*)?[\"\']

С здесь на RegExLib должно помочь вам начать

0 голосов
/ 09 марта 2009

Я связал здесь некоторый код, который позволит вам использовать «LINQ to HTML» ...

Ищем синтаксический анализатор C # HTML

0 голосов
/ 19 ноября 2008

Возможно, вам повезет больше с использованием xml, если вы знаете или можете исправить документ, чтобы он был хотя бы правильно сформирован. Если у вас есть хороший html (точнее, xhtml), система xml в .Net должна быть в состоянии справиться с этим. К сожалению, хороший HTML встречается крайне редко.

С другой стороны, регулярные выражения действительно плохи при разборе html. К счастью, вам не нужно обрабатывать полную спецификацию html. Все, о чем вам нужно беспокоиться, это парсинг href= строк для получения URL. Даже это может быть сложно, поэтому я не буду пытаться сделать это сразу. Вместо этого я начну задавать несколько вопросов, чтобы попытаться установить несколько основных правил. Все они в основном сводятся к «Как много вы знаете о документе?», Но здесь говорится:

  • Знаете ли вы, всегда ли текст "href" будет строчным?
  • Вы знаете, будет ли он всегда использовать двойные кавычки, одинарные кавычки или ничего вокруг URL?
  • Всегда ли это действительный URL-адрес или вам необходимо учитывать такие вещи, как '#', операторы javascript и т. П.?
  • Можно ли работать с документом, содержимое которого описывает функции html (т. Е. href= также может находиться в документе и не принадлежать тегу привязки)?
  • Что еще вы можете рассказать нам о документе?
...