【问题标题】:VB.net parsing HTML TV listingsVB.net 解析 HTML 电视列表
【发布时间】:2012-10-15 04:57:59
【问题描述】:

我从电视列表页面抓取了以下 HTML 代码:

<div class="channel_row">
   <span class="channel">                            
    <div class="logo"><img src ="/images/channel_logos/WGNAMER.png" /></div>                            
    <p><strong>2</strong><br />
    WGNAMER
    </p>
   </span>                          

   <span class="time" style="width:0.0px;padding:0;height:42px;">
     <div style="margin:10px">
       <a class="thickbox" style="" href="/tv/info/?program_id=49909&height=260&width=612" title="WGN News at Nine">WGN News at Nine</a>                                     
       <p class="schedule_flags"><strong class="new_flag">New</strong>, <strong class="cc_flag">CC</strong>, <strong class="stereo_flag">Stereo</strong></p>
     </div>
   </span>                          
   <span class="time" style="width:245.6px;padding:0;height:42px;">
     <div style="margin:10px">
       <a class="thickbox" style="" href="/tv/info/?program_id=49910&height=260&width=612" title="America&#39;s Funniest Home Videos">America&#39;s Funniest Home Videos</a>                                     
       <p class="schedule_flags"><strong class="cc_flag">CC</strong>, <strong class="stereo_flag">Stereo</strong></p>
     </div>
   </span>                          
</div>

它只是一遍又一遍地与 channel_row 循环......

现在我已经在 HtmlAgilityPack 的帮助下设置了一些 VB 代码,希望有一种快速简便的方法来循环所有这些类并获取 徽标图像、电视频道、电台名称,更多节目描述和节目标题的HREF

所以在上面的例子中,解析应该是这样的:

/images/channel_logos/WGNAMER.png
2
WGNAMER
/tv/info/?program_id=49909&height=260&width=612
WGN News at Nine

/tv/info/?program_id=49910&height=260&width=612
America&#39;s Funniest Home Videos

我的VB代码是:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim htmlString As String = "<div class=""channel_row"">" & _
                   "<span class=""channel"">" & _
                           "<div class=""logo""><img src =""/images/channel_logos/WELF.png"" /></div>" & _
                       "<p><strong>13</strong><br />" & _
  "WELF" & _
                       "</p>" & _
                   "</span>" & _
                       "<span class=""time"" style=""width:245.6px;padding:0;height:42px;"">" & _
                           "<div style=""margin:10px"">" & _
                               "<a class=""thickbox"" style="""" href=""/tv/info/?program_id=35424&height=260&width=612"" title=""Praise the Lord"">Praise the Lord</a>" & _
                               "<p class=""schedule_flags""><strong class=""cc_flag"">CC</strong></p>" & _
                           "</div>" & _
                       "</span>" & _
                       "<span class=""time"" style=""width:122.8px;padding:0;height:42px;"">" & _
                           "<div style=""margin:10px"">" & _
                               "<a class=""thickbox"" style="""" href=""/tv/info/?program_id=35425&height=260&width=612"" title=""ACLJ This Week"">ACLJ This Week</a> " & _
                               "<p class=""schedule_flags""><strong class=""cc_flag"">CC</strong></p>" & _
                           "</div>" & _
                       "</span>" & _
                       "<span class=""time"" style=""width:122.8px;padding:0;height:42px;"">" & _
                           "<div style=""margin:10px"">" & _
                               "<a class=""thickbox"" style="""" href=""/tv/info/?program_id=35426&height=260&width=612"" title=""Full Flame"">Full Flame</a>  " & _
                               "<p class=""schedule_flags""><strong class=""cc_flag"">CC</strong></p>" & _
                           "</div>" & _
                       "</span>" & _
                       "<span class=""time"" style=""width:0.0px;padding:0;height:42px;"">" & _
                           "<div style=""margin:10px"">" & _
                               "<a class=""thickbox"" style="""" href=""/tv/info/?program_id=35427&height=260&width=612"" title=""Secrets: Kim Clement"">Secrets: Kim Clement</a>                                     " & _
                               "<p class=""schedule_flags""></p>" & _
                           "</div>" & _
                       "</span>" & _
               "</div>"


    Dim doc = New HtmlAgilityPack.HtmlDocument()
    Dim htmlDocument As IHTMLDocument2 = New HTMLDocumentClass()
    htmlDocument.write(htmlString)
    htmlDocument.close()

    doc.LoadHtml(String.Format(htmlString))
    Dim res = doc.DocumentNode.SelectNodes("//div[@class='channel_row']")

    For Each item In res
        Dim firstDiv = item.SelectSingleNode(".//div[@class='channel']")
        Dim content1 = firstDiv.ChildNodes(0).InnerText.Trim()
        Dim content2 = firstDiv.ChildNodes(1).InnerText.Trim()
        Dim content4 = item.SelectSingleNode(".//div[@class='myclass2']")
    Next
