首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对DOMDocument的超文本标记语言响应

对DOMDocument的超文本标记语言响应
EN

Stack Overflow用户
提问于 2013-04-01 22:37:31
回答 2查看 4.3K关注 0票数 2

我正在尝试自动解析一个网站(例如。在http://www.delhaizedirect.be/nl/Search/Duvel中获取列表中第一项的价格。因此,我得到了HTML,它工作得很好。但是,当我将HTML解析为DOMDocument并应用XPath查询时,我没有得到任何结果。

这是我使用的代码:

代码语言:javascript
复制
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

有谁知道吗?

先谢谢你,汤姆

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-02 09:57:54

尽管页面顶部的DOCTYPE将其声明为“XHTML1.0Transition”,但为"Duvel“查询返回的页面甚至不是格式良好的XML。因此,它无法解析为DOMDocument60对象,因此不会返回任何节点。即使设置了XML,这也不会消除文档必须是格式良好的validateOnParse=False的要求。

您可以将来自网站的响应加载到一个字符串中,然后在将其加载到DOMDocument60之前手动将其更正为格式良好的XML。这可能需要一些时间,因为您需要修复一个问题,运行您的函数,然后检查dom.parseError的属性以查找下一个问题。

XHTML文档的问题包括:

  • &字符未被&amp;实体替换-例如,不带任何值的<option selected="selected" value="/nl/Search/Duvel?NB_REPLY=20&page=1">
  • tags替换为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> (缺少&amp;

还有一些特定的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'"对应命名空间前缀,而
  • 在XPath查询dom.setProperty "SelectionNamespaces", "xmlns:r='http://www.w3.org/1999/xhtml'"中使用该命名空间前缀

或者,您可以尝试将来自网站的响应加载到HTMLDocument中,并使用getElementsByClassName等方法来定位所需的数据。在这种情况下,不要求文档是格式良好的XML

为了让Duvel页面正常工作,我需要做这些替换。该站点上的其他页面可能需要一组不同的替换项。我不会说这是什么最佳实践,但它适用于这个特定的页面。临时重命名标准实体(加上&nbsp;),以允许替换文档中不正确的&字符。&nbsp;被替换为数字等效项:

代码语言:javascript
复制
Dim webResponse As String
webResponse = website.responseText
webResponse = Replace(webResponse, "&nbsp;", "^nbsp;")
webResponse = Replace(webResponse, "&amp;", "^amp;")
webResponse = Replace(webResponse, "&lt;", "^lt;")
webResponse = Replace(webResponse, "&gt;", "^gt;")
webResponse = Replace(webResponse, "&quot;", "^quot;")
webResponse = Replace(webResponse, "&apos;", "^apos;")

webResponse = Replace(webResponse, "&", "&amp;")

webResponse = Replace(webResponse, "^nbsp;", "&#160;")
webResponse = Replace(webResponse, "^amp;", "&amp;")
webResponse = Replace(webResponse, "^lt;", "&lt;")
webResponse = Replace(webResponse, "^gt;", "&gt;")
webResponse = Replace(webResponse, "^quot;", "&quot;")
webResponse = Replace(webResponse, "^apos;", "&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, "]]&gt;", "]]>")
webResponse = Replace(webResponse, "<span>prijs</span></span>", "<span>prijs</span></span></p>")
票数 1
EN

Stack Overflow用户

发布于 2013-04-01 23:34:16

这对我来说很有效:

代码语言:javascript
复制
//div[@class="displayProdList"][1]//p[@class="prodListPrice"]
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15745463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档