什么是从网页中提取值的更有效方法

时间:2012-06-26 17:48:26

标签: .net performance web-scraping

我需要从网站检索一个值(可能会有所不同,我无法控制该网站)。我目前有一些有用的代码......但需要很长时间才能运行。我知道有很多改进的方法,我只是不知道那是什么。

我考虑了几种替代方案,比如Regex和HTMLAgilityPack(似乎很复杂且可能有些过分?)但是如果不尝试每种方法,我不确定什么是最有效的。我相信还有更多的可能性。

问题可能在于我如何检索页面而不是我如何处理它。

    Dim GETURL As WebRequest
    GETURL = WebRequest.Create("http://www.example.com")
    Dim objStream As Stream = GETURL.GetResponse.GetResponseStream()

    Dim objReader As New StreamReader(objStream)
    Dim sLine As String = ""
    Dim a As Integer = 0
    Dim result As String = ""
    Do While Not sLine Is Nothing
        a += 1
        sLine = objReader.ReadLine
        If Not sLine Is Nothing Then
            result += sLine
        End If
    Loop

    Dim startTag as string ="<some html tag>"
    Dim endTag as string ="<closing tag>"
    Dim firstIndex As Integer = result.IndexOf(startTag) + startTag.Length
    result = result.Substring(firstIndex, result.Length - firstIndex)
    Dim RequiredVal As String = result.Substring(0, result.IndexOf(endTag))

请注意,我确实意识到这段代码的效率是多么低效,而不是尝试不同的排列(并且可能仍然有相当低效的代码),我想我会先问一些专家的建议: - )< / p>

更新

由于我没有得到任何回应(也许我的问题有点过于模糊?)我一直在努力提高效率。通过使用WebCient.DownloadString(),我已经设法减少了约50%的运行时间。这很好,但我怀疑我可以改进从页面中提取数据。请参阅以下更新代码:

    Dim client As New WebClient()
    Dim result As String = client.DownloadString("http://www.example.com")

    Dim startTag as string ="<some html tag>"
    Dim endTag as string ="<closing tag>"
    Dim firstIndex As Integer = result.IndexOf(startTag) + startTag.Length
    result = result.Substring(firstIndex, result.Length - firstIndex)
    Dim RequiredVal As String = result.Substring(0, result.IndexOf(endTag))

任何建议都会受到很大的关注。

2 个答案:

答案 0 :(得分:0)

使用WatiN或更好HTML Agility Pack

答案 1 :(得分:0)

如果问题在于等待来自Web请求的响应,那么用于解析它的实际引擎或技术可能与性能相关性要小得多,而不是简单地等待来自Web的每个响应。如果你有一个很长的页面列表,那么你可以通过异步运行同步请求来做得更好。目前尚不清楚这是怎么回事。

尝试CsQuery - 同样在NuGet - jQuery的新C#端口,它可以做你想要的。它具有同步和异步获取数据的方法,因此如果您确实想要启动并行Web请求,它可以直接执行此操作。但是,在最基本的层面上,代码可以同步执行:

CQ doc = CQ.CreateFromUrl("http://www.jquery.com");

string allStuffInsideTag = doc["sometag"].Contents().RenderSelection();

它就像jquery一样。 “CQ”对象与jQuery对象相同。 Contents是返回元素的所有子元素的jQuery方法; RenderSelection是一个CsQuery方法,它呈现选择集中每个元素的完整HTML。所以这将返回全文&amp;每个sometag块内的所有内容的HTML。

它还为所有常见选择器类型索引每个文档,并且比HTML Agility Pack快得多。