0

我有一大堆 HTML,其中只是一堆:

<li id="entry-c7" data-user="ThisIsSomeonesUsername">
  <img width="28" height="28" class="avatar" src="http://very_long_url.png">
  <span class="time">6:07</span>
  <span class="username">ThisIsSomeonesUsername</span>
  <span class="message">This is my message. It is nice, no?</span>
</li>

一遍又一遍地重复了大约十万次(当然,内容不同)。这一切都是通过检索包含所有这些的元素从 HTMLDocument 中获取的。该文档是从 Windows 窗体中的 WebBrowser 检索的。这看起来像:

HtmlDocument document = webBrowser1.Document;
HtmlElement element = document.GetElementById(chatElementId);

假设“chatElementId”只是一些已知的 ID。我想做的是检索“时间”(本例中为 6:07)、“用户名”(ThisIsSomeonesUsername)和“消息”(这是我的消息......等)中的内容。消息部分几乎可以包含任何内容,包括进一步的 html(如链接、图像等),但我希望保持所有内容不变。我本来打算用正则表达式来解析使用上面方法检索到的元素的InnerHtml,但是显然这会带来宇宙的毁灭。那我应该怎么做呢?

编辑:人们一直在建议 Html Agility Pack,那么有没有一种简单的方法可以在不使用完整 HTML 源的情况下在 Html Agility Pack 中执行此操作?我不确定这个类之外的其余 html 是否都那么好......但是我是否应该只传递整个 html 呢?

4

2 回答 2

1

仅供参考,正则表达式无法以任何可用的方式解析 HTML……正则表达式匹配开放标签,但 XHTML 自包含标签除外,仅适用于那些偶然发现这篇文章的人。

现在根据您的要求,您是否尝试过使用XmlDocumentXDocument

只需尝试以下操作(注意 img 标记缺少 end />),如果在您的 HTML 中是这种情况,这将无法正常工作,因为它的 XML 无效)。

//parse the xml
var xDoc = XDocument.Parse(html);

//create our list of results (basic tuple here, could be your class)
List<Tuple<string, string, string>> attributes = new List<Tuple<string, string, string>>();

//iterate all li elemenets
foreach (var element in xDoc.Root.Elements("li"))
{
    //set the default values
    string time = "",
            username = "",
            message = "";

    //get the time, username message attributes
    XElement tElem = element.Elements("span").FirstOrDefault(x => x.Attributes("class").Count() > 0 && x.Attribute("class").Value == "time");
    XElement uElem = element.Elements("span").FirstOrDefault(x => x.Attributes("class").Count() > 0 && x.Attribute("class").Value == "username");
    XElement mElem = element.Elements("span").FirstOrDefault(x => x.Attributes("class").Count() > 0 && x.Attribute("class").Value == "message");

    //set our values based on element results
    if (tElem != null)
        time = tElem.Value;

    if (uElem != null)
        username = uElem.Value;

    if (mElem != null)
        message = mElem.Value;

    //add to our list
    attributes.Add(new Tuple<string, string, string>(time, username, message));
}
于 2013-11-14T00:35:12.940 回答
1

阅读 Nico 答案的链接......我正要发布同一个(这很有趣)。

话虽如此,从您的评论来看,您似乎打算使用正则表达式。所以,正则表达式它。
应该不难做到。

转到http://regexpal.com/,将数据粘贴到底部,在顶部使用正则表达式部分,直到您对结果感到满意,然后循环您的数据并提取您需要的内容内容。

(我不确定我是否会这样做,但有时快速修复比更长的“正确”答案更好)。

于 2013-11-14T00:42:50.107 回答