数据采集过程中经常需要用到代理,Selenium
也支持代理功能,selenium\webdriver\common\proxy.py
提供了代理数据结构的实现。Selenium
实现代理的方法有很多种,不同WebDriver
实现实现代理的方法也不尽相同。由于经常使用FireFox浏览器,因此,以geckodriver
作为案例来演示代理功能。
官方文档推荐使用Capabilities
根据《Selenium3 Python WebDriver API源码探析(11)WebDriver Capabilities(驱动功能)概述,FirefoxOptions》可知,'proxy'
是标准Capabilities
对象的其中一项,值类型为JSON,具体格式见https://www.w3.org/TR/webdriver2/#proxy。
因此,可通过Capabilities
设置代理。这也是官方文档使用的方式,使用起来比较简洁。
案例:通过Capabilities
设置代理
from selenium import webdriver
# 初始化FirefoxOptions
options = webdriver.FirefoxOptions()
# 代理
PROXY = '15.207.201.85:80'
# 通过`Capabilities`设置代理
webdriver.DesiredCapabilities.FIREFOX['proxy'] = {
"httpProxy": PROXY,
"ftpProxy": PROXY,
"sslProxy": PROXY,
"proxyType": "MANUAL",
}
# 加载自定义功能
driver = webdriver.Firefox()
# 在结果中看到orgin的值为15.207.201.85:80,说明代理设置成功
driver.get("http://httpbin.org/get")
print(driver.capabilities)
通过首选项成功设置
通过首选项设置代理也是一个可行的办法。通过Options
、profile
等对象均可设置首选项。
from selenium import webdriver
from selenium.webdriver.common.proxy import ProxyType,Proxy
# 初始化FirefoxOptions
options =webdriver.FirefoxOptions()
options.set_preference("network.proxy.type", 1)
# ip及其端口号配置为 http 协议代理
options.set_preference("network.proxy.http", "15.207.201.85")
options.set_preference("network.proxy.http_port", 80)
# 所有协议共用一种 ip 及端口,如果单独配置,不必设置该项,因为其默认为 False
options.set_preference("network.proxy.share_proxy_settings", True)
# 加载自定义选项
driver=webdriver.Firefox(options=options)
driver.get("http://httpbin.org/get")
print(driver.capabilities )
失败案例
在WebDriver
实例化时提供proxy
参数
根据文档可知,在WebDriver
实例化时可提供proxy
参数,参数值为Proxy
对象。按照这种方式,最终代理未成功设置。
查询Stack Overflow等网站得知,该问题是一个历史悠久的BUG……
from selenium import webdriver
from selenium.webdriver.common.proxy import *
myProxy = '15.207.201.85:80'
proxy = Proxy({
'proxyType': ProxyType.MANUAL,
'httpProxy': myProxy,
'sslProxy': myProxy,
'ftpProxy': myProxy,
'noProxy':''})
driver = webdriver.Firefox(proxy=proxy)
driver.get("http://httpbin.org/get")
print(driver.capabilities )
利用opitons.proxy()
方法设置
根据selenium\webdriver\firefox\options.py
中的Options
类源码可知,Options
类的proxy( value)
可设置代理,参数值为Proxy
对象。按照这种方式,最终代理未成功设置。
案例
from selenium import webdriver
from selenium.webdriver.common.proxy import ProxyType,Proxy
# 代理
PROXY = '15.207.201.85:80'
# 代理格式
proxy1 = Proxy({
'proxyType': ProxyType.MANUAL,
'httpProxy': PROXY,
'ftpProxy': PROXY,
'sslProxy': PROXY,
'noProxy': ''
})
# 初始化FirefoxOptions
options =webdriver.FirefoxOptions()
print(options is not None)
options.proxy(proxy1)
driver=webdriver.Firefox(options=options)
driver.get("http://httpbin.org/get")
print(driver.capabilities )
True
Traceback (most recent call last):
File "proxy4.py", line 19, in <module>
options.proxy(proxy1)
TypeError: 'NoneType' object is not callable
解析
输入提示 options
为'NoneType'
,但是options
不为None
。
selenium\webdriver\remote\webdriver.py
中的WebDriver
类__init__
方法提示不要使用proxy
参数,建议使用FirefoxOptions
。
if proxy is not None:
warnings.warn("Please use FirefoxOptions to set proxy",
DeprecationWarning, stacklevel=2)
proxy.add_to_capabilities(capabilities)