我正在尝试自动解析一个网站(例如。在http://www.delhaizedirect.be/nl/Search/Duvel中获取列表中第一项的价格。因此,我得到了HTML,它工作得很好。但是,当我将HTML解析为DOMDocument并应用XPath查询时,我没有得到任何结果。
这是我使用的代码:
Public Function zoekDelhaizePrijs(Artikel As String)
Dim URL As String
URL = "http://www.delhaizedirect.be/nl/Search/" + Artikel
Dim website As Object
Set website = CreateObject("MSXML2.ServerXMLHTTP.6.0")
Call website.Open("GET", URL, False)
Call website.Send("")
Dim XPathQuery As String
XPathQuery = "/html/body/div[1]/div[3]/div[1]/div[1]/div[3]/ul/div[1]/div/div[2]/p[1]"
Dim dom As DOMDocument60
Set dom = New DOMDocument60
dom.async = False
dom.validateOnParse = False
'Debug.Print website.responseText
dom.LoadXML website.responseText
dom.setProperty "SelectionLanguage", "XPath"
Dim node As IXMLDOMNodeList
Set node = dom.SelectNodes(XPathQuery)
Dim title As IXMLDOMNode
For Each title In node
Debug.Print title.Text
Next
End Function有谁知道吗?
先谢谢你,汤姆
发布于 2013-04-02 09:57:54
尽管页面顶部的DOCTYPE将其声明为“XHTML1.0Transition”,但为"Duvel“查询返回的页面甚至不是格式良好的XML。因此,它无法解析为DOMDocument60对象,因此不会返回任何节点。即使设置了XML,这也不会消除文档必须是格式良好的validateOnParse=False的要求。
您可以将来自网站的响应加载到一个字符串中,然后在将其加载到DOMDocument60之前手动将其更正为格式良好的XML。这可能需要一些时间,因为您需要修复一个问题,运行您的函数,然后检查dom.parseError的属性以查找下一个问题。
XHTML文档的问题包括:
&字符未被&实体替换-例如,不带任何值的<option selected="selected" value="/nl/Search/Duvel?NB_REPLY=20&page=1">value="/nl/Search/Duvel?NB_REPLY=20&brand=Delhaize&page=1" -例如,<option selected value="/nl/Search/Duvel?NB_REPLY=20&page=1">替换为未关闭的</p>) -例如,<div><p></p><p></p><p><span><span></span></span></div> (缺少&
还有一些特定的MSXML2问题。默认情况下,DTD在DOMDocument60中是被禁止的,因此在尝试加载dom.setProperty "ProhibitDTD", False之前需要使用DTD。
您的XPath查询也可能会遇到MSXML2的默认名称空间问题-请参阅here (该链接指向MXML4.0,但这个问题在MSXML6.0中仍然存在)。由于页面具有默认的命名空间xmlns="http://www.w3.org/1999/xhtml",因此您需要:
dom.setProperty "SelectionNamespaces", "xmlns:r='http://www.w3.org/1999/xhtml'"对应命名空间前缀,而dom.setProperty "SelectionNamespaces", "xmlns:r='http://www.w3.org/1999/xhtml'"中使用该命名空间前缀或者,您可以尝试将来自网站的响应加载到HTMLDocument中,并使用getElementsByClassName等方法来定位所需的数据。在这种情况下,不要求文档是格式良好的XML
为了让Duvel页面正常工作,我需要做这些替换。该站点上的其他页面可能需要一组不同的替换项。我不会说这是什么最佳实践,但它适用于这个特定的页面。临时重命名标准实体(加上 ),以允许替换文档中不正确的&字符。 被替换为数字等效项:
Dim webResponse As String
webResponse = website.responseText
webResponse = Replace(webResponse, " ", "^nbsp;")
webResponse = Replace(webResponse, "&", "^amp;")
webResponse = Replace(webResponse, "<", "^lt;")
webResponse = Replace(webResponse, ">", "^gt;")
webResponse = Replace(webResponse, """, "^quot;")
webResponse = Replace(webResponse, "'", "^apos;")
webResponse = Replace(webResponse, "&", "&")
webResponse = Replace(webResponse, "^nbsp;", " ")
webResponse = Replace(webResponse, "^amp;", "&")
webResponse = Replace(webResponse, "^lt;", "<")
webResponse = Replace(webResponse, "^gt;", ">")
webResponse = Replace(webResponse, "^quot;", """)
webResponse = Replace(webResponse, "^apos;", "'")
webResponse = Replace(webResponse, "<option selected ", "<option selected=" & Chr$(34) & "selected" & Chr$(34) & " ")
webResponse = Replace(webResponse, " style=>", " style=" & Chr$(34) & Chr$(34) & ">")
webResponse = Replace(webResponse, "]]>", "]]>")
webResponse = Replace(webResponse, "<span>prijs</span></span>", "<span>prijs</span></span></p>")发布于 2013-04-01 23:34:16
这对我来说很有效:
//div[@class="displayProdList"][1]//p[@class="prodListPrice"]https://stackoverflow.com/questions/15745463
复制相似问题