【问题标题】:VB.net searching through HTML codeVB.net 通过 HTML 代码搜索
【发布时间】:2016-06-08 13:13:05
【问题描述】:

我正在创建一个程序,它将搜索页面 HTML 源代码并返回是否存在指定的字符串,尽管它总是返回 false,如果我遗漏了什么,有人可以看看吗?

Private Const QUOTE As Char = """"c

Private Sub ServerStatus_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    'download the page source and store it here
    Dim sourceString As String = New System.Net.WebClient().DownloadString("https://support.rockstargames.com/hc/en-us/articles/200426246")

    'call the source and validate a string exists, if not
    If (sourceString).Contains($"<div class={QUOTE}panel-base xbl{QUOTE} style={QUOTE}background-color: RGB(236, 255, 236);{QUOTE}><div class={QUOTE}marshmallowLogo{QUOTE} id={QUOTE}xboxLogo{QUOTE}>Xbox 360</div><center><span class={QUOTE}statusSpan{QUOTE} style={QUOTE}color green;{QUOTE}>Up</span></center>") = True Then
        Label1.Text = "It's there"
        ' if it does
    ElseIf (sourceString).Contains($"<div class={QUOTE}panel-base xbl{QUOTE} style={QUOTE}background-color: RGB(236, 255, 236);{QUOTE}><div class={QUOTE}marshmallowLogo{QUOTE} id={QUOTE}xboxLogo{QUOTE}>Xbox 360</div><center><span class={QUOTE}statusSpan{QUOTE} style={QUOTE}color green;{QUOTE}>Up</span></center>") = False Then
        Label1.Text = "It's not"
    End If

End Sub

结束类

【问题讨论】:

  • 那个 html 在那个页面上不存在,所以它看起来对我来说工作正常
  • 请注意,您不需要elseif,只需else 即可获得相同的结果
  • 我在 chrome 上使用了检查元素,这就是我得到它的方式,所以我不确定发生了什么。
  • 试试右键-查看源码
  • 您要查找的div 是由页面中的Javascript 动态创建的。 AFAIK 你不能使用WebClient 来执行脚本,所以这个方法不起作用。

标签: html vb.net


【解决方案1】:

所以我花了几分钟分析页面(不客气),正如评论中所指出的,数据是通过 javascript 加载的,并且不存在于原始 URL 返回的基本 html 中。我还不是 100% 确定,但我想你真的想看看这个地址:

https://supportfiles.rockstargames.com/support/serverStatus.json

返回如下响应:

jsonCallbackStatus(
    {
        "statuses":

            {
                "psnUpOrDownOverride": "",
                "ps4UpOrDownOverride": "",
                "xboxUpOrDownOverride": "",
                "xboxOneUpOrDownOverride": "",
                "rgscUpOrDownOverride": "",
                "psnWarningOverrideMessage": "",
                "ps4WarningOverrideMessage": "",
                "xboxWarningOverrideMessage": "",
                "xboxOneWarningOverrideMessage": "",
                "rgscWarningOverrideMessage": "",
                "pcWarningOverrideMessage": "",
                "pcUpOrDownOverride": "",
                "giantWarningOverrideMessage": ""
            },

    }
);

如果我没看错的话,每个项目旁边的空字符串意味着没有错……没有消息就是好消息。这应该比所有 html 更容易解析 :) 不要忘记查看平台的警告和 up/down 状态,以及 giantWarningOverrideMessage

我是如何找到这个地址的

这样的数据几乎总是以以下三种方式之一出现:json、rss(或类似的 xml)或 Web 服务(soap)。 web服务一般会在服务端加载解析,然后和html一起发送,而rss在javascript中更难解析,最近不太流行,所以我先用json。

我首先在 chrome 中打开页面。然后我打开开发者工具 (F12) 并选择 Network 选项卡。现在,当我刷新页面时,我会获得从该页面的网络服务器下载的每个项目的列表。1 然后我通过查看 javascript 下载(JS 中的按钮工具栏...我正在寻找 json 响应)。这给了我合理数量的项目,我可以通过仅查看200 状态响应来进一步缩小搜索范围,其中我只看到了两个:都来自这个地址。

请注意,完整地址实际上如下所示:

https://supportfiles.rockstargames.com/support/serverStatus.json?callback=jsonCallbackStatus&callback=jsonCallbackStatus&_=1465445182216

页面中有一个错误,因为两次使用 callback url 参数是没有意义的,尤其是使用相同的值。我只是因为_ url 参数才提出这个问题。去掉该值的最后 3 位数字,您最终会得到一个恰好与今天日期匹配的 unix 时间戳。您可能希望生成一个包含这样时间戳的 url,因为 Rockstar 可能会使用服务器上的时间戳来避免提供缓存的响应。如果服务器现在关闭,您会讨厌在一小时前一切正常时获得缓存的响应。

最后提醒:我不能 100% 确定这是您需要的数据。它可能来自另一个请求。但这就是你免费获得的全部 :) 希望我写到这一步的方法足以让你自己做侦探工作来验证结果。

当然,您也可以选择使用 WebBrowser 控件,该控件将运行 javascript。但它方式变慢了,你又要解析丑陋的 html,任何小的 html 更改都会破坏你的代码(而 json 结果可能会通过多次网站重新设计而存在)。

读取数据的源代码

Dim unixTime As ULong = (DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0)).TotalMilliSeconds
Using wc As New WebClient(),
      rdr As New StreamReader(wc.OpenRead($"https://supportfiles.rockstargames.com/support/serverStatus.json?_={unixTime}"))

    Dim line = rdr.ReadLine()
    While line IsNot Nothing
        line = line.Trim()
        If line.StartsWith("""xboxUpOrDownOverride") Then
            Dim parts = line.Split(":".ToCharArray())
            parts(1) = Regex.Replace(parts(1), "[ "",]", "")
            If parts(1).Length > 0 Then
                Console.WriteLine("Up/Down Failed")
            Else
                Console.WriteLine("Up/Down Okay")
            End If
        End If
        If line.StartsWith("""xboxWarningOverrideMessage") Then
            Dim parts = line.Split(":".ToCharArray())
            parts(1) = Regex.Replace(parts(1), "[ "",]", "")
            If parts(1).Length > 0 Then
                Console.WriteLine("Warning Failed")
            Else
                Console.WriteLine("Warning Okay")
            End If
        End If
        If line.StartsWith("""giantWarningOverrideMessage") Then
            Dim parts = line.Split(":".ToCharArray())
            parts(1) = Regex.Replace(parts(1), "[ "",]", "")
            If parts(1).Length > 0 Then
                Console.WriteLine("Giant Warning Failed")
            Else
                Console.WriteLine("Giant Warning Okay")
            End If
        End If
        line = rdr.ReadLine()
    End While

您还应该考虑使用真正的 json 解析器(通过 NuGet 很容易做到),因为即使是像添加最小化器这样简单的事情也会通过将所有内容集中到一行来破坏现有代码。


1 下载了很多 很多 东西。 Rockstar 应该投资一个捆绑器,以最大限度地减少 http 请求,以实现更快的页面加载和更低的带宽,尤其是在移动设备上。

【讨论】:

  • 非常感谢!我并没有真正深入研究这个,但现在我回顾了这个网站,你帮了我很大的忙!
【解决方案2】:

无法使用VS2015(VB14)的人参考代码:

Private Const QUOTE As Char = """"c

Private Sub ServerStatus_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    'download the page source and store it here
    Dim sourceString As String = New System.Net.WebClient.DownloadString("https://support.rockstargames.com/hc/en-us/articles/200426246")

    'call the source and validate a string exists, if not

Label1.Text = If(sourceString.Contains(String.Format(
"<div class={0}panel-base xbl{0} style={0}background-color: RGB(236, 255, 236);{0}><div class={0}marshmallowLogo{0} id={0}xboxLogo{0}>Xbox 360</div><center><span class={0}statusSpan{0} style={0}color green;{0}>Up</span></center>",
QUOTE)),"It's there", "It's not")

    End If
End Sub
End Class

【讨论】:

  • 他正在使用 Visual Basic 14 中全新的字符串插值语言功能。它可以与最新的 Visual Studio 2015 完美编译。
  • @Joel 没有使用 VS2015,因为它无法安装...等待新的 VS。
  • @Joel Coehoorn 我应该删除这个答案吗?
  • 你会等一会儿。从事物的声音来看,MS 将通过功能包和增量更新推进 VS 几个周期,因此他们可以将开发时间投入到 .Net 核心和 Roslyn 中。
  • 不...这对那些还不能使用 VB 14 的人很有用。我不会投赞成票,但我也不会投反对票。
猜你喜欢
  • 1970-01-01
  • 2017-02-10
  • 2013-07-24
  • 2015-10-17
  • 2011-09-26
  • 2016-04-26
  • 2011-01-17
  • 2013-09-27
  • 1970-01-01
相关资源
最近更新 更多