始终使用Selenium在Firefox中允许地理位置

时间:2013-04-30 05:16:55

标签: python selenium geolocation

我正在使用Selenium为网络应用创建一些端到端测试。

我正在使用Python并使用Firefox驱动程序

driver = webdriver.Firefox()

问题在于我的网络应用程序使用HTML5地理位置,似乎每次运行我的测试时,我都必须点击Firefox中的“允许位置”弹出窗口,使我的测试不会自动化。

有没有办法强制Selenium Firefox驱动程序始终允许地理定位而不提示?

9 个答案:

答案 0 :(得分:7)

您可以强制浏览器在没有权限请求的情况下返回某些预定义位置。

只需执行以下JavaScript代码:

"navigator.geolocation.getCurrentPosition = function(success) { success({coords: {latitude: 50.455755, longitude: 30.511565}}); }"

在Firefox和Chrome中测试过。

答案 1 :(得分:3)

因为在问到这个问题差不多3年后我遇到了同样的问题,并且上述答案都没有让我满意。我想展示我使用的解决方案。

所以我在this blog找到了答案。

以这种方式在我的python代码上使用它:

@classmethod
def setUpClass(cls):
    cls.binary = FirefoxBinary(FF_BINARY_PATH)
    cls.profile = FirefoxProfile()
    cls.profile.set_preference("geo.prompt.testing", True)
    cls.profile.set_preference("geo.prompt.testing.allow", True)
    cls.profile.set_preference('geo.wifi.uri', GEOLOCATION_PATH)
    cls.driver = Firefox(firefox_binary=cls.binary, firefox_profile=cls.profile)

GEOLOCATION_PATH上是JSON文件的路径:

{
    "status": "OK",
    "accuracy": 10.0,
    "location": {
        "lat": 50.850780,
        "lng": 4.358138,
        "latitude": 50.850780,
        "longitude": 4.358138,
        "accuracy": 10.0
    }
}

答案 2 :(得分:3)

截至撰写本文时(Apr / 20),这个问题已经存在了将近7年,但是随着API的改变,这个问题仍然很重要。我在用Selenium编写功能测试时遇到了类似的问题。

作为示例,规范Mozilla example中可能发生的情况:

  • 浏览器不支持地理位置(!navigator.geolocation
  • 支持地理位置(getCurrentPosition(success, error)
    • 拒绝访问地理位置(error
    • 允许访问地理位置(success

以下是这些方案如何转换为Selenium设置:

from selenium import webdriver

# geolocation API not supported
geoDisabled = webdriver.FirefoxOptions()
geoDisabled.set_preference("geo.enabled", False)
browser = webdriver.Firefox(options=geoDisabled)

为了进行模拟“不允许”的操作,请在启用了地理位置的浏览器的提示中单击(默认情况下已启用,请通过about:config进行检查):

# geolocation supported but denied
geoBlocked = webdriver.FirefoxOptions()
geoBlocked.set_preference("geo.prompt.testing", True)
geoBlocked.set_preference("geo.prompt.testing.allow", False)
browser = webdriver.Firefox(options=geoBlocked)

最后,模拟“允许位置访问”点击

# geolocation supported, allowed and location mocked
geoAllowed = webdriver.FirefoxOptions()
geoAllowed.set_preference('geo.prompt.testing', True)
geoAllowed.set_preference('geo.prompt.testing.allow', True)
geoAllowed.set_preference('geo.provider.network.url',
    'data:application/json,{"location": {"lat": 51.47, "lng": 0.0}, "accuracy": 100.0}')
browser = webdriver.Firefox(options=geoAllowed)

geo.wifi.uri属性似乎不再存在,而是改为了geo.provider.network.url。该解决方案还可以防止从磁盘加载“随机” Firefox概要文件,或者防止在运行时执行JS代码来模拟该位置。通过“选项”(通过此解决方案就是这种情况),“配置文件”或"DesiredCapabilities"来设置浏览器配置在很大程度上无关紧要。我发现选项是最简单的。

答案 3 :(得分:1)

今天偶然发现了这个问题,我知道应该有一个简单快捷的方法来解决这个问题。这是我解决的方法:

  1. 创建一个供Selenium使用的新Firefox配置文件。您可以输入about:profiles,然后单击“创建新的个人资料”来完成此操作。可以在Mozilla's docs中找到分步说明。
  2. 前往需要权限的站点,然后等待它要求您授予它们。授予他们,然后选中“记住此决定”框。
  3. 您需要知道配置文件的存储位置,以便Selenium可以使用它。您可以在about:profiles中找到位置。在这里,我创建了一个“ example_profile”,然后复制了“根目录”路径: about:profiles

  4. 然后您可以在实例化Firefox浏览器时将路径作为参数传递:

    root_directory_path = "/.../Firefox/Profiles/loeiok2p.example_profile"
    driver = webdriver.Firefox(firefox_profile=root_directory_path)
    

Selenium应该使用具有授予权限的配置文件,并且弹出窗口不应重新出现。

答案 4 :(得分:0)

我认为默认情况下是使用新的匿名配置文件启动Firefox。您可以使用-Dwebdriver.firefox.profile = whatever启动selenium,其中“whatever”是启动firefox -P时配置文件的名称。

确保持久登录和其他cookie没有任何奇怪之处:<​​/ p>

  • 使用“firefox -P”启动Firefox
  • 选择您将使用
  • 启动测试的配置文件
  • 编辑 - &gt;偏好 - &gt;隐私,选择使用历史记录的自定义设置
  • 告诉Firefox保留cookie直到“我关闭Firefox”

答案 5 :(得分:0)

以上是其中一个答案的更精确的答案。这会在执行地理定位成功回调之前增加一些超时,因为通常JavaScript的编写方式是,在有一个循环返回到事件循环之前,预计地理位置坐标不可用。

这也允许通过Web控制台跟踪欺骗。

SPOOF_LOCATION_JS = """
(function() {
console.log('Preparing geo spoofing');
navigator.geolocation.getCurrentPosition = function(success) {
    console.log("getCurrentPosition() called");
    setTimeout(function() { console.log("Sending out fake coordinates"); success({coords: {latitude: 50.455755, longitude: 30.511565}}); }, 500);
};
console.log("Finished geospoofing")})();
"""


browser.evaluate_script(SPOOF_LOCATION_JS.replace("\n", " "))

答案 6 :(得分:0)

以上都不对我有用,但这确实做到了:

从以下位置获得答案:https://security.stackexchange.com/questions/147166/how-can-you-fake-geolocation-in-firefox

from selenium import webdriver

profile = webdriver.FirefoxProfile()

profile.set_preference("geo.prompt.testing", True)
profile.set_preference("geo.prompt.testing.allow", True)
profile.set_preference('geo.wifi.uri',
                       'data:application/json,{"location": {"lat": 40.7590, "lng": -73.9845}, "accuracy": 27000.0}')


driver = webdriver.Firefox(firefox_profile=profile)

driver.get('https://www.where-am-i.net/')

答案 7 :(得分:0)

我正在将Firefox 74.0与Selenium / Python 3.141.0配合使用,以下内容使我进入了纽约市

profile = FirefoxProfile()
profile.set_preference("geo.prompt.testing", True)
profile.set_preference("geo.prompt.testing.allow", True)
profile.set_preference("geo.provider.testing", True)
"geo.provider.network.url", "data:application/json,{"location": {"lat": 40.7590, "lng": -73.9845}, "accuracy": 27000.0}")

答案 8 :(得分:-2)

只需手动允许一次,然后让python做到这一点就足够了吗?

因为您可以通过在Firefox中的网站属性中设置它来轻松允许: enter image description here