我正在尝试将请求标头“Referer”设置为欺骗来自其他网站的请求。我们需要使用特定引用者的能力测试,它将特定表单返回给用户,否则会给出替代表单。
我可以通过以下方式在恶作剧中做到这一点:
page.driver.headers = {"Referer" => referer_string}
但我找不到selemium驱动程序的等效功能。
如何在capybara selenium驱动程序中设置请求标头?
答案 0 :(得分:31)
Webdriver不包含API来执行此操作。有关详细信息,请参阅issue 141 from Selenium tracker。该问题的标题说它是关于响应标头但是决定Selenium在此问题的范围内不包含请求标头的API。有关添加API以设置请求标头的几个问题已标记为重复:first,second,third。
我可以提出以下几种可能性:
在大多数情况下,我会选择选项3。这并不难。
请注意Ghostdriver has an API for it,但其他驱动程序不支持。
答案 1 :(得分:8)
我有同样的问题。我解决了下载modify-headers firefox附加组件并使用selenium激活它。
python中的代码如下
li = [1,2,3,4]
max_time = [0,0,0,0]
li.sort()
if 2 in li:
pos2 = li.index(2)
max_time[0] = 2
while(pos2<4 and li.index(2) != 3):
if(li[pos2+1] == 3):
max_time[1] = li[pos2+1]
pos2 += 1
continue
elif(li[pos2+1] == 4 or li[pos2+1] == 5):
max_time[2] = li[pos2+1]
pos2 += 1
continue
else:
max_time[3] = li[pos2+1]
pos2 += 1
continue
答案 2 :(得分:8)
对于那些使用Python的人,您可以考虑使用Selenium Wire,它可以设置请求标头,并为您提供检查请求和响应的功能。
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
答案 3 :(得分:5)
今天有同样的问题,除了我需要为每个测试设置不同的引用。我最终使用中间件和类将标头传递给它。以为我会分享(或者可能有更清洁的解决方案?):
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
然后我可以在任何需要的地方包含共享上下文,或者在另一个before
块中传递不同的头。我没有用Selenium和RackTest以外的任何东西测试它,但它应该是透明的,因为在请求实际到达应用程序之前完成了头文件注入。
答案 4 :(得分:1)
如果您使用HtmlUnitDriver
,则可以通过修改WebClient
来设置请求标头,如下所示:
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
}
}
然后,标题将出现在Web浏览器发出的所有请求中。
答案 5 :(得分:1)
检查一下: chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"')
问题解决了!
答案 6 :(得分:1)
使用上面已经讨论的解决方案,最可靠的解决方案是使用Browsermob-Proxy
但是在使用远程网格计算机时,Browsermob-proxy并没有真正的帮助。
这就是我解决此问题的方式。希望对安装类似设置的人有所帮助。
如何下载Modheader?链接
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File(C://Downloads//modheader//modheader.crx));
// Set the Desired capabilities
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
// Instantiate the chrome driver with capabilities
WebDriver driver = new RemoteWebDriver(new URL(YOUR_HUB_URL), options);
。
// set the context on the extension so the localStorage can be accessed
driver.get("chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj/_generated_background_page.html");
Where `idgpnmonknjnojddfkpgkljpfnnfcklj` is the value captured from the Step# 2
Javascript
。
((Javascript)driver).executeScript(
"localStorage.setItem('profiles', JSON.stringify([{ title: 'Selenium', hideComment: true, appendMode: '',
headers: [
{enabled: true, name: 'token-1', value: 'value-1', comment: ''},
{enabled: true, name: 'token-2', value: 'value-2', comment: ''}
],
respHeaders: [],
filters: []
}]));");
token-1
,value-1
,token-2
,value-2
是要添加的请求标头和值。
现在导航到所需的Web应用程序。
driver.get("your-desired-website");
答案 7 :(得分:0)
你可以使用PhantomJSDriver。
PhantomJSDriver pd = ((PhantomJSDriver) ((WebDriverFacade) getDriver()).getProxiedDriver());
pd.executePhantomJS(
"this.onResourceRequested = function(request, net) {" +
" net.setHeader('header-name', 'header-value')" +
"};");
使用请求对象,您也可以进行过滤,这样就不会为每个请求设置标头。
答案 8 :(得分:0)
我想让RSpec / Ruby稍微苗条一些,以便自定义代码只能放在一个地方。这是我的解决方案:
/spec/support/selenium.rb
...
RSpec.configure do |config|
config.after(:suite) do
$custom_headers = nil
end
end
module RequestWithExtraHeaders
def headers
$custom_headers.each do |key, value|
self.set_header "HTTP_#{key}", value
end if $custom_headers
super
end
end
class ActionDispatch::Request
prepend RequestWithExtraHeaders
end
然后在我的规格中:
/specs/features/something_spec.rb
...
$custom_headers = {"Referer" => referer_string}
答案 9 :(得分:0)
如果您正在使用 javacsript 并且只想在 chrome 上实现,那么 Puppeteer 是最好的选择,因为它具有修改标头的本机支持。 看看这个:https://pptr.dev/#?product=Puppeteer&version=v10.1.0&show=api-pagesetextrahttpheadersheaders
尽管要跨浏览器使用,您可以查看 @requestly/selenium
npm 包。它是 requestly 扩展的包装器,可以轻松集成到 selenium-webdriver 中。扩展可以修改标头。
退房:https://www.npmjs.com/package/@requestly/selenium