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

在Ruby中调用Google Places API获取下一页结果遇重复问题

问题排查:Google Places Text Search 传入next_page_token返回重复结果

核心问题分析

你的代码里有两个关键错误导致分页无效:

  1. 错误的next_page_token获取方式
    你用@results.last&.dig('next_page_token')尝试获取下一页token,但@results存储的是所有商家的结果数组——单个商家数据里根本没有next_page_token字段,这个字段只存在于每次请求返回的完整响应对象(也就是fetch_page返回的JSON结构)里。

  2. 分页逻辑的状态丢失
    你只把响应里的results数组合并到@results,没有保留当前响应的完整信息,导致后续循环时无法拿到正确的下一页token,最终发起的是不带page_token的重复请求,自然返回第一页结果。

修复后的代码

1. 修正分页循环逻辑

def extract
  current_page_token = nil
  loop do
    page = fetch_page(current_page_token)
    break if page.nil? || page['results'].empty?

    @results += page['results']
    # 直接从当前page对象里拿下一页token
    current_page_token = page['next_page_token']

    break if current_page_token.nil?

    # Google要求next_page_token生成后需等待至少1秒才能使用,1秒足够,无需10秒
    sleep(1)
  end

  @results = @results.map do |result|
    result_details = fetch_place_details(result['place_id'])
    result.merge(result_details)
  end

  upsert_businesses(clean_data(@results))
end

2. 修复Place Details API的参数问题

你之前复用了@params(包含query参数)调用Details API,这是冗余且不符合API要求的,应该单独构造请求参数:

def fetch_place_details(place_id)
  params = {
    place_id: place_id,
    fields: 'name,formatted_phone_number,formatted_address,website,place_id,types',
    key: API_KEY
  }
  response = RestClient.get(DETAILS_ENDPOINT, params: params)

  return {} unless response.code == 200

  details = JSON.parse(response.body)['result']
  details || {}
end

3. 增强API错误处理(可选)

除了HTTP状态码,还要检查Google API返回的业务状态,避免无效请求:

def fetch_page(page_token)
  params = @params.dup
  params[:page_token] = page_token if page_token.present?
  response = RestClient.get(SEARCH_ENDPOINT, params: params)

  return nil unless response.code == 200

  data = JSON.parse(response.body)
  if data['status'] != 'OK' && data['status'] != 'ZERO_RESULTS'
    puts "Places API Error: #{data['status']} - #{data['error_message']}"
    return nil
  end

  data
end

额外注意事项

  • Google的next_page_token有有效期(通常几分钟),且只能使用一次,不要重复使用同一个token。
  • 控制请求频率,避免触发OVER_QUERY_LIMIT,官方限制是10次/秒,1秒延迟足够覆盖分页请求的间隔。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:46:37