首页 > 解决方案 > Ruby API 调用从复杂的 json 中获取数据

问题描述

我正在使用 Ruby 进行 API GET 调用 - 调用是针对学习管理系统并返回以下 JSON:

{
    "id": 12345,
    "body": null,
    "url": null,
    "grade": "75",
    "score": 75,
    "submitted_at": "2020-05-02T11:30:53Z",
    "assignment_id": 9876,
    "user_id": 1111,
    "submission_type": "online_upload",
    "workflow_state": "graded",
    "grade_matches_current_submission": true,
    "graded_at": "2017-06-05T08:47:49Z",
    "grader_id": 2222,
    "attempt": 1,
    "cached_due_date": "2020-05-03T15:00:00Z",
    "excused": false,
    "late_policy_status": null,
    "points_deducted": null,
    "grading_period_id": null,
    "late": false,
    "missing": false,
    "seconds_late": 0,
    "entered_grade": "75",
    "entered_score": 75,
    "preview_url": "https://etcetc",
    "turnitin_data": {
        "attachment_33333": {
            "status": "scored",
            "object_id": "44444444",
            "similarity_score": 0,
            "web_overlap": 0,
            "publication_overlap": 0,
            "student_overlap": 0,
            "state": "none"
        }
    },
    "attachments": [
        {
            "id": 33333,
            "uuid": "kjsdkjhsdfkhsfd",
            "folder_id": 55555,
            "display_name": "Submission.pdf",
            "filename": "Submission.pdf",
            "content-type": "application/pdf",
            "url": "https://etcetc",
            "size": 2668226,
            "created_at": "2020-05-02T11:30:51Z",
            "updated_at": "2020-06-06T15:01:46Z",
            "unlock_at": null,
            "locked": false,
            "hidden": false,
            "lock_at": null,
            "hidden_for_user": false,
            "thumbnail_url": null,
            "modified_at": "2020-05-02T11:30:51Z",
            "mime_class": "pdf",
            "media_entry_id": null,
            "locked_for_user": false,
            "preview_url": "api/etcetc"
        }
    ],
    "submission_comments": [
        {
            "id": 99999,
            "comment": "here’s a comment",
            "author_id": 1,
            "author_name": "Mickey Mouse",
            "created_at": "2020-05-15T12:54:08Z",
            "edited_at": null,
            "avatar_path": "/images/users/1",
            "author": {
                "id": 1,
                "display_name": " Mickey Mouse ",
                "avatar_image_url": "https://etcetc",
                "html_url": "https://etcetc"
            }
        },
        {
            "id": 223344,
            "comment": "another comment",
            "author_id": 2,
            "author_name": "Donald Duck",
            "created_at": "2020-06-05T10:48:51Z",
            "edited_at": null,
            "avatar_path": "/images/users/2",
            "author": {
                "id": 2,
                "display_name": "Donald Duck",
                "avatar_image_url": "https://etcetc",
                "html_url": "https://etcetc"
            }
        }
    ]
}

我需要能够从“submission_comments”中检索特定值,即“comment”、“author_id”和“author_name”的值。目前我能做的最好的就是将“submission_comments”作为一个大实体检索。这就是我如何做到这一点:

require 'typhoeus'
require 'link_header'
require 'json'
require 'csv'

the_url = 'https://etctetc' 
token = 'mytoken'
api_endpoint = '/api/etc'
output_csv = 'C:\Users\me\Desktop\Ruby Canvas course\assignment_comments.csv'

CSV.open(output_csv, 'wb') do |csv|
    csv << ["user_id", "TII", "marker"]
end

request_url = "#{the_url}#{api_endpoint}"
count = 0
more_data = true
while more_data  
    get_comments = Typhoeus::Request.new(
        request_url,    
        method: :get,
        headers: { authorization: "Bearer #{token}" }
        )

        get_comments.on_complete do |response|
        #get next link
            links = LinkHeader.parse(response.headers['link']).links
            next_link = links.find { |link| link['rel'] == 'next' } 
            request_url = next_link.href if next_link 
            if next_link && "#{response.body}" != "[]"
                more_data = true
            else
                more_data = false
            end

        if response.code == 200
            data = JSON.parse(response.body)
            data.each do |comments|
                CSV.open(output_csv, 'a') do |csv|
                    csv << [comments['id'], comments['turnitin_data'], comments['submission_comments']]
                end
            end
        else
            puts "Something went wrong! Response code was #{response.code}"
        end
    end

    get_comments.run
end
puts "Script done running"

我是新手(红宝石代码基于练习,所以我可能不完全理解) - 任何帮助/建议将不胜感激!

编辑:我还应该注意,这不是我正在处理的全部 JSON 响应——这只是返回的十个项目之一

标签: jsonrubyrest

解决方案


"submission_comments": [
        {
            "id": 99999,
        }
]

表示[]它是数组。{}表示它是一个对象。

所以你可能需要做这样的事情:

json["submission_comments"].first["id"]

或更好地遍历它:

ids = json["submission_comments"].map{|comment| comment["id"]}

推荐阅读