html - Excel VBA Web Scraping在MSXML2.XMLHTTP方法中返回错误的文本

标签 html excel vba web-scraping

我正在尝试从此 URL 中提取电影描述,
"https://ssl.ofdb.de/plot/138627,271359,I-Am-Legend "

当我使用 CreateObject("InternetExplorer.Application") 方法时,它会为我提供正确的 Web 字符串,就像在网站中直观地看到的那样(这种方法很慢)

但是如果我使用 MSXML2.XMLHTTP,一些返回的文本或不可读的文本(但这种方法很快)

第一种方法的输出:(没问题)

罗伯特·内维尔 (Will Smith) 与 Wissenschaftler 的 war ,aber auch er konnte nicht verhindern,dass ein Virus vor 3 Jahren die gesamte Menschheit befiel。 Nur er wurde aus unbekannten Gründen verschont und hat es sich inzwischen in einer mehr verwahrlosenden Umgebung eingerichtet。 Doch die Bedrohung wächst ständig under er versucht ein Gegensenrum zu entwickeln...

第二种方法的输出:

罗伯特·内维尔 (Will Smith) 与 Wissenschaftler 的 war ,aber auch er konnte nicht verhindern,dass ein Virus vor 3 Jahren die gesamte Menschheit befiel。 Nur er wurde aus unbekannten Gründen verschont und hat es sich inzwischen in einer immer mehr verwahrlosenden Umgebung eingerichtet.Tagsüber kann er sich verhältnismässig frei bewegen, aber nachts lauern überall Gefahren durch vampirähnliche infizierte Gestalten, die nur das Sonnenlicht fern halten坎恩Doch die Bedrohung wächst ständig under versucht ein Gegensrum zu entwickeln...

如您所见,第二种方法中存在一些 unicode 文本。

在这里我附上第二种方法代码,任何想法如何获得与网站上看到的相同的文本?

Link_3 = "https://ssl.ofdb.de/plot/138627,271359,I-Am-Legend"

    'required VBE (Alt+F11) > Tools > References > Microsoft HTML Object Library

    Set xhr = New MSXML2.XMLHTTP60
    Set html = New MSHTML.HTMLDocument

    With xhr
        .Open "GET", Link_3, False
        .setRequestHeader "Content-Type", "text/html; charset=none"
        .send
         html.body.innerHTML = StrConv(.responseBody, vbUnicode)
    End With

Dim sana As String
sana = html.getElementsByClassName("Blocksatz")(0).getElementsByTagName("font")(0).getElementsByTagName("b")(0).innerText
ActiveSheet.Cells(1, 4).Value = Application.WorksheetFunction.Clean(Trim(Application.WorksheetFunction.Substitute(html.getElementsByClassName("Blocksatz")(0).getElementsByTagName("font")(0).innerText, sana, ""))) 
Set xhr = Nothing
 Set html = Nothing

最佳答案

您想从返回的字节字符串而不是 unicode 中获得 UTF-8。您可以使用我从 here 获取的帮助函数,如下所示。 .这是 64 位版本。我将把 32 位留在底部。你也可以使用更有针对性的css选择器来获取你的节点;这将更快并避免额外的字符串清理函数调用。

Option Explicit


''' Maps a character string to a UTF-16 (wide character) string
Private Declare PtrSafe Function MultiByteToWideChar Lib "kernel32" ( _
    ByVal CodePage As Long, _
    ByVal dwFlags As Long, _
    ByVal lpMultiByteStr As LongPtr, _
    ByVal cchMultiByte As Long, _
    ByVal lpWideCharStr As LongPtr, _
    ByVal cchWideChar As Long _
    ) As Long
' CodePage constant for UTF-8
Private Const CP_UTF8 = 65001

''' Return length of byte array or zero if uninitialized
Private Function BytesLength(abBytes() As Byte) As Long
    ' Trap error if array is uninitialized
    On Error Resume Next
    BytesLength = UBound(abBytes) - LBound(abBytes) + 1
End Function

''' Return VBA "Unicode" string from byte array encoded in UTF-8
Public Function Utf8BytesToString(abUtf8Array() As Byte) As String
    Dim nBytes As Long
    Dim nChars As Long
    Dim strOut As String
    Utf8BytesToString = ""
    ' Catch uninitialized input array
    nBytes = BytesLength(abUtf8Array)
    If nBytes <= 0 Then Exit Function
    ' Get number of characters in output string
    nChars = MultiByteToWideChar(CP_UTF8, 0&, VarPtr(abUtf8Array(0)), nBytes, 0&, 0&)
    ' Dimension output buffer to receive string
    strOut = String(nChars, 0)
    nChars = MultiByteToWideChar(CP_UTF8, 0&, VarPtr(abUtf8Array(0)), nBytes, StrPtr(strOut), nChars)
    Utf8BytesToString = Left$(strOut, nChars)
End Function

Public Sub test()

    Dim xhr As MSXML2.XMLHTTP60: Set xhr = New MSXML2.XMLHTTP60
    Dim html As MSHTML.HTMLDocument: Set html = New MSHTML.HTMLDocument

    With xhr
        .Open "GET", "https://ssl.ofdb.de/plot/138627,271359,I-Am-Legend", False
        .send
         html.body.innerHTML = Utf8BytesToString(.responseBody)
    End With

    [A1] = html.querySelector("p.Blocksatz").innerText
 
End Sub

32 位:
Private Declare Function MultiByteToWideChar Lib "kernel32" ( _
    ByVal CodePage As Long, _
    ByVal dwFlags As Long, _
    ByVal lpMultiByteStr As Long, _
    ByVal cchMultiByte As Long, _
    ByVal lpWideCharStr As Long, _
    ByVal cchWideChar As Long _
    ) As Long

关于html - Excel VBA Web Scraping在MSXML2.XMLHTTP方法中返回错误的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61578926/

相关文章:

c# - VSTO AddIn for Excel - 如何防止自定义任务 Pane 失去焦点?

c# - 从 C# 中的 excel 中读取列索引和列值

vba - 命名范围字符串限制

html - 如何使用 HTML 和 CSS 将 14 张图片放在两个垂直列中,每张图片下方都有一个标题,并且图片也排在每一行上?

php - 从 MP3 PHP 获取专辑封面

javascript - 如何下载 HTML5 Canvas 的背景图像?

excel - 如何创建一个列出包含 "yes"的先前字段的标题的字段?

html - 微博 : Content Overlaps Fixed Header?

Excel:检查工作簿内的工作表依赖性?

excel - 选择 'save' 时如何使宏运行?