Как разобрать этот кусок HTML? - PullRequest
3 голосов
/ 19 января 2010

доброе утро! я использую c # (framework 3.5sp1) и хочу проанализировать следующий фрагмент HTML через регулярное выражение:

<h1>My caption</h1>
<p>Here will be some text</p>

<hr class="cs" />
<h2 id="x">CaptionX</h2>
<p>Some text</p>

<hr class="cs" />
<h2 id="x">CaptionX</h2>
<p>Some text</p>

<hr class="cs" />
<h2 id="x">CaptionX</h2>
<p>Some text</p>

Мне нужен следующий вывод:

  • группа 1: содержание h1
  • группа 2: содержание следующего текста h1
  • группа 3-n: содержание подразделов + текст

что у меня есть в банкомате:

<hr.*?/>
<h2.*?>(.*?)</h2>
([\W\S]*?)
<hr.*?/>

это даст мне каждый нечетный подзаголовок + контент (например, 1, 3, ...) из-за завершающего <hr/>. для разбора h1-заголовка у меня есть другой шаблон (<h1.*?>(.*?)</h1>), который дает мне только заголовок, но не содержимое - я в порядке с этим банкоматом.

У кого-нибудь есть подсказка / решение для меня или любой другой альтернативной логики (например, парсинг html через ридер и назначение его таким образом?)?

редактирование:
как некоторые принесли HTMLAgilityPack , мне было интересно узнать об этом хорошем инструменте. я получил содержимое тега <h1>.
но ... моя проблема разбирает остальное. это вызвано тем, что теги для содержимого могут различаться - от <p> до <div> и <ul> ... АТМ это кажется более или менее итерации по всему документу и разбор тега для тега ...? какие-нибудь намеки?

Ответы [ 4 ]

9 голосов
/ 19 января 2010

Вам действительно понадобится HTML-парсер для этого

6 голосов
/ 19 января 2010

Не используйте регулярные выражения для анализа HTML. Попробуйте использовать HTML Agility Pack .

2 голосов
/ 19 декабря 2011

Есть несколько возможностей:

REGEX - Быстрый, но не надежный, он не может справиться с искаженным html.

HtmlAgilityPack - Хорошо, но есть много утечек памяти. Если вы хотите иметь дело с несколькими файлами, проблем нет.

SGMLReader - Действительно хорошо, но есть проблема. Иногда он не может найти пространство имен по умолчанию, чтобы получить другие узлы, тогда невозможно проанализировать html.

http://developer.mindtouch.com/SgmlReader

Majestic-12 - Хорошо, но не так быстро, как SGMLReader.

http://www.majestic12.co.uk/projects/html_parser.php

Пример для SGMLreader (VB.net)

Dim sgmlReader As New Sgml.SgmlReader()
Public htmldoc As New System.Xml.Linq.XDocument
sgmlReader.DocType = "HTML"
sgmlReader.WhitespaceHandling = System.Xml.WhitespaceHandling.All
sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower
sgmlReader.InputStream = New System.IO.StringReader(vSource)
sgmlReader.CaseFolding = CaseFolding.ToLower
htmldoc = XDocument.Load(sgmlReader)    
Dim XNS As XNamespace 

' In this part you can have a bug, sometimes it cant get the Default Namespace*********
Try
      XNS = htmldoc.Root.GetDefaultNamespace
Catch
        XNS = "http://www.w3.org/1999/xhtml"
End Try
If XNS.NamespaceName.Trim = "" Then
        XNS = "http://www.w3.org/1999/xhtml"
End If

'use it with the linq commands
For Each link In htmldoc.Descendants(XNS + "script")
        Scripts &= link.Value
Next

В Majestic-12 все по-другому, вам нужно пройти к каждому тегу с помощью команды «Далее». Вы можете найти пример кода с помощью dll.

1 голос
/ 19 января 2012

Как уже упоминалось, используйте HtmlAgilityPack. Однако, если вам нравятся селекторы jQuery / CSS, я только что нашел ответвление HtmlAgilityPack под названием Fizzler: http://code.google.com/p/fizzler/ Используя это, вы можете найти все <p> теги, используя:

var pTags = doc.DocumentNode.QuerySelectorAll('p').ToList();

Или найдите конкретный элемент типа <div id="myDiv"></div>:

var myDiv = doc.DocumentNode.QuerySelectorAll('#myDiv');

Это не может быть проще, чем это!

...