Базовая аутентификация HTTP с помощью Anemone Web Spider

Мне нужно собрать все "заголовки" со всех страниц сайта.
Сайт имеет конфигурацию HTTP Basic Auth.
Без аутентификации я делаю следующее:

require 'anemone'
Anemone.crawl("http://example.com/") do |anemone|
  anemone.on_every_page do |page|
    puts page.doc.at('title').inner_html rescue nil
  end
end

Но у меня есть некоторые проблемы с HTTP Basic Auth...
Как я могу собирать заголовки с сайта с помощью HTTP Basic Auth?
Если я пытаюсь использовать "Anemone.crawl (" http://username:password@example.com/")", то у меня только заголовок первой страницы, но другие ссылки имеют стиль http://example.com/ и я получил 401 ошибка.

1 ответ

Решение

HTTP Basic Auth работает через HTTP-заголовки. Клиент, желающий получить доступ к ограниченному ресурсу, должен предоставить заголовок аутентификации, например:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Он содержит имя и пароль в кодировке Base64. Больше информации в статье в Википедии: Базовая аутентификация доступа.

Я немного погуглил и не нашел способа заставить Anemone принимать заголовки пользовательских запросов. Может быть, вам повезет больше.

Но я нашел другого сканера, который утверждает, что может это сделать: Месси. Может быть, вы должны попробовать

Обновить

Вот место, где Anemone устанавливает заголовки своих запросов: Anemone:: HTTP. В самом деле, там нет настройки. Вы можете сделать это. Нечто подобное должно работать (поместите это где-нибудь в вашем приложении):

module Anemone
  class HTTP
    def get_response(url, referer = nil)
      full_path = url.query.nil? ? url.path : "#{url.path}?#{url.query}"

      opts = {}
      opts['User-Agent'] = user_agent if user_agent
      opts['Referer'] = referer.to_s if referer
      opts['Cookie'] = @cookie_store.to_s unless @cookie_store.empty? || (!accept_cookies? && @opts[:cookies].nil?)

      retries = 0
      begin
        start = Time.now()
        # format request
        req = Net::HTTP::Get.new(full_path, opts)
        response = connection(url).request(req)
        finish = Time.now()
        # HTTP Basic authentication
        req.basic_auth 'your username', 'your password' # <<== tweak here
        response_time = ((finish - start) * 1000).round
        @cookie_store.merge!(response['Set-Cookie']) if accept_cookies?
        return response, response_time
      rescue Timeout::Error, Net::HTTPBadResponse, EOFError => e
        puts e.inspect if verbose?
        refresh_connection(url)
        retries += 1
        retry unless retries > 3
      end
    end
  end
end

Очевидно, вы должны предоставить свои собственные значения для username а также password параметры к basic_auth вызов метода. Это быстро и грязно и жестко, да. Но иногда у вас нет времени, чтобы сделать все правильно.:)

Другие вопросы по тегам