selenium
2025年9月5日大约 6 分钟
官网:https://googlechromelabs.github.io/chrome-for-testing/#stable
国内镜像:https://registry.npmmirror.com/binary.html?path=chrome-for-testing/
Chrome extension source viewer
element not interactable 元素不可交互
使用脚本执行
resp = requests.get(r'https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js')
# 直接执行jquery源码
self.driver.execute_script(resp.content.decode())
time.sleep(2)
self.driver.execute_script("$(arguments[0]).click()",xpath)
操作打开的浏览器
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=13888 --remote-debugging-address=0.0.0.0 --user-data-dir=D://1388
import time
import subprocess
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
# Connect Selenium to the running Chrome
option = Options()
option.debugger_address = "localhost:13888"
# Specify path to your ChromeDriver
service = Service(executable_path="chromedriver.exe")
driver = webdriver.Chrome(service=service, options=option)
# Visit the site
driver.get("https://catpd.cn")
# Wait so you can see the browser
time.sleep(10)
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
import subprocess
# 打开浏览器
subprocess.Popen("C:\Program Files\Google\Chrome\Application\chrome.exe --remote-debugging-port=9527")
option = Options()
option.add_experimental_option("debuggerAddress", "localhost:9527")
driver = Chrome(executable_path=r"chromedriver.exe", options=option)
2
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import base64
from selenium.webdriver.remote.command import Command
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.chrome.remote_connection import ChromeRemoteConnection
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import InvalidElementStateException
class MyWebDriver(RemoteWebDriver):
"""
Controls the ChromeDriver and allows you to drive the browser.
You will need to download the ChromeDriver executable from
http://chromedriver.storage.googleapis.com/index.html
"""
def __init__(self, command_executor, session_id):
self.r_session_id = session_id
RemoteWebDriver.__init__(self, command_executor=command_executor, desired_capabilities={})
def start_session(self, capabilities, browser_profile=None):
"""
重写start_session方法
"""
if not isinstance(capabilities, dict):
raise InvalidElementStateException("Capabilities must be a dictionary")
if browser_profile:
if "moz:firefoxOptions" in capabilities:
capabilities["moz:firefoxOptions"]["profile"] = browser_profile.encoded
else:
capabilities.update({'firefox_profile': browser_profile.encoded})
self.capabilities = Options().to_capabilities()
self.session_id = self.r_session_id
self.w3c = False
def launch_app(self, id):
"""Launches Chrome app specified by id."""
return self.execute("launchApp", {'id': id})
def quit(self):
"""
Closes the browser and shuts down the ChromeDriver executable
that is started when starting the ChromeDriver
"""
try:
RemoteWebDriver.quit(self)
except:
# We don't care about the message because something probably has gone wrong
pass
finally:
self.service.stop()
def create_options(self):
return Options()
import time
from selenium import webdriver
from my_remote_chrome import MyWebDriver
driver = webdriver.Chrome(executable_path='./chromedriver.exe')
executor_url = driver.command_executor._url
session_id = driver.session_id
driver.get("http://www.spiderpy.cn/")
print(session_id)
print(executor_url)
driver2 = MyWebDriver(command_executor=executor_url, session_id=session_id)
print(111111)
print(driver2.current_url)
driver2.get("https://www.baidu.com")
time.sleep(10)
自动下载网站视频
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pyautogui, time
download_dir = r"D:\wjn\cs\redio" # 替换为你的路径
# 你的连接代码
option = Options()
option.debugger_address = "localhost:13888"
service = Service(executable_path="chromedriver.exe")
driver = webdriver.Chrome(service=service, options=option)
def get_current_window():
# 获取所有窗口句柄
windows = driver.window_handles
# 切换到最新打开的窗口(最后一个)
driver.switch_to.window(windows[-1])
def click_video():
# 点击链接
a_xpath = "/html/body/div[3]/div/div/div/div/div/div[6]/div[1]/div/div[5]/div[2]/ul/li[1]/a"
driver.find_element(by=By.XPATH, value=a_xpath).click()
time.sleep(3)
get_current_window()
# 可选:验证是否切换成功
print("当前窗口标题:", driver.title)
time.sleep(1)
pyautogui.click(100, 100)
time.sleep(0.5)
# 再发送快捷键
pyautogui.hotkey('ctrl', 'm')
time.sleep(3)
def download():
get_current_window()
max_wait = 600 # 最大等待时间(秒)
poll_frequency = 1 # 每秒检测一次
start_time = time.time()
while True:
try:
element = driver.find_element(By.XPATH,
"/html/body/div[1]/div/div[1]/div[3]/section/div[4]/div/div[1]/div/div[2]/div[4]/div/div/button[1]")
is_displayed = element.is_displayed()
is_enabled = element.is_enabled()
# 判断元素是否可见、可用,并且用 JS 检测是否被遮挡
clickable = False
if is_displayed and is_enabled:
clickable = driver.execute_script(
"var elem = arguments[0];"
"var rect = elem.getBoundingClientRect();"
"return (rect.width > 0 && rect.height > 0 && window.getComputedStyle(elem).visibility !== 'hidden');",
element)
print(f"检测状态 -> 显示: {is_displayed}, 可用: {is_enabled}, 可点击: {clickable}")
if clickable:
element.click()
print("元素已点击!")
break
except Exception as e:
print(f"检测元素异常: {e}")
if time.time() - start_time > max_wait:
print("无法下载,等待超时。")
break
time.sleep(poll_frequency)
click_video()
download()
发布抖音
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pyautogui, time
option = Options()
option.debugger_address = "localhost:13889"
service = Service(executable_path="chromedriver.exe")
driver = webdriver.Chrome(service=service, options=option)
def upload_images():
"""
抖音上传照片, 需要定位到https://creator.douyin.com/creator-micro/content/upload 页面
:return:
"""
inputs = driver.find_elements(By.XPATH, '//input[@type="file"]')
for i, inp in enumerate(inputs):
print(f"Input {i}: {inp.get_attribute('outerHTML')}")
image_input = inputs[1]
driver.execute_script("arguments[0].style.display = 'block';", image_input)
#
# # 上传图片(必须是绝对路径,支持多选)
# # image_input.send_keys(r"C:\Users\wjn_0\Desktop\shortkey.png")
#
# 可选:上传多个图片(分号隔开,Windows 支持)
file_paths = [
r"C:\Users\wjn_0\Desktop\shortkey.png",
r"C:\Users\wjn_0\Desktop\bg.png"
]
image_input.send_keys('\n'.join(file_paths))
upload_images()
import base64
import os.path
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pyautogui, time
from PIL import Image
from config import imgs_dir
from message import print_message
class ChromeDriver:
def __init__(self,option:Options=None):
print(f""" 初始化driver 驱动""")
service = Service(executable_path="drivers/chromedriver.exe")
self.driver = webdriver.Chrome(service=service, options=option)
class ChromePrtScDriver(ChromeDriver):
"""
浏览器截图驱动
"""
def __init__(self):
options = Options()
# options.add_argument('--headless') # 无头模式,不弹出浏览器窗口
# options.add_argument('--disable-gpu') # 禁用 GPU 加速
# options.add_argument('window-size=1920x1080') # 设置浏览器窗口大小
super().__init__(option=options)
def get(self,url:str,target_file_name:str):
"""
:param url: html 地址
:param target_file_name:
:return:
"""
self.driver.maximize_window()
# 访问本地 HTML 文件
self.driver.get(url)
# 等待页面加载完成
time.sleep(3)
# 截图并保存
screenshot_path = os.path.join(imgs_dir,f"{target_file_name}.png")
# self.driver.save_screenshot(screenshot_path)
# 使用 DevTools 协议截图整页
result = self.driver.execute_cdp_cmd("Page.captureScreenshot", {
"captureBeyondViewport": True,
"fromSurface": True
})
# 保存截图
with open(screenshot_path, "wb") as f:
f.write(base64.b64decode(result['data']))
# 可选:使用 Pillow 进行裁剪或进一步处理
image = Image.open(screenshot_path)
image.show() # 显示截图(可选)
# 关闭 WebDriver
self.driver.quit()
class ChromeDownLoadDriver(ChromeDriver):
"""
浏览器视频下载驱动
"""
def __init__(self):
print(f"""
打开 Stream Recorder 的快捷键需要设置为: Ctrl+M
""")
option = Options()
option.debugger_address = "localhost:13888"
super().__init__(option=option)
# self.driver.get("https://tv.cctv.com/lm/xwlb/")
time.sleep(3)
def _go_download_page(self):
windows = self.driver.window_handles
target_url = "https://www.hlsloader.com/cn/record.html" # 替换为你想要匹配的URL
for window in windows:
self.driver.switch_to.window(window)
current_url = self.driver.current_url
if target_url in current_url: # 或者使用 current_url == target_url 完全匹配
break # 找到目标窗口,跳出循环
def _get_current_window(self):
# 切换到最新打开的窗口(最后一个)
windows = self.driver.window_handles
self.driver.switch_to.window(windows[-1])
print(self.driver.title) # 打印当前页面的标题
def _download(self):
self._go_download_page()
max_wait = 600 # 最大等待时间(秒)
poll_frequency = 1 # 每秒检测一次
start_time = time.time()
while True:
try:
element = self.driver.find_element(By.XPATH,
"/html/body/div[1]/div/div[1]/div[3]/section/div[4]/div/div[1]/div/div[2]/div[4]/div/div/button[1]")
is_displayed = element.is_displayed()
is_enabled = element.is_enabled()
# 判断元素是否可见、可用,并且用 JS 检测是否被遮挡
clickable = False
if is_displayed and is_enabled:
clickable = self.driver.execute_script(
"var elem = arguments[0];"
"var rect = elem.getBoundingClientRect();"
"return (rect.width > 0 && rect.height > 0 && window.getComputedStyle(elem).visibility !== 'hidden');",
element)
print(f"检测状态 -> 显示: {is_displayed}, 可用: {is_enabled}, 可点击: {clickable}")
if clickable:
element.click()
print("元素已点击!")
file_name = self.driver.find_element(By.XPATH, "/html/body/div[1]/div/div[1]/div[3]/section/div[4]/div/div[1]/div/div[2]/div[1]/div[1]/a/span").text
return file_name
except Exception as e:
print(f"检测元素异常: {e}")
if time.time() - start_time > max_wait:
print("无法下载,等待超时。")
break
time.sleep(poll_frequency)
def download_video(self) -> str:
"""
下载视频
:return:
"""
# 点击链接
a_xpath = "/html/body/div[3]/div/div/div/div/div/div[6]/div[1]/div/div[5]/div[2]/ul/li[1]/a"
self.driver.find_element(by=By.XPATH, value=a_xpath).click()
time.sleep(3)
# 可选:验证是否切换成功
print("当前窗口标题:", self.driver.title)
self.driver.maximize_window() # 窗口最大化(保留系统任务栏)
time.sleep(1)
pyautogui.click(100, 100)
time.sleep(0.5)
# 再发送快捷键
pyautogui.hotkey('ctrl', 'm')
time.sleep(3)
return self._download()
class ChromeDyUploadDirver(ChromeDriver):
def __init__(self,file_name:str):
option = Options()
option.debugger_address = "localhost:13889"
super().__init__(option=option)
self.file_name = file_name
# self.driver.get("https://tv.cctv.com/lm/xwlb/")
time.sleep(2)
def _upload_img(self):
inputs = self.driver.find_elements(By.XPATH, '//input[@type="file"]')
for i, inp in enumerate(inputs):
print(f"Input {i}: {inp.get_attribute('outerHTML')}")
image_input = inputs[1]
self.driver.execute_script("arguments[0].style.display = 'block';", image_input)
# 上传图片(必须是绝对路径,支持多选)
upload_file = os.path.join(imgs_dir, f"{self.file_name}.png")
image_input.send_keys(os.path.join(imgs_dir, f"{self.file_name}.png"))
#
# 可选:上传多个图片(分号隔开,Windows 支持)
# file_paths = [
# r"C:\Users\wjn_0\Desktop\shortkey.png",
# r"C:\Users\wjn_0\Desktop\bg.png"
# ]
# image_input.send_keys('\n'.join(file_paths))
def _input_title(self):
x = "/html/body/div[1]/div[1]/div/div[2]/div/div/div/div[2]/div/div/div/div/div[1]/div/div[1]/div[2]/div[1]/div[1]/div[2]/div/div/div/div/div[1]/div/div/input"
title = self.file_name.split()[1]
self.driver.find_element(By.XPATH,x).send_keys(title)
print(f"添加标题 {title}")
def upload(self):
"""
抖音上传照片, 需要定位到https://creator.douyin.com/creator-micro/content/upload 页面
:return:
"""
print("开始发布")
# self._upload_img()
self._input_title()
if __name__ == '__main__':
file_name = "《新闻联播》 20250729 19:00"
file_name = file_name.replace(":", "_")
# driver = ChromePrtScDriver()
# driver.get("file:///C:/Users/shingi/Desktop/cs.html", "cs")
# driver = ChromeDownLoadDriver()
# driver.download_video()
cs = ChromeDyUploadDirver(file_name)
cs.upload()