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

使用Ruby Mechanize爬取美国务院页面遭遇403 Forbidden错误求助

403 Forbidden错误排查(Ruby Mechanize爬取美国国务院页面)

报错信息

403 => Net::HTTPForbidden for https://www.state.gov/countries-areas-archive/tunisia/page/2/ -- unhandled response (Mechanize::ResponseCodeError)

问题描述

我想要爬取美国国务院关于突尼斯的9页声明,但访问第二页时出现上述403错误,我的Ruby Mechanize代码如下,请问问题出在哪里?

require 'mechanize'
agent = Mechanize.new
9.times do |i|
  page = agent.get("https://www.state.gov/countries-areas-archive/tunisia/page/#{i+1}/")
  page.search('a.collection-result_link').each do |link|
    agent.click(link)
    url = agent.page.search('link[rel = "canonical"]').attr('href').text
    wrapped_url = url.gsub(url, "<a href='#{url}'>الرابط</a>")  
    title = agent.page.search('h1.featured-content__headline report-header__headline stars-above').text
    statements = [wrapped_url, title]
    puts statements
  end
end

问题根源

403错误是网站服务器直接拒绝了你的请求,核心原因是反爬机制识别出你是爬虫,而非正常用户:

  • Mechanize默认的请求头特征明显,比如User-Agent是Mechanize专属标识,很容易被拦截
  • 爬取速度过快,没有设置请求间隔,触发了网站的访问频率限制
  • 缺少真实浏览器会携带的必要请求头(如Accept-Language、Referer等),请求特征不符合正常用户行为

修复方案

1. 伪装浏览器请求头

给Mechanize设置主流浏览器的User-Agent,模拟真实用户访问:

agent = Mechanize.new
# 使用预设的Chrome浏览器UA
agent.user_agent_alias = 'Chrome'
# 也可以自定义UA字符串
# agent.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'

2. 添加请求间隔

每次请求后暂停几秒,避免触发频率限制:

9.times do |i|
  page = agent.get("https://www.state.gov/countries-areas-archive/tunisia/page/#{i+1}/")
  page.search('a.collection-result_link').each do |link|
    agent.click(link)
    # 你的处理代码...
    sleep(2) # 每次点击详情页后暂停2秒
  end
  sleep(3) # 每页爬完后暂停3秒
end

3. 补充必要请求头

添加真实浏览器会携带的请求头,进一步模拟正常请求:

agent.add_field('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8')
agent.add_field('Accept-Language', 'en-US,en;q=0.5')
agent.add_field('Referer', 'https://www.state.gov/countries-areas-archive/tunisia/')

4. 捕获异常避免程序崩溃

添加异常捕获逻辑,遇到错误时可以记录信息或尝试重试:

9.times do |i|
  begin
    page = agent.get("https://www.state.gov/countries-areas-archive/tunisia/page/#{i+1}/")
    # 后续处理代码...
  rescue Mechanize::ResponseCodeError => e
    puts "请求第#{i+1}页失败: #{e.message}"
    sleep(5)
    retry # 可选:重试一次
  end
end

额外注意事项

  • 先查看网站的robots.txt文件(https://www.state.gov/robots.txt),确认目标页面是否允许爬取,避免违反网站规则
  • 不要过度爬取,避免给服务器造成过大压力,否则可能被永久封禁IP

内容的提问来源于stack exchange,提问作者Karim Bn Abdlaziz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:45:10