2014-06-19 23 views
0

我对htmlagilitypack有点新。我想用我的HttpWebRequest,它可以返回一个网页的HTML,然后用htmlagilitypack解析这个HTML。我想找到所有div的特定课程,然后获取这些div的内部文本。这是我迄今为止所拥有的。我的get请求成功返回网页html:HtmlAgilityPack找不到来自HttpWebRequest的返回HTML的节点

Public Function mygetreq(ByVal myURL as String, ByRef thecookie As CookieContainer) 
     Dim getreq As HttpWebRequest = DirectCast(HttpWebRequest.Create(myURL), HttpWebRequest) 
     getreq.Method = "GET" 
     getreq.KeepAlive = True 
     getreq.CookieContainer = thecookie 
     getreq.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0" 

     Dim getresponse As HttpWebResponse 
     getresponse = DirectCast(getreq.GetResponse, HttpWebResponse) 


     Dim getreqreader As New StreamReader(getresponse.GetResponseStream()) 
     Dim thePage = getreqreader.ReadToEnd 

     'Clean up the streams and the response. 
     getreqreader.Close() 
     getresponse.Close() 


     Return thePage 
    End Function 

该函数返回html。然后我把HTML到这一点:

 'The html successfully shows up in the RichTextBox 
     RichTextBox1.Text = mygetreq("http://someurl.com", thecookie) 

     Dim htmldoc = New HtmlAgilityPack.HtmlDocument() 

     htmldoc.LoadHtml(RichTextBox1.Text) 

     Dim htmlnodes As HtmlNodeCollection 
     htmlnodes = htmldoc.DocumentNode.SelectNodes("//div[@class='someClass']") 


     If htmlnodes IsNot Nothing Then 
      For Each node In htmlnodes 
       MessageBox.Show(node.InnerText()) 
      Next 
     End If 

的问题是,htmlnodes是回来为null。所以最后的If Then循环将不会运行。它觉得没有什么,但我知道一个事实,这divclass存在于HTML页面,因为我可以看到在RichTextBox1的HTML:

<div class="someClass"> This is inner text </div>

到底是什么问题吗? htmldoc.LoadHtml不喜欢mygetreq为页面html返回的字符串类型吗?

这和html实体有什么关系吗? thePage包含<>括号。他们没有实习。

我还看到有人发帖here(C#)使用HtmlWeb类,但我不知道如何设置它。我的大部分代码已经写入httpWebRequest

感谢您的阅读并感谢您的帮助。

+0

一如既往,我建议使用CsQuery而不是HtmlAgilityPack。其中一位SO成员也提到过,一旦尝试过,我不想回去。 – Neolisk

+0

@neolisk从未听说过。我只是不断听到HtmlAgilityPack。任何好的示例代码在那里为我正在尝试做的,你可能已经可用? =) – Micro

+0

同样在这里,我总是在我尝试[CsQuery]之前推荐HtmlAgilityPack(https://github.com/jamietre/CsQuery)。你知道jQuery吗?如果是的话,应该是一个简单的开关。我会尽快为你带来一些例子。 – Neolisk

回答

1

如果你愿意转换,你可以使用CsQuery,东西沿着这些线路:

Dim q As New CQ(mygetreq("http://someurl.com", thecookie)) 
For Each node In q("div.someClass") 
    Console.WriteLine(node.InnerText) 
Next 

您可能要添加一些错误处理,但总体应该是一个良好的开端为您服务。

您可以通过添加的NuGet到CsQuery项目:

Install-Package CsQuery 

而且不要忘了在你的代码文件的顶部使用Imports CsQuery

这可能不会直接解决您的问题,但应该更容易实验您的数据(例如通过直接窗口)。

有趣的阅读(性能比较):

+0

即使我尝试使用CsQuery,嗯仍然不适用于我。我不知道这是'mygetreq'返回'thepage'的方式。它将所有内容变成html实体,除了括号'<' and '>'。 'thepage'的结果你认为呢?我做对了吗? – Micro

+0

也就是说,它没有找到任何具有'div.somecClass'的节点。它表示在我的错误检查中它是空的。 – Micro

+0

我认为这可能是因为我正在寻找的'div'在评论块内! ''所以它没有找到它们? – Micro

0

使用htmlweb是真实地简单和很好的方式与HtmlAgilityPack ......这里工作是一个例子:

Private Sub GetHtml() 
    Dim HtmlWeb As New HtmlWeb 
    Dim HtmlDoc As HtmlDocument 
    Dim NodeCollection As HtmlNodeCollection 
    Dim URL As String = "" 
    HtmlDoc = HtmlWeb.Load(URL) 'Notice that i used load, and not LoadHtml 
    NodeCollection=HtmlDoc.DocumentNode.SelectNodes(put here your XPath) 
    For Each Node As HtmlNode In NodeCollection 
     If IsNothing(Node) = False Then 
      MsgBox(Node.InnerText) 
     End If 
    Next 
End Sub 
+1

但是,如何为POST和GET请求设置'HtmlWeb.Load()'的URL?我怎样才能为'HtmlWeb'指定现有的Cookie? – Micro

+0

在您的代码中,myURL是一个参数,因此您只需将myURL放入HtmlWeb.Load()中,然后使用XPath就可以选择所需的标签。你为什么要使用cookies?你说过“我想找一个特定类的所有div,然后得到这些div内的东西的内部文本。” – ILoveMom

+2

因为我无法在未启用Cookie的情况下访问URL。我从我的'httpwebrequest'预设了cookies,我必须使用它来访问该网站。 – Micro