Selenium Python:多层shadow-root搜索框输入及archive.org操作失效解决方案
问题1:Python + Selenium 操作多层shadow-root(open)搜索框输入文本
shadow-root(open)允许通过JavaScript的shadowRoot属性访问内部DOM,核心思路是从外层元素开始,依次穿透每一层shadow-root,最终定位到目标搜索框,再执行输入操作。
实现方法
- 定位包含第一层shadow-root的宿主元素
- 通过JS获取该元素的
shadowRoot,进而定位下一层宿主元素 - 重复步骤1-2,穿透所有嵌套层级
- 找到目标输入框后,用
send_keys()或JS注入完成输入
代码示例
假设页面结构为outer-host > #shadow-root > middle-host > #shadow-root > input#search-box:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() driver.get("目标页面URL") # 封装穿透shadow-root的函数 def get_shadow_element(parent, selector): return parent.execute_script('return arguments[0].shadowRoot.querySelector(arguments[1])', parent, selector) # 第一层宿主元素 outer_host = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "outer-host"))) # 穿透第一层shadow-root,找到中间宿主 middle_host = get_shadow_element(outer_host, "middle-host") # 穿透第二层shadow-root,找到搜索框 search_box = get_shadow_element(middle_host, "input#search-box") # 输入文本 search_box.send_keys("要输入的内容")
也可以用一行JS直接完成多层穿透:
search_box = driver.execute_script(""" return document.querySelector('outer-host') .shadowRoot.querySelector('middle-host') .shadowRoot.querySelector('input#search-box'); """) search_box.send_keys("要输入的内容")
问题2:archive.org 无法用Selenium/undetected_chromedriver/Playwright操作的解决方案
archive.org的反爬机制会识别自动化工具的指纹特征,即使使用undetected_chromedriver也可能因配置不足暴露痕迹,以下是针对性解决措施:
1. 优化undetected_chromedriver配置
你的现有代码存在配置冗余,且缺少关键反检测参数,调整后代码如下:
import undetected_chromedriver as uc from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By keyword = "photo" url_photo = f"https://archive.org/search?query={keyword}&and%5B%5D=mediatype%3A%22image%22" # 合并必要配置参数 options = uc.ChromeOptions() options.add_argument("--start-maximized") options.add_argument("--disable-infobars") options.add_argument("--disable-extensions") options.add_argument("--disable-blink-features=AutomationControlled") # 隐藏自动化标识 options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") # 模拟真实浏览器UA(根据本地Chrome版本调整) options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") # 自动匹配Chrome版本启动,无需手动指定driver路径 driver = uc.Chrome(options=options) driver.get(url_photo) # 用稳定的CSS选择器替代绝对XPATH try: first_tile = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.CSS_SELECTOR, "item-tile:nth-of-type(1) img")) ) first_tile.click() print("request successful") except Exception as e: print(f"Error: {str(e)}") driver.save_screenshot("error.png") # 保存截图排查问题 driver.quit()
2. 关键优化说明
- 移除冗余配置:直接使用
uc.ChromeOptions(),避免重复初始化 - 禁用自动化特征:
--disable-blink-features=AutomationControlled会隐藏navigator.webdriver等检测标识 - 替换绝对XPATH:绝对路径极易因页面结构变化失效,改用CSS选择器更可靠
- 版本自动匹配:undetected_chromedriver会自动适配本地Chrome版本,无需手动指定驱动路径
- 模拟真实行为:操作前可加入
time.sleep(2)或滚动页面,贴近真实用户操作
3. Playwright优化方案
如果Playwright也失效,启用stealth插件并模拟真实环境:
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=False) context = browser.new_context( user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", viewport={"width": 1920, "height": 1080} ) # 启用stealth插件(需先安装playwright-stealth) from playwright_stealth import stealth_sync page = context.new_page() stealth_sync(page) page.goto("https://archive.org/search?query=photo&and%5B%5D=mediatype%3A%22image%22") page.wait_for_selector("item-tile:nth-of-type(1) img").click() print("request successful") browser.close()
4. 其他排查方向
- IP封禁:多次失败后尝试更换代理IP
- Cookie导入:手动登录archive.org后,将Cookie导入自动化工具
- 页面加载验证:等待
document.readyState === "complete"确保页面完全加载
内容的提问来源于stack exchange,提问作者xtrabyte
相关产品推荐
相关产品推荐

