mdbq 4.0.71__py3-none-any.whl → 4.0.73__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mdbq/__version__.py +1 -1
- mdbq/selenium/get_driver.py +309 -109
- {mdbq-4.0.71.dist-info → mdbq-4.0.73.dist-info}/METADATA +1 -1
- {mdbq-4.0.71.dist-info → mdbq-4.0.73.dist-info}/RECORD +6 -6
- {mdbq-4.0.71.dist-info → mdbq-4.0.73.dist-info}/WHEEL +0 -0
- {mdbq-4.0.71.dist-info → mdbq-4.0.73.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION = '4.0.
|
1
|
+
VERSION = '4.0.73'
|
mdbq/selenium/get_driver.py
CHANGED
@@ -9,6 +9,8 @@ import socket
|
|
9
9
|
import tempfile
|
10
10
|
import shutil
|
11
11
|
import uuid
|
12
|
+
import subprocess
|
13
|
+
import json
|
12
14
|
|
13
15
|
dir_path = os.path.expanduser("~")
|
14
16
|
|
@@ -52,54 +54,6 @@ class GetDriver:
|
|
52
54
|
self.user_agent = user_agents[random.randint(0, len(user_agents) - 1)]
|
53
55
|
self.maximize_window = maximize_window
|
54
56
|
|
55
|
-
def __enter__(self):
|
56
|
-
"""
|
57
|
-
支持with语法自动获取driver
|
58
|
-
:return: selenium.webdriver.Chrome实例
|
59
|
-
"""
|
60
|
-
self.driver = self.getdriver()
|
61
|
-
return self.driver
|
62
|
-
|
63
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
64
|
-
"""
|
65
|
-
支持with语法自动清理资源
|
66
|
-
"""
|
67
|
-
self.quit()
|
68
|
-
|
69
|
-
def close(self):
|
70
|
-
"""
|
71
|
-
关闭浏览器窗口并清理临时目录
|
72
|
-
"""
|
73
|
-
if self.driver:
|
74
|
-
try:
|
75
|
-
self.driver.close()
|
76
|
-
except:
|
77
|
-
pass
|
78
|
-
self._cleanup_temp_dirs()
|
79
|
-
|
80
|
-
def quit(self):
|
81
|
-
"""
|
82
|
-
彻底退出浏览器并清理临时目录
|
83
|
-
"""
|
84
|
-
if self.driver:
|
85
|
-
try:
|
86
|
-
self.driver.quit()
|
87
|
-
except:
|
88
|
-
pass
|
89
|
-
self._cleanup_temp_dirs()
|
90
|
-
|
91
|
-
def _cleanup_temp_dirs(self):
|
92
|
-
"""
|
93
|
-
清理所有创建的临时目录
|
94
|
-
"""
|
95
|
-
for temp_dir in self.temp_dirs:
|
96
|
-
try:
|
97
|
-
if os.path.exists(temp_dir):
|
98
|
-
shutil.rmtree(temp_dir)
|
99
|
-
except:
|
100
|
-
pass
|
101
|
-
self.temp_dirs = []
|
102
|
-
|
103
57
|
def check_proxy(self):
|
104
58
|
"""
|
105
59
|
校验代理格式和连通性,支持http/https/socks5
|
@@ -119,14 +73,177 @@ class GetDriver:
|
|
119
73
|
except:
|
120
74
|
return False
|
121
75
|
|
76
|
+
def _get_chrome_version(self, chrome_path):
|
77
|
+
"""
|
78
|
+
获取Chrome版本号
|
79
|
+
:param chrome_path: Chrome可执行文件路径
|
80
|
+
:return: 版本号字符串,如"120.0.6099.109"
|
81
|
+
"""
|
82
|
+
try:
|
83
|
+
if platform.system().lower() == 'windows':
|
84
|
+
# Windows下尝试多种方式获取版本
|
85
|
+
# 方法1: 尝试--version参数
|
86
|
+
try:
|
87
|
+
result = subprocess.run([chrome_path, '--version'],
|
88
|
+
capture_output=True, text=True, timeout=10, shell=True)
|
89
|
+
if result.returncode == 0:
|
90
|
+
version_match = re.search(r'Chrome\s+(\d+\.\d+\.\d+\.\d+)', result.stdout)
|
91
|
+
if version_match:
|
92
|
+
return version_match.group(1)
|
93
|
+
except:
|
94
|
+
pass
|
95
|
+
|
96
|
+
# 方法2: 尝试从注册表获取版本
|
97
|
+
try:
|
98
|
+
import winreg
|
99
|
+
key_path = r"SOFTWARE\Google\Chrome\BLBeacon"
|
100
|
+
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path) as key:
|
101
|
+
version = winreg.QueryValueEx(key, "version")[0]
|
102
|
+
return version
|
103
|
+
except:
|
104
|
+
pass
|
105
|
+
|
106
|
+
# 方法3: 尝试从文件属性获取版本
|
107
|
+
try:
|
108
|
+
result = subprocess.run(['wmic', 'datafile', 'where', f'name="{chrome_path.replace("/", "\\")}"', 'get', 'version', '/value'],
|
109
|
+
capture_output=True, text=True, timeout=10, shell=True)
|
110
|
+
if result.returncode == 0:
|
111
|
+
version_match = re.search(r'Version=(\d+\.\d+\.\d+\.\d+)', result.stdout)
|
112
|
+
if version_match:
|
113
|
+
return version_match.group(1)
|
114
|
+
except:
|
115
|
+
pass
|
116
|
+
|
117
|
+
# 方法4: 尝试直接启动Chrome获取版本信息
|
118
|
+
try:
|
119
|
+
result = subprocess.run([chrome_path, '--headless', '--disable-gpu', '--dump-dom', 'about:version'],
|
120
|
+
capture_output=True, text=True, timeout=15, shell=True)
|
121
|
+
if result.returncode == 0:
|
122
|
+
version_match = re.search(r'Chrome/(\d+\.\d+\.\d+\.\d+)', result.stdout)
|
123
|
+
if version_match:
|
124
|
+
return version_match.group(1)
|
125
|
+
except:
|
126
|
+
pass
|
127
|
+
|
128
|
+
else:
|
129
|
+
# macOS和Linux下使用--version参数
|
130
|
+
result = subprocess.run([chrome_path, '--version'],
|
131
|
+
capture_output=True, text=True, timeout=10)
|
132
|
+
if result.returncode == 0:
|
133
|
+
# 输出格式: "Google Chrome 120.0.6099.109"
|
134
|
+
version_match = re.search(r'Chrome\s+(\d+\.\d+\.\d+\.\d+)', result.stdout)
|
135
|
+
if version_match:
|
136
|
+
return version_match.group(1)
|
137
|
+
except Exception as e:
|
138
|
+
print(f"获取Chrome版本失败: {e}")
|
139
|
+
return None
|
140
|
+
|
141
|
+
def _get_chromedriver_version(self, chromedriver_path):
|
142
|
+
"""
|
143
|
+
获取Chromedriver版本号
|
144
|
+
:param chromedriver_path: Chromedriver可执行文件路径
|
145
|
+
:return: 版本号字符串,如"120.0.6099.109"
|
146
|
+
"""
|
147
|
+
try:
|
148
|
+
if platform.system().lower() == 'windows':
|
149
|
+
# Windows下使用shell=True确保参数正确传递
|
150
|
+
result = subprocess.run([chromedriver_path, '--version'],
|
151
|
+
capture_output=True, text=True, timeout=10, shell=True)
|
152
|
+
else:
|
153
|
+
result = subprocess.run([chromedriver_path, '--version'],
|
154
|
+
capture_output=True, text=True, timeout=10)
|
155
|
+
|
156
|
+
if result.returncode == 0:
|
157
|
+
# 输出格式: "ChromeDriver 120.0.6099.109"
|
158
|
+
version_match = re.search(r'ChromeDriver\s+(\d+\.\d+\.\d+\.\d+)', result.stdout)
|
159
|
+
if version_match:
|
160
|
+
return version_match.group(1)
|
161
|
+
except Exception as e:
|
162
|
+
print(f"获取Chromedriver版本失败: {e}")
|
163
|
+
return None
|
164
|
+
|
165
|
+
def _check_version_compatibility(self, chrome_path, chromedriver_path):
|
166
|
+
"""
|
167
|
+
检查Chrome和Chromedriver版本兼容性
|
168
|
+
:param chrome_path: Chrome可执行文件路径
|
169
|
+
:param chromedriver_path: Chromedriver可执行文件路径
|
170
|
+
:return: (is_compatible, chrome_version, chromedriver_version)
|
171
|
+
"""
|
172
|
+
chrome_version = self._get_chrome_version(chrome_path)
|
173
|
+
chromedriver_version = self._get_chromedriver_version(chromedriver_path)
|
174
|
+
|
175
|
+
# 如果无法获取版本信息,返回True允许尝试启动
|
176
|
+
if not chrome_version or not chromedriver_version:
|
177
|
+
print(f"警告: 无法获取版本信息 - Chrome: {chrome_version}, Chromedriver: {chromedriver_version}")
|
178
|
+
return True, chrome_version, chromedriver_version
|
179
|
+
|
180
|
+
# 提取主版本号进行比较
|
181
|
+
chrome_major = chrome_version.split('.')[0]
|
182
|
+
chromedriver_major = chromedriver_version.split('.')[0]
|
183
|
+
|
184
|
+
is_compatible = chrome_major == chromedriver_major
|
185
|
+
return is_compatible, chrome_version, chromedriver_version
|
186
|
+
|
187
|
+
def _try_create_driver(self, chrome_path, chromedriver_path, option, temp_dir):
|
188
|
+
"""
|
189
|
+
尝试创建Chrome WebDriver实例
|
190
|
+
:param chrome_path: Chrome可执行文件路径
|
191
|
+
:param chromedriver_path: Chromedriver可执行文件路径
|
192
|
+
:param option: ChromeOptions实例
|
193
|
+
:param temp_dir: 临时目录路径
|
194
|
+
:return: Chrome WebDriver实例或None
|
195
|
+
"""
|
196
|
+
try:
|
197
|
+
option.binary_location = chrome_path
|
198
|
+
service = Service(chromedriver_path)
|
199
|
+
driver = webdriver.Chrome(service=service, options=option)
|
200
|
+
if self.maximize_window:
|
201
|
+
driver.maximize_window()
|
202
|
+
|
203
|
+
# --- 防反爬:注入多段JS隐藏Selenium特征 ---
|
204
|
+
js_hide_features = [
|
205
|
+
# 隐藏webdriver属性
|
206
|
+
"Object.defineProperty(navigator, 'webdriver', {get: () => undefined, configurable: true});",
|
207
|
+
# 模拟真实浏览器插件
|
208
|
+
"Object.defineProperty(navigator, 'plugins', {get: () => [1,2,3,4,5], configurable: true});",
|
209
|
+
# 设置语言
|
210
|
+
"Object.defineProperty(navigator, 'languages', {get: () => ['zh-CN', 'zh', 'en'], configurable: true});",
|
211
|
+
# 模拟Chrome运行时
|
212
|
+
"window.chrome = {runtime: {}, loadTimes: function(){}, csi: function(){}, app: {}};",
|
213
|
+
# 删除原型链上的webdriver
|
214
|
+
"delete window.navigator.__proto__.webdriver;",
|
215
|
+
# 删除Selenium相关属性
|
216
|
+
r"for (let key in window) {if (key.match(/^[\$\_]{3,}/)) {try {delete window[key];} catch(e){}}}",
|
217
|
+
# 隐藏自动化相关属性
|
218
|
+
"Object.defineProperty(navigator, 'permissions', {get: () => ({query: () => Promise.resolve({state: 'granted'})}), configurable: true});",
|
219
|
+
# 模拟真实的navigator属性
|
220
|
+
"Object.defineProperty(navigator, 'hardwareConcurrency', {get: () => 8, configurable: true});",
|
221
|
+
"Object.defineProperty(navigator, 'deviceMemory', {get: () => 8, configurable: true});",
|
222
|
+
# 防止检测自动化工具
|
223
|
+
"Object.defineProperty(navigator, 'maxTouchPoints', {get: () => 0, configurable: true});",
|
224
|
+
# 隐藏CDP相关属性
|
225
|
+
"delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;",
|
226
|
+
"delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;",
|
227
|
+
"delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;"
|
228
|
+
]
|
229
|
+
for js in js_hide_features:
|
230
|
+
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": js})
|
231
|
+
|
232
|
+
return driver
|
233
|
+
except Exception as e:
|
234
|
+
print(f"创建Chrome WebDriver失败: {e}")
|
235
|
+
return None
|
236
|
+
|
122
237
|
def getdriver(self):
|
123
238
|
"""
|
124
239
|
创建并返回Chrome WebDriver实例,自动注入反检测JS,异常时抛出GetDriverException
|
240
|
+
智能版本检测:优先使用正式版,版本不匹配时自动切换到测试版
|
125
241
|
:return: selenium.webdriver.Chrome实例
|
126
242
|
:raises: GetDriverException
|
127
243
|
"""
|
128
244
|
if not self.check_proxy():
|
129
245
|
raise GetDriverException(f"代理不可用或格式错误: {self.proxy}")
|
246
|
+
|
130
247
|
option = webdriver.ChromeOptions() # 浏览器启动选项
|
131
248
|
if self.headless:
|
132
249
|
option.add_argument("--headless") # 设置无界面模式
|
@@ -134,16 +251,19 @@ class GetDriver:
|
|
134
251
|
option.add_argument("--disable-gpu")
|
135
252
|
option.add_argument("--no-sandbox")
|
136
253
|
option.add_argument("--disable-dev-shm-usage")
|
254
|
+
# 隐藏Chrome测试版提示信息
|
255
|
+
option.add_argument("--disable-blink-features=AutomationControlled")
|
256
|
+
option.add_argument("--disable-features=VizDisplayCompositor")
|
257
|
+
option.add_argument("--disable-background-timer-throttling")
|
258
|
+
option.add_argument("--disable-backgrounding-occluded-windows")
|
259
|
+
option.add_argument("--disable-renderer-backgrounding")
|
260
|
+
option.add_argument("--disable-features=TranslateUI")
|
261
|
+
option.add_argument("--disable-ipc-flooding-protection")
|
137
262
|
# 添加唯一的用户数据目录,避免Chrome实例冲突
|
138
263
|
temp_dir = tempfile.mkdtemp(prefix=f'chrome_automation_{uuid.uuid4().hex[:8]}_')
|
139
264
|
option.add_argument(f'--user-data-dir={temp_dir}')
|
140
265
|
option.add_argument('--no-first-run')
|
141
266
|
option.add_argument('--no-default-browser-check')
|
142
|
-
option.add_argument('--disable-background-timer-throttling')
|
143
|
-
option.add_argument('--disable-backgrounding-occluded-windows')
|
144
|
-
option.add_argument('--disable-renderer-backgrounding')
|
145
|
-
option.add_argument('--disable-features=TranslateUI')
|
146
|
-
option.add_argument('--disable-ipc-flooding-protection')
|
147
267
|
# 关键安全浏览禁用参数
|
148
268
|
option.add_argument('--allow-insecure-localhost')
|
149
269
|
option.add_argument('--allow-running-insecure-content')
|
@@ -177,91 +297,171 @@ class GetDriver:
|
|
177
297
|
"profile.password_manager_enabled": False,
|
178
298
|
"download_restrictions": 0,
|
179
299
|
}
|
300
|
+
option.add_experimental_option("prefs", prefs)
|
301
|
+
|
180
302
|
# 平台与路径自动检测
|
181
303
|
sys_platform = platform.system().lower()
|
182
304
|
chrome_path = self.chrome_path
|
183
305
|
chromedriver_path = self.chromedriver_path
|
306
|
+
|
184
307
|
try:
|
185
308
|
if sys_platform == 'windows':
|
186
309
|
if not chrome_path:
|
187
|
-
|
310
|
+
chrome_path_candidates = [
|
311
|
+
'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', # 正式版
|
312
|
+
os.path.join(f'C:\\Users\\{getpass.getuser()}', 'chrome\\chrome_win64\\chrome.exe'), # 测试版
|
313
|
+
]
|
188
314
|
if not chromedriver_path:
|
189
|
-
|
190
|
-
|
191
|
-
|
315
|
+
chromedriver_path_candidates = [
|
316
|
+
os.path.join(f'C:\\Users\\{getpass.getuser()}', 'chrome\\chromedriver.exe'),
|
317
|
+
os.path.join(f'C:\\Users\\{getpass.getuser()}', 'chrome\\chrome_win64\\chromedriver.exe'),
|
318
|
+
]
|
192
319
|
elif sys_platform == 'linux':
|
193
320
|
if not chrome_path:
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
"""
|
321
|
+
chrome_path_candidates = [
|
322
|
+
'/usr/bin/google-chrome', # 正式版
|
323
|
+
'/usr/bin/chrome/chrome', # 测试版
|
324
|
+
]
|
199
325
|
if not chromedriver_path:
|
200
|
-
|
201
|
-
|
202
|
-
|
326
|
+
chromedriver_path_candidates = [
|
327
|
+
'/usr/local/bin/chromedriver',
|
328
|
+
'/usr/bin/chromedriver',
|
329
|
+
]
|
203
330
|
elif sys_platform == 'darwin':
|
204
331
|
if not chrome_path:
|
205
|
-
# 优先使用用户指定的默认路径
|
206
332
|
chrome_path_candidates = [
|
207
|
-
'/
|
208
|
-
'/usr/local/chrome/Google Chrome for Testing.app',
|
209
|
-
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
210
|
-
'/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome',
|
333
|
+
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', # 正式版
|
334
|
+
'/usr/local/chrome/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing', # 测试版
|
211
335
|
]
|
212
|
-
chrome_path = next((p for p in chrome_path_candidates if os.path.exists(p)), None)
|
213
336
|
if not chromedriver_path:
|
214
337
|
chromedriver_path_candidates = [
|
215
338
|
'/usr/local/chrome/chromedriver',
|
216
339
|
'/usr/local/bin/chromedriver',
|
217
340
|
'/opt/homebrew/bin/chromedriver',
|
218
341
|
]
|
219
|
-
chromedriver_path = next((p for p in chromedriver_path_candidates if os.path.exists(p)), None)
|
220
|
-
if not chrome_path or not chromedriver_path:
|
221
|
-
raise GetDriverException("未找到Chrome或Chromedriver,请手动指定chrome_path和chromedriver_path")
|
222
|
-
# option.binary_location = chrome_path # macOS 设置此参数报错
|
223
|
-
service = Service(chromedriver_path)
|
224
342
|
else:
|
225
343
|
raise GetDriverException(f"不支持的平台: {sys_platform}")
|
344
|
+
|
345
|
+
# 如果用户指定了路径,直接使用
|
346
|
+
if chrome_path and chromedriver_path:
|
347
|
+
driver = self._try_create_driver(chrome_path, chromedriver_path, option, temp_dir)
|
348
|
+
if driver:
|
349
|
+
self.temp_dirs.append(temp_dir)
|
350
|
+
self.driver = driver
|
351
|
+
return driver
|
352
|
+
else:
|
353
|
+
raise GetDriverException(f"指定的Chrome路径无法启动: {chrome_path}")
|
354
|
+
|
355
|
+
# 智能版本检测和切换
|
356
|
+
chrome_paths = [p for p in chrome_path_candidates if os.path.exists(p)]
|
357
|
+
chromedriver_paths = [p for p in chromedriver_path_candidates if os.path.exists(p)]
|
358
|
+
|
359
|
+
if not chrome_paths:
|
360
|
+
raise GetDriverException("未找到Chrome浏览器,请手动指定chrome_path")
|
361
|
+
if not chromedriver_paths:
|
362
|
+
raise GetDriverException("未找到Chromedriver,请手动指定chromedriver_path")
|
363
|
+
|
364
|
+
# 优先尝试正式版Chrome
|
365
|
+
for chrome_path in chrome_paths:
|
366
|
+
for chromedriver_path in chromedriver_paths:
|
367
|
+
# 检查版本兼容性
|
368
|
+
is_compatible, chrome_version, chromedriver_version = self._check_version_compatibility(chrome_path, chromedriver_path)
|
369
|
+
|
370
|
+
if is_compatible:
|
371
|
+
# print(f"版本兼容: Chrome {chrome_version}, Chromedriver {chromedriver_version}")
|
372
|
+
driver = self._try_create_driver(chrome_path, chromedriver_path, option, temp_dir)
|
373
|
+
if driver:
|
374
|
+
self.temp_dirs.append(temp_dir)
|
375
|
+
self.driver = driver
|
376
|
+
return driver
|
377
|
+
else:
|
378
|
+
print(f"版本不兼容: Chrome {chrome_version}, Chromedriver {chromedriver_version}")
|
379
|
+
# 即使版本不兼容也尝试启动,有时可能仍然可以工作
|
380
|
+
driver = self._try_create_driver(chrome_path, chromedriver_path, option, temp_dir)
|
381
|
+
if driver:
|
382
|
+
print("警告:版本不兼容但启动成功,建议更新Chromedriver")
|
383
|
+
self.temp_dirs.append(temp_dir)
|
384
|
+
self.driver = driver
|
385
|
+
return driver
|
386
|
+
|
387
|
+
# 如果所有组合都失败,抛出异常
|
388
|
+
raise GetDriverException("所有Chrome和Chromedriver组合都无法启动,请检查版本兼容性")
|
389
|
+
|
226
390
|
except Exception as e:
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
if self.maximize_window:
|
232
|
-
driver.maximize_window()
|
233
|
-
# --- 防反爬:注入多段JS隐藏Selenium特征 ---
|
234
|
-
js_hide_features = [
|
235
|
-
"Object.defineProperty(navigator, 'webdriver', {get: () => false});",
|
236
|
-
"Object.defineProperty(navigator, 'plugins', {get: () => [1,2,3,4,5]});",
|
237
|
-
"Object.defineProperty(navigator, 'languages', {get: () => ['zh-CN', 'zh', 'en']});",
|
238
|
-
"window.chrome = {runtime: {}};",
|
239
|
-
"delete window.navigator.__proto__.webdriver;",
|
240
|
-
r"for (let key in window) {if (key.match(/^[\$\_]{3,}/)) {try {delete window[key];} catch(e){}}}"
|
241
|
-
]
|
242
|
-
for js in js_hide_features:
|
391
|
+
try:
|
392
|
+
if os.path.exists(temp_dir):
|
393
|
+
shutil.rmtree(temp_dir)
|
394
|
+
except Exception as cleanup_error:
|
243
395
|
pass
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
396
|
+
if isinstance(e, GetDriverException):
|
397
|
+
raise e
|
398
|
+
else:
|
399
|
+
raise GetDriverException(f"启动ChromeDriver失败: {e}")
|
400
|
+
|
401
|
+
def _cleanup_temp_dirs(self):
|
402
|
+
"""
|
403
|
+
清理所有创建的临时目录
|
404
|
+
"""
|
405
|
+
for temp_dir in self.temp_dirs:
|
249
406
|
try:
|
250
407
|
if os.path.exists(temp_dir):
|
251
408
|
shutil.rmtree(temp_dir)
|
252
|
-
except
|
409
|
+
except:
|
253
410
|
pass
|
254
|
-
|
411
|
+
self.temp_dirs = []
|
412
|
+
|
413
|
+
def __enter__(self):
|
414
|
+
"""
|
415
|
+
支持with语法自动获取driver
|
416
|
+
:return: selenium.webdriver.Chrome实例
|
417
|
+
"""
|
418
|
+
self.driver = self.getdriver()
|
419
|
+
return self.driver
|
420
|
+
|
421
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
422
|
+
"""
|
423
|
+
支持with语法自动清理资源
|
424
|
+
"""
|
425
|
+
self.quit()
|
426
|
+
|
427
|
+
def close(self):
|
428
|
+
"""
|
429
|
+
关闭浏览器窗口并清理临时目录
|
430
|
+
"""
|
431
|
+
if self.driver:
|
432
|
+
try:
|
433
|
+
self.driver.close()
|
434
|
+
except:
|
435
|
+
pass
|
436
|
+
self._cleanup_temp_dirs()
|
437
|
+
|
438
|
+
def quit(self):
|
439
|
+
"""
|
440
|
+
彻底退出浏览器并清理临时目录
|
441
|
+
"""
|
442
|
+
if self.driver:
|
443
|
+
try:
|
444
|
+
self.driver.quit()
|
445
|
+
except:
|
446
|
+
pass
|
447
|
+
self._cleanup_temp_dirs()
|
255
448
|
|
256
449
|
|
257
450
|
if __name__ == '__main__':
|
258
|
-
with GetDriver(
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
) as driver:
|
266
|
-
|
267
|
-
|
451
|
+
# with GetDriver(
|
452
|
+
# headless=True,
|
453
|
+
# proxy=None, # 代理('socks5://127.0.0.1:1080')
|
454
|
+
# user_agent=None,
|
455
|
+
# download_dir=None,
|
456
|
+
# chrome_path=None,
|
457
|
+
# chromedriver_path=None,
|
458
|
+
# ) as driver:
|
459
|
+
# driver.get('https://www.baidu.com')
|
460
|
+
# print(driver.title)
|
461
|
+
|
462
|
+
|
463
|
+
driver = GetDriver(headless=False).getdriver()
|
464
|
+
driver.get('https://www.baidu.com')
|
465
|
+
print(driver.title)
|
466
|
+
import time
|
467
|
+
time.sleep(1000)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
|
2
|
-
mdbq/__version__.py,sha256=
|
2
|
+
mdbq/__version__.py,sha256=v9CxLcSDpoYTepVqra_1iaKkOd7scJSGR8ITdcM5Nr4,18
|
3
3
|
mdbq/log/__init__.py,sha256=Mpbrav0s0ifLL7lVDAuePEi1hJKiSHhxcv1byBKDl5E,15
|
4
4
|
mdbq/log/mylogger.py,sha256=kPe3wsQNaB1slfX-Z7VMqzZoMoqPfc7ylYXZDBeFzzI,24945
|
5
5
|
mdbq/myconf/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
@@ -22,9 +22,9 @@ mdbq/pbix/refresh_all.py,sha256=OBT9EewSZ0aRS9vL_FflVn74d4l2G00wzHiikCC4TC0,5926
|
|
22
22
|
mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
|
23
23
|
mdbq/redis/getredis.py,sha256=vpBuNc22uj9Vr-_Dh25_wpwWM1e-072EAAIBdB_IpL0,23494
|
24
24
|
mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
|
25
|
-
mdbq/selenium/get_driver.py,sha256=
|
25
|
+
mdbq/selenium/get_driver.py,sha256=ppV_CJvvRu2__VIYQS-nfhW0lOlesuR11bG_d2MfmNs,21523
|
26
26
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
27
|
-
mdbq-4.0.
|
28
|
-
mdbq-4.0.
|
29
|
-
mdbq-4.0.
|
30
|
-
mdbq-4.0.
|
27
|
+
mdbq-4.0.73.dist-info/METADATA,sha256=i2uf1d6ZPcI60XOSOGXW6wgePbz_pHsumb0-LGJD8Ns,364
|
28
|
+
mdbq-4.0.73.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
29
|
+
mdbq-4.0.73.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
30
|
+
mdbq-4.0.73.dist-info/RECORD,,
|
File without changes
|
File without changes
|