You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby调用LMS API解析复杂JSON,提取submission_comments指定字段

搞定嵌套评论提取:Ruby代码修改与新手友好建议

嘿,作为Ruby新手能写出带分页的API请求脚本已经很厉害了!我看你现在的问题是没法从submission_comments数组里拆出单个评论的comment、author_id、author_name字段,直接把整个数组塞到CSV里了对吧?下面我一步步帮你修改代码,同时解释每个关键部分,方便你理解。

先说说当前代码的核心问题

你现在在遍历返回的提交数据时,直接把comments['submission_comments']这个完整数组写入CSV了,但每个提交可能有多条评论,所以得先遍历这个数组,把每条评论的指定字段单独提出来才行。

修改后的完整代码

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,写入包含评论字段的表头
CSV.open(output_csv, 'wb') do |csv|
  csv << ["user_id", "TII", "comment_content", "comment_author_id", "comment_author_name"]
end

request_url = "#{the_url}#{api_endpoint}"
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|
    # 处理分页链接,加个rescue避免没有link头时崩溃
    links = LinkHeader.parse(response.headers['link']).links rescue []
    next_link = links.find { |link| link['rel'] == 'next' }
    request_url = next_link.href if next_link
    # 控制循环:有下一页且返回内容非空时继续
    more_data = !next_link.nil? && response.body != "[]"

    if response.code == 200
      data = JSON.parse(response.body)
      data.each do |submission|
        # 先拿到当前提交的基础信息
        user_id = submission['user_id']
        tii_data = submission['turnitin_data']

        # 遍历当前提交的所有评论!这是核心修改点
        submission['submission_comments'].each do |single_comment|
          # 提取你要的三个字段
          comment_text = single_comment['comment']
          author_id = single_comment['author_id']
          author_name = single_comment['author_name']

          # 把每条评论的信息追加到CSV
          CSV.open(output_csv, 'a') do |csv|
            csv << [user_id, tii_data, comment_text, author_id, author_name]
          end
        end
      end
    else
      puts "哎呀,请求出错啦!响应码是:#{response.code}"
    end
  end

  get_comments.run
end

puts "脚本跑完啦!可以去看CSV文件啦😉"

关键修改点详解

  1. 表头更新:我把表头改成了更清晰的命名,比如comment_content,避免和变量名混淆,你也可以改成自己喜欢的名字。
  2. 遍历评论数组:新增了submission['submission_comments'].each do |single_comment|循环,这样就能逐条处理每个提交下的所有评论,而不是把整个数组丢进去。
  3. 字段提取:从每条评论对象里单独取出comment、author_id、author_name,确保CSV里每条行对应一条评论的信息。
  4. 健壮性优化:在解析LinkHeader时加了rescue [],如果响应里没有分页链接,不会直接崩溃,而是继续处理当前页的数据。
  5. 变量命名更清晰:把原来的comments改成submission,因为这个变量代表的是单个作业提交数据,不是评论,这样代码读起来更顺。

给Ruby新手的额外小技巧

  • 调试神器:加个require 'pp',然后在处理评论前写pp submission['submission_comments'],可以格式化打印出评论的结构,方便你确认字段名有没有写错。
  • CSV写入优化:当前代码每次写评论都打开一次CSV文件,数据量大的时候会有点慢。你可以把CSV对象放在循环外面,一直保持打开状态,比如:
    CSV.open(output_csv, 'wb') do |csv|
      csv << ["user_id", "TII", "comment_content", "comment_author_id", "comment_author_name"]
      while more_data
        # 发起请求、处理响应的代码放在这里
        data.each do |submission|
          # ... 处理提交和评论
          submission['submission_comments'].each do |single_comment|
            csv << [user_id, tii_data, comment_text, author_id, author_name]
          end
        end
      end
    end
    
    这样减少了IO操作,效率会更高。
  • 错误防护:可以给JSON解析加个rescue,比如data = JSON.parse(response.body) rescue nil,然后判断data是否存在再处理,避免返回无效JSON时脚本直接挂掉。

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:21:42