【问题标题】:403 Error with Mechanize on HerokuHeroku上的机械化403错误
【发布时间】:2014-10-21 07:18:19
【问题描述】:

当使用 mechanize 从 craigslist 中提取一些数据时,我在 Heroku 上不断收到以下错误:status: Net::HTTPForbidden 1.1 403 Forbidden

我想知道有什么方法可以防止这种情况发生,我的设置如下:

agent = Mechanize.new do |agent|
  agent.log              = @logger
  agent.user_agent_alias = 'Mac Safari'
  agent.robots           = false
end

有什么想法吗?

【问题讨论】:

  • 你必须弄清楚他们为什么禁止它。 403 只是“不”,没有真正的解释。尝试简化并使用 OpenURI 抓取一些页面,看看会发生什么。然后尝试使用各种用户代理签名进行机械化。或者,联系他们并询问他们是否有 API。
  • 可能是基于地理位置、引荐来源网址、cookies,或者您可能只是太用力了。
  • 你每隔 10 分钟就会刮一次,这肯定会引起注意。是否有解决方法,可能会更改用户代理?我尝试每次刮掉 cookie,但仍然遇到 403 错误。

标签: ruby heroku web-scraping mechanize mechanize-ruby


【解决方案1】:

我想我会让这个更干净一些。我遇到了同样的问题,我可以通过请求新标头来解决:

@agent = Mechanize.new { |agent|
                      agent.user_agent_alias = 'Windows Chrome'}


@agent.request_headers

如果您还没有,您还应该包括一些错误处理。我写了以下内容来给出一个想法:

begin  #beginning of block for handling rescue
              @results_page = #getting some page and doing cool stuff
         #The following line puts mechanize to sleep when a new page is reached for 1/10 second.  This keeps you from overloading the site you're scraping and minimizing the chance of getting errors.  If you start to get '503' errors you should increase this number a little!
              @agent.history_added = Proc.new {sleep 0.1}

            rescue Mechanize::ResponseCodeError => exception
              if exception.response_code == "503"
                @agent.history_added = Proc.new {sleep .2}
              #the following line closes all active connections
                @agent.shutdown
                @agent = Mechanize.new { |agent|
                  agent.user_agent_alias = 'Windows Chrome'}
                @agent.request_headers
                @page = @agent.get('the-webpage-i-wanted.com')
                @form = @page.#GettingBackToWhereIWas
                redo 
                else
                #more error handling if needed
                end

***注意:考虑将其作为后台进程运行以避免在 heroku 上出现超时错误,因为它们只允许 15-30 秒的请求-响应周期。如果您还没有这样做,我会使用 redisToGo(heroku 插件)和 sidekiq(dl gem)!

【讨论】:

  • 你能贴出例子吗?
  • 设置别名后忘记添加:@agent.request_headers。还为您肯定会遇到的错误添加救援:rescue Mechanize::ResponseCodeError => exception if exception.response_code == "413"
【解决方案2】:

使用 mechanize 和其他类似浏览器模拟器时,您必须监控您的网络,我更喜欢 Google chrome 开发者工具。

使用普通浏览器检查您的 URL 并检查以下内容:

  1. 此网址有效吗?
  2. 这个 URL 是公开的吗?
  3. 此 URL 浏览器是否受限?
  4. 此 URL 是否通过登录来保护?
  5. 此 URL 在正常情况下需要哪些参数?

调试这些点,因为您访问的 URL 可能受限于:

  • 公共使用
  • 可能是目录路径,不允许索引
  • 可能是服务器限制了某些用户代理使用它
  • 可能是您没有完全复制请求

我想我使用了太多“可能”,但我的意思是,如果你不能公开发布你的链接,我只能猜到你的错误,如果你的链接直接点击一个目录并且它的索引是关闭的,那么你也不能在机械化中浏览它,如果是针对特定用户代理,那么您应该使用特定用户代理初始化您的机械化,例如:

browser = Mechanize.new
browser.user_agent_alias = 'Windows IE 7'

在任何其他情况下,如果您没有复制您的请求,或者缺少某些重要参数或您发送的请求类型错误,则可能缺少标头。

编辑:现在您已经在此处提供了链接,这就是您在处理 https 时应该做的事情

Mechanize.new{|a| a.ssl_version, a.verify_mode = 'SSLv3', OpenSSL::SSL::VERIFY_NONE};

【讨论】:

  • 一个示例链接是:sfbay.craigslist.org/search/sfc/… 在浏览器中运行良好。我也尝试过轮换用户代理,但仍然遇到问题。
  • 所以我设置了这个:Mechanize.new { |agent| agent.log = logger; agent.user_agent_alias = 'Mac Safari'; agent.robots = false; agent.ssl_version; agent.verify_mode = 'SSLv3'; OpenSSL::SSL::VERIFY_NONE } 但是不明白为什么我只打印ssl_versionOpenSSL::SSL::VERIFY_NONE 而不设置它?当我尝试在上面使用 Mechanize 时,我不断收到TypeError: no implicit conversion of String into Integer。有什么想法吗?
  • 我不确定你在说什么,我检查了你给你的 cadoe sn-p 在这里可以正常工作
  • 它现在在本地工作,但在 Heroku 上仍然出现 403 Forbidden 错误。还有其他想法吗?
  • @bklane 你有想过这个吗?我在使用 Kayak 时遇到了同样的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多