【问题标题】:Parsing Google Books JSON to obtain book info by entering ISBN in EXCEL with VBA使用 VBA 在 EXCEL 中输入 ISBN 解析 Google Books JSON 以获取图书信息
【发布时间】:2019-06-06 21:52:58
【问题描述】:

我构建了一个 VBA 代码,以便通过输入我之前使用我的手机使用条形扫描仪应用扫描的图书的 ISBN 代码从 Google Books API 获取数据。 使用VBA-JSON 库,一切似乎都还可以,但我仍然有一个无法导入的对象。

我用来检查代码是否有效的 JSON 文件是这样的:

https://www.googleapis.com/books/v1/volumes?q=isbn:9780553897852

这是我现在用来挑选数据的代码:

Public Sub exceljson()

'Error message if active cell is empty
If ActiveCell.Value = 0 Then
     MsgBox "Select cell with ISBN", vbExclamation
     Exit Sub
End If

'Error message if there is no match
On Error GoTo ErrMsg

Dim http As Object, JSON As Object, i As Integer, subitem As Object
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", "https://www.googleapis.com/books/v1/volumes?q=isbn:" & ActiveCell.Value, False
http.send
Set JSON = ParseJson(http.responseText)

i = ActiveCell.Row
For Each Item In JSON("items")
Set subitem = Item("volumeInfo")
Sheets(1).Cells(i, ActiveCell.Column + 1).Value = subitem("publishedDate")
Sheets(1).Cells(i, ActiveCell.Column + 2).Value = subitem("title")
Sheets(1).Cells(i, ActiveCell.Column + 3).Value = subitem("subtitle")
Sheets(1).Cells(i, ActiveCell.Column + 4).Value = subitem("pageCount")

'To obtain ISBN-10 and ISBN-13
j = 5
For Each Child In subitem("industryIdentifiers")
Sheets(1).Cells(i, ActiveCell.Column + j).Value = Child("identifier")
j = j + 1
Next
i = i + 1

'To end with success
Next
MsgBox ("Process complete"), vbInformation
Exit Sub

'To en with an error message
ErrMsg:
MsgBox ("No match obtained"), vbCritical

End Sub

This is the resulted EXCEL sheet I made

实际上,我在 ActiveCell 的后续单元格中显示了以下字段:出版年份、标题、副标题、页数、ISBN-10、ISBN-13 我写的是 ISBN。 但是我不知道如何从“作者”数组中收集数据。 是我唯一想念的数据字段,所以如果你能帮助我,我真的很感激。 提前致谢。

【问题讨论】:

  • For Each a In Item("VolumeInfo")("authors")
  • 不,它不起作用。由于没有大括号并且内部没有相等的事实,所以库似乎不解析数组。无论如何,谢谢你的想法。

标签: json excel vba api web-scraping


【解决方案1】:

以下显示了作者的正确路径。 {} 表示通过键访问的字典,[] 表示通过索引访问的集合。请注意,图像中的 0 索引基实际上是所用库的 1 基。

Option Explicit

Public Sub GetInfo()
    Const URL As String = "https://www.googleapis.com/books/v1/volumes?q=isbn:9780553897852"
    Dim json As Object
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", URL, False
        .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
        .send
        Set json = JsonConverter.ParseJson(.responseText)
    End With
    Debug.Print json("items")(1)("volumeInfo")("authors")(1)
End Sub

您还可以在此处查看该路径:


根据你的逻辑,你需要

Option Explicit
Public Sub GetInfo()
    Const URL As String = "https://www.googleapis.com/books/v1/volumes?q=isbn:9780553897852"
    Dim json As Object
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", URL, False
        .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
        .send
        Set json = JsonConverter.ParseJson(.responseText)
    End With
    'Debug.Print json("items")(1)("volumeInfo")("authors")(1)
    Dim item As Object, item2 As Variant, subItem As Object, r As Long, c As Long
    For Each item In json("items")
        Set subItem = item("volumeInfo")
        If subItem.Exists("authors") Then
            r = r + 1: c = 1
            For Each item2 In subItem("authors")
                ActiveSheet.Cells(r, c) = item2
                c = c + 1
            Next
        End If
    Next
End Sub

【讨论】:

  • 如果作者超过 1 个,可能需要添加一个方法来迭代所有作者。项目也是如此。
  • @RyanWildry 底层版本应该考虑到这一点,不是吗?这里已经很晚了,所以我的想法不太好。
  • 哦,我明白你的意思了!
  • 哇非常感谢@QHarr。我只是把: Sheets(1).Cells(i, ActiveCell.Column + 5).Value = json("items")(1)("volumeInfo")("authors")(1) 下面的“pageCount”和它作品。我只是更改 j = 6 以避免重叠,它完美地工作!非常感谢。但是我仍然不知道为什么会发生这种情况jiji
  • 感谢@RyanWildry,我添加了一行来说明作者下的集合中可能有多个作者。
【解决方案2】:

查看您从中检索的网页中的数据,"authors" 看起来像 subitemItem("volumeInfo")。如果"authors" 以数组形式读取,您可以使用

将其拉入单元格
Sheets(1).Cells(i, ActiveCell.Column + 5).Value = Join(subitem("authors"),",")

或者如果它只是一个字符串,那么你可以使用

Sheets(1).Cells(i, ActiveCell.Column + 5).Value = subitem("authors")

然后使j = 6 防止覆盖输出。

【讨论】:

  • 不工作,因为库似乎没有解析它,因为没有找到相等或括号。或者至少是我对 VBA 编程的短暂了解:-(
  • 这不是它的工作原理。如果您注意到,volumeInfo 前面的大括号实际上包含了整个数据集。括号或多或少在元数据中建立了层次结构。根据您的逻辑,您也不应该能够提取pageCount。您为什么不尝试添加Debug.Print subitem("authors") 并单步执行代码。或者,更好的是,您可以将 subitem 添加到您的监视列表中,单步执行代码,一旦分配了值,就转到监视窗口,展开它并浏览数据。
  • 我明白你的意思@Tate Garringer,但我仍然不明白为什么例如我可以通过在“volumeInfo”中搜索 Child 从对象“industryIdentifiers”中获取项目,但这个逻辑没有t 与“作者”合作。我是新手,所以对我来说非常棘手。对不起。
猜你喜欢
  • 2018-12-18
  • 1970-01-01
  • 2014-12-31
  • 1970-01-01
  • 2013-01-19
  • 2017-03-17
  • 1970-01-01
  • 2023-03-22
  • 2015-11-05
相关资源
最近更新 更多