End Sub

目前错误出现在 Dim content1 = firstDiv.ChildNodes(0).InnerText.Trim() 行上:

对象引用未设置为对象的实例。

任何帮助都会很棒!

更新

最新的代码建议:

Dim doc = New HtmlAgilityPack.HtmlDocument()
doc.LoadHtml(htmlString)

Dim all = new Dictionary(of String, Object)()
For Each channel In doc.DocumentNode.SelectNodes(".//div[@class='channel_row']") 
    Dim info = new Dictionary(of String, Object)()

    With channel

        info!Logo    = .SelectSingleNode(".//img").Attributes("src").Value
        info!Channel = .SelectSingleNode(".//span[@class='channel']").ChildNodes(1).ChildNodes(0).InnerText
        info!Station = .SelectSingleNode(".//span[@class='channel']").ChildNodes(1).ChildNodes(2).InnerText

        info!Shows = From tag In .SelectNodes(".//a[@class='thickbox']")
                     Select New With {.Show = tag.Attributes("title").Value, .Link = tag.Attributes("href").Value}

    End With

    all.Add(info!Station, info)
Next 

all.Dump()

有3个错误:

1) 上线Select New With {.Show = Tag.Attributes("title").Value, .Link = Tag.Attributes("href").Value}

错误是:“Select Case”必须以匹配的“End Select”结尾。

2) 上线all.Add(info!Station, info)

错误是:语句和标签在“Select Case”和第一个“Case”之间无效。

3) 上线all.Dump()

错误是:'Dump'不是'System.Collections.Generic.Dictionary(Of String, Object)'的成员。

【问题讨论】:

  • 仍在寻找可行的解决方案。
  • 确保您已导入命名空间System.Linq。正如我已经说过的,您可以使用任何其他类型来代替匿名类型。另外,我已经告诉过您,Dump() 扩展方法是 LINQPad 的一部分,因此如果您在 Visual Studio(或 LINQPad 之外的任何地方)中编译代码,很明显找不到该方法。您显然也不需要该调用,因为该方法所做的只是将对象转储到 LINQPad 的输出窗口。
  • @Mr.Steak 好的,它可以导入它,但是我如何从 Shows 中获取值来显示?我已经尝试过 msgbox(info.Shows) 和 msgbox(info.Shows.show) 但我无法从仅此错误中得到任何信息。我如何获得节目和链接?

标签: vb.net parsing html-parsing html-agility-pack


【解决方案1】:

我不是 HtmlAgilityPack 专家,但是如何:

Dim htmlString As String = "<div class=""channel_row"">" &  _ ...

Dim doc = New HtmlAgilityPack.HtmlDocument()
doc.LoadHtml(htmlString)

Dim all = new Dictionary(of String, Object)()
For Each channel In doc.DocumentNode.SelectNodes(".//div[@class='channel_row']") 
    Dim info = new Dictionary(of String, Object)()

    With channel

        info!Logo    = .SelectSingleNode(".//img").Attributes("src").Value
        info!Channel = .SelectSingleNode(".//span[@class='channel']").ChildNodes(1).ChildNodes(0).InnerText
        info!Station = .SelectSingleNode(".//span[@class='channel']").ChildNodes(1).ChildNodes(2).InnerText

        info!Shows = From tag In .SelectNodes(".//a[@class='thickbox']")
                     Select New With {.Show = tag.Attributes("title").Value, .Link = tag.Attributes("href").Value}

    End With

    all.Add(info!Station, info)
Next 

all.Dump()

【讨论】:

  • Select Tuple.Createinfo.Dump()shows.ToList().Dump() 有问题?
  • 你能解释一下除了使用元组之外的另一种方法吗?
  • 这似乎也没有通过 channel_row 的每个 id 循环,它只执行一次,仅此而已。
  • @StealthRT 你没有说你使用的是哪个框架版本。 Tuple 是在 .NET 4.0 中添加的,所以我猜您使用的是 3.5 或其他版本。我用匿名类型替换了代码中Tuple 的使用,但您当然可以使用任何其他类型。也许只是创建一个类来保存值,但它会使这个例子膨胀。
  • @StealthRT Dump() 扩展方法是LINQPad 的一部分,您可以使用它在没有 Visual Studio 的情况下运行 .NET 代码。你应该试一试。我的代码适用于您提供的示例 html;尽管如此,我还是将其更新为使用 For Each 循环遍历多个 channel_row 元素,如您所见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 2011-09-07
  • 2011-09-13
  • 2016-09-03
  • 1970-01-01
  • 1970-01-01
  • 2016-07-14
相关资源
最近更新 更多