【问题标题】:Setting custom User Agent in Selenium Webdriver for PhantomJS with Ruby使用 Ruby 在 Selenium Webdriver 中为 PhantomJS 设置自定义用户代理
【发布时间】:2014-10-09 03:10:00
【问题描述】:

今晚我已经上网了,大约 3 到 4 个小时。我已经尝试了我遇到的每一个建议。我什至检查了我的 Selenium 驱动程序对象上的“功能”对象,以确保它确实设置在那里,事实上,它是:

#<Selenium::WebDriver::Remote::Capabilities:0x00000007475cf0
 @capabilities=
  {:browser_name=>"phantomjs",
   :version=>"1.9.7",
   :platform=>:"linux-unknown-64bit",
   :javascript_enabled=>true,
   :css_selectors_enabled=>true,
   :takes_screenshot=>true,
   :native_events=>true,
   :rotatable=>false,
   :firefox_profile=>nil,
   :proxy=>#<Selenium::WebDriver::Proxy:0x00000007475908 @type=:direct>,
   "driverName"=>"ghostdriver",
   "driverVersion"=>"1.1.0",
   "handlesAlerts"=>false,
   "databaseEnabled"=>false,
   "locationContextEnabled"=>false,
   "applicationCacheEnabled"=>false,
   "browserConnectionEnabled"=>false,
   "webStorageEnabled"=>false,
   "acceptSslCerts"=>false,
   "proxy"=>{"proxyType"=>"direct"},
   "phantomjs.page.settings.userAgent"=>
    "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:27.0) Gecko/20100101 Firefox/27.0"}>

除了“phantomjs.page.settings.userAgent”之外,我还尝试了“userAgent”等。过去 3-4 小时内我可以在网上找到的所有东西,我都试过了。显然,在 2013 年初,这是一个相当普遍的问题,而我所说的解决方案显然是常见的解决方案。这些都不起作用,事实上,我从这一点信息中肯定知道这一点(请注意,User-Agent 是“Ruby”)

UNCAUGHT EXCEPTION: {"errorMessage"=>"Element is not currently visible and may not be manipulated",
 "request"=>
  {"headers"=>
    {"Accept"=>"application/json",
     "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
     "Connection"=>"close",
     "Content-Length"=>"2",
     "Content-Type"=>"application/x-www-form-urlencoded",
     "Host"=>"localhost:9876",
     "User-Agent"=>"Ruby"},
   "httpVersion"=>"1.1",
   "method"=>"POST",
   "post"=>"{}",
   "postRaw"=>"{}",
   "url"=>"/click",
   "urlParsed"=>
    {"anchor"=>"",
     "query"=>"",
     "file"=>"click",
     "directory"=>"/",
     "path"=>"/click",
     "relative"=>"/click",
     "port"=>"",
     "host"=>"",
     "password"=>"",
     "user"=>"",
     "userInfo"=>"",
     "authority"=>"",
     "protocol"=>"",
     "source"=>"/click",
     "queryKey"=>{},
     "chunks"=>["click"]},
   "urlOriginal"=>
    "/session/a03cc440-4f5c-11e4-8854-ed9c22bf60af/element/%3Awdc%3A1412822036214/click"}}

不幸的是,关于这些 Selenium 问题以及许多其他问题的信息和讨论更多,如果您使用的是 Java。在这一点上,我希望我在这个项目中以各种方式使用 Java,但现在我有 30,000 行代码,这些代码完全是我在过去 2 个月里自己编写的。至少现在失去这份工作,不仅对我个人而言是毁灭性的,而且对我的工作也是灾难性的。

什么给了?我真的需要深入挖掘并自定义源代码以获得我想要的东西,还是现在真的实现了这个功能?同样,我看到了 2013 年初的所有答案,但它们对我不起作用,我不知道为什么,或者如何轻松解决它。我在最后期限,所以这开始变得非常紧张。

有人对我有什么想法吗?请记住,我使用的是 Ruby,而不是 Java。

Selenium-webdriver 是 2.43。 PhantomJS 是 1.9.7。 GhostDriver 是 1.1.0。

在我看来,无法修改您的 User-Agent。

如果我能提供任何其他可能有帮助的信息,请告诉我。

如果您愿意分享一些想法或一些信息以帮助我指明正确的方向,我提前表示感谢。

