2012-06-26 25 views
2

提取值的更有效的方法,我需要从网站检索的值(可以改变,我必须在现场无法控制)。我目前有一些代码可行,但需要很长时间才能运行。我知道这样做有很大的改进,我只是不知道那是什么。什么是从网页

我考虑了几种方案像正则表达式和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)) 

请注意,我不知道这个代码是多么可怕效率低下,而不是尝试不同排列的负载(和可能仍然有相当低效的代码),我想我会问一些专家为他们出谋划策第一:-)

UPDATE:(?也许我的问题是有点过于模糊)

,因为我没有得到任何回应,我一直在努力提高自己的效率。通过使用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)) 

任何建议将大大apprieciated。

回答

0

如果你的问题是等待来自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。因此,这将返回sometag块内的所有内容的全文&。

而且它索引的每个文档的所有常见类型的选择,比HTML敏捷性包快得多。

+0

谢谢。TBH我不确定问题是等待响应还是处理。但是,现在,你提到它,这很可能是需要花费时间的请求。我没有很长的名单(至少在时间问题上)。最多会有10个请求。做异步请求可能是一个选项,虽然它可能会有点混乱,因为我需要它们都返回一个值,然后继续前进。如您所说,CsQuery当然看起来像是一个优雅的解决方案,并且如果它比Agility快,那么会让人印象深刻。 – Gravitate

+0

管理等待所有异步回调应该不会太难。在C#5中,你可以使用'Tasks.WaitAll':http://msdn.microsoft.com/en-us/library/dd270695.aspx ..个人我仍然使用VS2010,所以我没有在CsQuery中实现类似的东西,请参阅When.All:https://github.com/jamietre/csquery#promises CsQuery比选择器的HAP快得多,实际上我只是跑了一些数字:http://blog.outsharked.com/2012/06/ csquery-performance-vs-fizzler.html,但又一次 - 取决于你提取的内容和页面的大小 - 你可能只是在等待服务器。 –

+0

嗨,对不起,暂时还没有试图解决一些汽车故障。我认为我可能会请求并处理一次关键页面,然后在向用户发送响应之后处理其余部分。然后,我会看到响应时间是什么样的,如果我需要进一步优化(我会在某些时候做),会记住你的建议。你的许多建议对其他项目也很有帮助,所以非常感谢你的意见。 – Gravitate

0

使用WatiN或更好的HTML Agility Pack

+0

嗨,谢谢你。我之前没有看到过WatiN,我不认为它适合特定的问题,但它对另一个项目看起来很有趣。我同意HTML敏捷包是一种可能性。我只是担心添加一个像这样的整个库对于这个小函数来说是过分的。在我学会使用它之前,它有可能是一个很大的改进吗? – Gravitate