当前位置:网站首页>selenium.common.exceptions.WebDriverException: Message: ‘chromedriver‘ executable needs to be in PAT
selenium.common.exceptions.WebDriverException: Message: ‘chromedriver‘ executable needs to be in PAT
2022-04-23 20:08:00 【liulanba】
最近需要使用一下selenium,刚运行就报错了。。。
前提准备:
1.安装selenium
2.下载chrome对应版本的chromedriver
代码就是一个简单的demo:
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('http://www.baidu.com/')
time.sleep(10)
运行报错:
网上说要把chromedriver放到环境变量,放进去还是报错!!
然后就直接看源码吧:
这个过程很繁琐,很枯燥,嫌废话连篇请直接翻到文末解决方法~~
这个过程很繁琐,很枯燥,嫌废话连篇请直接翻到文末解决方法~~
这个过程很繁琐,很枯燥,嫌废话连篇请直接翻到文末解决方法~~
1.代码报错入口:
browser = webdriver.Chrome()
2.首先看报错被挂起的地方:
File “E:\APP_Install\python_install\lib\site-packages\selenium\webdriver\common\service.py”, line 83, in start
os.path.basename(self.path), self.start_error_message)
对应代码:
def start(self):
""" Starts the Service. :Exceptions: - WebDriverException : Raised either when it can't start the service or when it can't connect to the service """
try:
cmd = [self.path]
cmd.extend(self.command_line_args())
self.process = subprocess.Popen(cmd, env=self.env,
close_fds=system() != 'Windows',
stdout=self.log_file,
stderr=self.log_file,
stdin=PIPE,
creationflags=self.creationflags)
except TypeError:
raise
except OSError as err:
if err.errno == errno.ENOENT:
raise WebDriverException(
"'%s' executable needs to be in PATH. %s" % (
os.path.basename(self.path), self.start_error_message)
)
elif err.errno == errno.EACCES:
raise WebDriverException(
"'%s' executable may have wrong permissions. %s" % (
os.path.basename(self.path), self.start_error_message)
)
else:
raise
3.是start()方法的try失败了,这里可以看到是self.path的问题,再往上回溯看调用start方法的地方,self.path = executable找到传值 executable的地方:
File “E:\APP_Install\python_install\lib\site-packages\selenium\webdriver\chromium\webdriver.py”, line 90, in init
self.service.start()
相关代码如下:
class ChromiumDriver(RemoteWebDriver):
""" Controls the WebDriver instance of ChromiumDriver and allows you to drive the browser. """
def __init__(self, browser_name, vendor_prefix,
port=DEFAULT_PORT, options: BaseOptions = None, service_args=None,
desired_capabilities=None, service_log_path=DEFAULT_SERVICE_LOG_PATH,
service: Service = None, keep_alive=DEFAULT_KEEP_ALIVE):
if desired_capabilities:
warnings.warn('desired_capabilities has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
if port != DEFAULT_PORT:
warnings.warn('port has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
self.port = port
if service_log_path != DEFAULT_SERVICE_LOG_PATH:
warnings.warn('service_log_path has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
if keep_alive != DEFAULT_KEEP_ALIVE and type(self) == __class__:
warnings.warn('keep_alive has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
else:
keep_alive = True
self.vendor_prefix = vendor_prefix
_ignore_proxy = None
if not options:
options = self.create_options()
if desired_capabilities:
for key, value in desired_capabilities.items():
options.set_capability(key, value)
if options._ignore_local_proxy:
_ignore_proxy = options._ignore_local_proxy
if not service:
raise AttributeError('service cannot be None')
self.service = service
self.service.start()
4.粗看似乎没什么问题,self.service.start()前面并没有进行什么特殊定义和处理,并没有进行传参"self.path",这时候就要考虑python 的继承问题了,我进入它的父类RemoteWebDriver也没有发现导致该报错的问题,这时就要考虑子类了,我们此时还忽略了一个问题:报错入口: browser = webdriver.Chrome()
webdriver.Chrome()代码如下:
E:\APP_Install\python_install\Lib\site-packages\selenium\webdriver\chrome\webdriver.py
class WebDriver(ChromiumDriver):
def __init__(self, executable_path=DEFAULT_EXECUTABLE_PATH, port=DEFAULT_PORT,
options: Options = None, service_args=None,
desired_capabilities=None, service_log_path=DEFAULT_SERVICE_LOG_PATH,
chrome_options=None, service: Service = None, keep_alive=DEFAULT_KEEP_ALIVE):
if executable_path != 'chromedriver':
warnings.warn('executable_path has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
if chrome_options:
warnings.warn('use options instead of chrome_options',
DeprecationWarning, stacklevel=2)
options = chrome_options
if keep_alive != DEFAULT_KEEP_ALIVE:
warnings.warn('keep_alive has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
else:
keep_alive = True
if not service:
service = Service(executable_path, port, service_args, service_log_path)
super(WebDriver, self).__init__(DesiredCapabilities.CHROME['browserName'], "goog",
port, options,
service_args, desired_capabilities,
service_log_path, service, keep_alive)
5.这不就连起来了吗,子类调用父类的__init__方法:
super(WebDriver, self).__init__ #和第3步相连
6.这个时候我们要关注Service类的传参,即super(WebDriver, self).__init__的倒数第二个参数service:
service = Service(executable_path, port, service_args, service_log_path)
对应代码:
E:\APP_Install\python_install\Lib\site-packages\selenium\webdriver\chrome\service.py
class Service(service.ChromiumService):
def __init__(self, executable_path: str = DEFAULT_EXECUTABLE_PATH,
port: int = 0, service_args: List[str] = None,
log_path: str = None, env: dict = None):
super(Service, self).__init__(
executable_path,
port,
service_args,
log_path,
env,
"Please see https://chromedriver.chromium.org/home")
这里有同学可能有疑问了?
此处的Service和第2步的Service不是一个类啊!
是的,这里还有两层嵌套关系,直接ctrl点击进去就可以看:
1.super(Service, self).__init__
2.service.Service.__init__(self, executable_path, port=port, env=env, start_error_message=start_error_message)
7.根据第6步的关系我们知道:在第2步Service出现问题的self.path就是这里面的executable_path,我们来看下这个参数的定义:
executable_path=DEFAULT_EXECUTABLE_PATH
8.刨根究底来看这个常量的定义:
DEFAULT_EXECUTABLE_PATH = "chromedriver"
9.这不就出来了,定义的executable_path 解释器没有找到,就直接使用chromedriver了,所以导致报错,我们确认一下这个参数的定义:
- executable_path - Deprecated: path to the executable. If the default is used it assumes the executable is in the $PATH
10.至此,有两个解决办法:
1.直接修改DEFAULT_EXECUTABLE_PATH 为你机器的chromedriver的路径
哈哈,但是这个方法只适用于你的机器了,因此我们考虑脚本传参executable_path:
那不就是第一个参数吗?直接传进去,大功告成:
from selenium import webdriver
import time
browser = webdriver.Chrome("F:\google_download\chromedriver_99.0/chromedriver.exe")
browser.get('http://www.baidu.com/')
time.sleep(10)
版权声明
本文为[liulanba]所创,转载请带上原文链接,感谢
https://blog.csdn.net/liulanba/article/details/124364135
边栏推荐
- Kubernetes entry to mastery - bare metal loadbalance 80 443 port exposure precautions
- 【数值预测案例】(3) LSTM 时间序列电量预测,附Tensorflow完整代码
- 山东大学软件学院项目实训-创新实训-网络安全靶场实验平台(八)
- Possible root causes include a too low setting for -Xss and illegal cyclic inheritance dependencies
- Physical meaning of FFT: 1024 point FFT is 1024 real numbers. The actual input to FFT is 1024 complex numbers (imaginary part is 0), and the output is also 1024 complex numbers. The effective data is
- 山东大学软件学院项目实训-创新实训-网络安全靶场实验平台(六)
- 对普通bean进行Autowired字段注入
- uIP1.0 主动发送的问题理解
- MFCC: Mel频率倒谱系数计算感知频率和实际频率转换
- R语言ggplot2可视化分面图(facet_wrap)、使用lineheight参数自定义设置分面图标签栏(灰色标签栏)的高度
猜你喜欢
Class loading process of JVM
Kubernetes entry to mastery - bare metal loadbalance 80 443 port exposure precautions
Virtual machine performance monitoring and fault handling tools
如何在BNB鏈上創建BEP-20通證
Class loading mechanism
Possible root causes include a too low setting for -Xss and illegal cyclic inheritance dependencies
LeetCode动态规划训练营(1~5天)
MySQL 进阶 锁 -- MySQL锁概述、MySQL锁的分类:全局锁(数据备份)、表级锁(表共享读锁、表独占写锁、元数据锁、意向锁)、行级锁(行锁、间隙锁、临键锁)
Zero cost, zero foundation, build profitable film and television applet
Leetcode XOR operation
随机推荐
ESP8266-入门第一篇
精简CUDA教程——CUDA Driver API
NC basic usage 1
R语言ggplot2可视化:ggplot2可视化散点图并使用geom_mark_ellipse函数在数据簇或数据分组的数据点周围添加椭圆进行注释
使用 WPAD/PAC 和 JScript在win11中进行远程代码执行
@MapperScan与@Mapper
Mysql database - connection query
Building googlenet neural network based on pytorch for flower recognition
nc基础用法2
Kubernetes入门到精通-在 Kubernetes 上安装 OpenELB
Possible root causes include a too low setting for -Xss and illegal cyclic inheritance dependencies
Scrum Patterns之理解各种团队模式
@Mapperscan and @ mapper
C语言的十六进制printf为何输出有时候输出带0xFF有时没有
本地调用feign接口报404
山大网安靶场实验平台项目—个人记录(四)
Physical meaning of FFT: 1024 point FFT is 1024 real numbers. The actual input to FFT is 1024 complex numbers (imaginary part is 0), and the output is also 1024 complex numbers. The effective data is
R语言ggplot2可视化分面图(facet_wrap)、使用lineheight参数自定义设置分面图标签栏(灰色标签栏)的高度
MySQL advanced lock - overview of MySQL locks and classification of MySQL locks: global lock (data backup), table level lock (table shared read lock, table exclusive write lock, metadata lock and inte
数据库查询 - 选课系统