réglage en-têtes de requête en sélénium

j'essaie de définir l'en-tête de requête 'Referer' pour mystifier une requête provenant d'un autre site. Nous avons besoin du test de capacité qu'un referrer spécifique est utilisé, qui renvoie un formulaire spécifique à l'utilisateur, sinon un formulaire alternatif est donné.

je peux le faire à l'intérieur de lutin par:

page.driver.headers = {"Referer" => referer_string}

mais je ne trouve pas la fonctionnalité équivalente pour le pilote selemium.

comment définir les en-têtes de requête dans le pilote capybara selenium?

38
demandé sur Andrei Botalov 2013-03-26 22:51:09

6 réponses

Webdriver ne contient pas D'API pour le faire. Voir numéro 141 de Sélénium tracker pour plus d'info. Le titre du numéro dit que c'est à propos des en-têtes de réponse mais il a été décidé que le sélénium ne contiendra pas D'API pour les en-têtes de requête dans le cadre de ce numéro. Plusieurs problèmes concernant l'ajout D'API pour définir les en-têtes de requête ont été identifiés comme des doublons: premier, deuxième, troisième.

voici quelques possibilités que je peux proposer:

  1. Utiliser un autre pilote/bibliothèque au lieu de sélénium
  2. Ecrire un plugin spécifique au navigateur (ou trouver un plugin existant) qui vous permet d'ajouter de l'en-tête pour la requête.
  3. Utiliser browsermob-proxy ou une autre proxy.

j'opterais pour l'option 3 dans la plupart des cas. Il n'est pas difficile.

Notez que Ghostdriver a une API pour elle mais il n'est pas supporté par d'autres pilotes.

28
répondu Andrei Botalov 2016-12-13 11:26:52

j'ai eu le même problème. Je l'ai résolu en téléchargeant modifier-en-tête firefox add-on et l'activer avec du sélénium.

Le code en python est le suivant

fp = webdriver.FirefoxProfile()
path_modify_header = 'C:/xxxxxxx/modify_headers-0.7.1.1-fx.xpi'
fp.add_extension(path_modify_header)

fp.set_preference("modifyheaders.headers.count", 1)
fp.set_preference("modifyheaders.headers.action0", "Add")
fp.set_preference("modifyheaders.headers.name0", "Name_of_header") # Set here the name of the header
fp.set_preference("modifyheaders.headers.value0", "value_of_header") # Set here the value of the header
fp.set_preference("modifyheaders.headers.enabled0", True)
fp.set_preference("modifyheaders.config.active", True)
fp.set_preference("modifyheaders.config.alwaysOn", True)

driver = webdriver.Firefox(firefox_profile=fp)
7
répondu Fernando Marengo 2017-01-12 19:11:10

avait le même problème aujourd'hui, sauf que j'avais besoin de définir un référent différent par test. J'ai fini par utiliser un middleware et une classe pour passer en-têtes. J'ai pensé partager (ou peut-être qu'il y a une solution plus propre?):

lib/request_headers.rb:

class CustomHeadersHelper
  cattr_accessor :headers
end

class RequestHeaders
  def initialize(app, helper = nil)
    @app, @helper = app, helper
  end

  def call(env)
    if @helper
      headers = @helper.headers

      if headers.is_a?(Hash)
        headers.each do |k,v|
          env["HTTP_#{k.upcase.gsub("-", "_")}"] = v
        end
      end
    end

    @app.call(env)
  end
end

config/initializers/middleware.rb

require 'request_headers'

if %w(test cucumber).include?(Rails.env)
  Rails.application.config.middleware.insert_before Rack::Lock, "RequestHeaders", CustomHeadersHelper
end

spec/support/capybara_headers.rb

require 'request_headers'

module CapybaraHeaderHelpers
  shared_context "navigating within the site" do
    before(:each) { add_headers("Referer" => Capybara.app_host + "/") }
  end

  def add_headers(custom_headers)
    if Capybara.current_driver == :rack_test
      custom_headers.each do |name, value|
        page.driver.browser.header(name, value)
      end
    else
      CustomHeadersHelper.headers = custom_headers
    end
  end
end

spec/spec_helper.rb

...
config.include CapybaraHeaderHelpers

alors je peux inclure le contexte partagé partout où j'en ai besoin, ou passer des en-têtes différents dans un autre before bloc. Je ne l'ai testé qu'avec du sélénium et du RackTest, mais il doit être transparent, car l'injection de l'en-tête est faite avant que la requête n'atteigne réellement l'application.

4
répondu HargrimmTheBleak 2013-06-19 17:46:22

pour ceux qui utilisent Python, vous pouvez envisager d'utiliser Fil De Sélénium, qui peut définir des en-têtes de requête, ainsi que vous fournir la capacité d'inspecter les requêtes et les réponses.

from seleniumwire import webdriver  # Import from seleniumwire

# Create a new instance of the Firefox driver
driver = webdriver.Firefox()

driver.header_overrides = {
    'Referer': 'referer_string',
}

# All subsequent requests will now contain the Referer
2
répondu Will Keeling 2018-08-19 15:44:29

Si vous utilisez le HtmlUnitDriver, Vous pouvez définir les en-têtes de requête en modifiant le WebClient, comme ceci:

final case class Header(name: String, value: String)

final class HtmlUnitDriverWithHeaders(headers: Seq[Header]) extends HtmlUnitDriver {
  super.modifyWebClient {
    val client = super.getWebClient
    headers.foreach(h => client.addRequestHeader(h.name, h.value))
    client
  }
}

les en-têtes seront alors sur toutes les requêtes faites par le navigateur web.

0
répondu John P 2017-03-23 18:22:30

Vous pouvez le faire avec le driver fantôme.

PhantomJSDriver pd = ((PhantomJSDriver) ((WebDriverFacade) getDriver()).getProxiedDriver());
pd.executePhantomJS(
            "this.onResourceRequested = function(request, net) {" +
            "   net.setHeader('header-name', 'header-value')" +
            "};");

en utilisant l'objet request, vous pouvez filtrer aussi pour que l'en-tête ne soit pas défini pour chaque requête.

0
répondu stijn van crombrugge 2017-12-22 13:11:29