【问题讨论】:

  • 从未尝试过自己,但请检查:github.com/mururu/capybara-user_agent。根据定义,它基本上是在底层实现 Capybara.current_session.driver.add_headers('User-Agent' =&gt; user_agent)Capybara.current_session.driver.header('User-Agent', user_agent)
  • 呃,好像因为stackoverflow.com/a/15647143/2117020所以不行。所以,我想,最好的方法是从 Selenium 切换到 Poltergeist (github.com/teampoltergeist/poltergeist)。好像支持add_headers
  • 那太糟糕了!我认为您需要使用 Capybara 才能使用 Poltergeist,但我会更多地查看那里的代码,看看我能做些什么。谢谢。如果您有任何想法,请告诉我。

标签: ruby selenium-webdriver phantomjs user-agent ghostdriver


【解决方案1】:

在 Java 中我做了以下事情:(PhantomJS 1.9.8,Selenium 2.39)

String userAgent = "Mozilla/5.0 (Linux; U; Android 2.3.3; en-us; LG-LU3000 Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(PhantomJSDriverService.PHANTOMJS_PAGE_SETTINGS_PREFIX + "userAgent", userAgent);
PhantomJSDriver driver = new PhantomJSDriver(caps);

也许 Ruby 也有类似的设置选项。看看“page.settings.userAgent”

【讨论】:

    【解决方案2】:
    capabilities = Selenium::WebDriver::Remote::Capabilities.phantomjs('phantomjs.page.settings.userAgent' => 'some user Agent')
    @instance = Selenium::WebDriver.for(:remote,:url=>'http://localhost:8910',:desired_capabilities=>capabilities)
    

    【讨论】:

      【解决方案3】:

      这最终不是“可能的”开箱即用,正如 moonfly 在他的 cmets 对我的问题中提到的那样。然而,事实证明这相对容易做到。我应该注意,这并没有解决我的特定问题。我可能天真地认为,由于用户代理“Ruby”,我得到了奇怪的结果。结果我花了几个小时才弄清楚这一点。我仍然得到相同的结果。

      但是,对于那些希望这会有所帮助的人,您必须为 Selenium 制作一个快速的猴子补丁。讨厌,粗暴,丑陋,骇人听闻,我知道。但是,它成功了。

      请注意,这是 Ruby 的 selenium-webdriver 版本 2.43.0 的猴子补丁 - 如果您有其他版本,则无法保证它会起作用。

      module Selenium
          module WebDriver
              module Remote
                  module Http
      
                      class Default < Common
                          private
      
                          def request(verb, url, headers, payload, redirects = 0)
                  # THIS IS WHERE OUR CUSTOM CHANGE BEGINS
                  headers.merge!('User-Agent' => 'Whatever User Agent You May Want')
                  # THIS IS WHERE OUR CUSTOM CHANGE ENDS
      
                  request = new_request_for(verb, url, headers, payload)
      
                  retries = 0
                  begin
                    response = response_for(request)
                  rescue Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EADDRINUSE
                    # a retry is sometimes needed on Windows XP where we may quickly
                    # run out of ephemeral ports
                    #
                    # A more robust solution is bumping the MaxUserPort setting
                    # as described here:
                    #
                    # http://msdn.microsoft.com/en-us/library/aa560610%28v=bts.20%29.aspx
                    raise if retries >= MAX_RETRIES
      
                    request = new_request_for(verb, url, headers, payload)
                    retries += 1
      
                    retry
                  rescue Errno::ECONNREFUSED => ex
                    if use_proxy?
                      raise ex.class, "using proxy: #{proxy.http}"
                    else
                      raise
                    end
                  end
      
                  if response.kind_of? Net::HTTPRedirection
                    raise Error::WebDriverError, "too many redirects" if redirects >= MAX_REDIRECTS
                    request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
                  else
                    create_response response.code, response.body, response.content_type
                  end
                end
      
              end
      
            end
          end
        end
      end
      

      【讨论】:

      • 猴子修补 Rubys Selenium Webdriver 的更体面的方法是:Selenium::WebDriver::Remote::Http::Common::DEFAULT_HEADERS['User-Agent'] = 'Whatever User Agent You May Want'
      猜你喜欢
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 2013-06-25
      • 2016-12-05
      • 1970-01-01
      • 2013-07-25
      相关资源
      最近更新 更多