基于Selenium的网页爬取前元素修改与激活问题
解决方案:修改页面后爬取Marvel Snap卡组数据
问题分析
你的核心问题是没有在正确的时机用Selenium操作页面DOM,而是错误地先用BeautifulSoup解析了静态HTML,导致后续的JS操作无法作用到实际页面上。必须直接通过Selenium操作浏览器中的页面元素,完成添加标签、搜索、排序后,再获取更新后的页面源码进行解析。
完整修改后的代码
import re import os from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup def scrap(): url = 'https://marvelsnapzone.com/decks' chrome_options = Options() chrome_options.headless = True chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument('--disable-extensions') chrome_options.add_argument('--disable-gpu') # 无头模式下添加窗口大小参数,避免元素定位失败 chrome_options.add_argument('--window-size=1920,1080') browser = webdriver.Chrome(options=chrome_options) browser.get(url) wait = WebDriverWait(browser, 10) # 显式等待,确保元素加载完成 # 1. 添加指定卡片标签(以Angela为例) tags_container = wait.until(EC.presence_of_element_located((By.ID, 'tags'))) # 执行JS在DOM中创建并插入新标签 browser.execute_script(""" const tag = document.createElement('div'); tag.id = 'tagsblock'; tag.className = 'tag card'; tag.textContent = 'Angela'; arguments[0].appendChild(tag); """, tags_container) # 2. 执行搜索操作(触发id为searchdecks的按钮) search_button = wait.until(EC.element_to_be_clickable((By.ID, 'searchdecks'))) search_button.click() # 等待表格更新,确保搜索结果加载完成 wait.until(EC.staleness_of(browser.find_element(By.CSS_SELECTOR, '.deck-table-row'))) # 3. 按点赞数升序排序 likes_sort_element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'span[data-sorttype="likes"]'))) # 模拟点击切换排序状态(仅修改class不会触发页面排序逻辑) likes_sort_element.click() # 若点击一次为降序,再次切换为升序 if 'asc' not in likes_sort_element.get_attribute('class'): likes_sort_element.click() # 等待排序完成,确认升序状态生效 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'span[data-sorttype="likes"].asc'))) # 获取更新后的页面源码进行解析 html = browser.page_source soup = BeautifulSoup(html, 'html.parser') # 后续爬取操作 links = soup.findAll('a', {'class': 'card cardtooltip maindeckcard tooltiploaded'}) # ... 你的其他爬取代码 ... browser.quit() # 关闭浏览器 if __name__ == '__main__': characters = scrap()
关键修改点说明
- 移除提前解析HTML的步骤:必须先完成所有页面操作,再调用
browser.page_source获取最新的DOM内容。 - 使用显式等待:通过
WebDriverWait确保元素加载完成后再操作,避免因页面未加载完全导致的定位失败。 - 正确添加标签元素:通过Selenium执行JS直接在浏览器的DOM中创建并插入标签,而非操作BeautifulSoup的静态对象。
- 模拟点击触发排序:仅修改元素的
class属性不会触发页面的排序逻辑,必须模拟点击排序按钮,让页面执行内置的排序JS代码。 - 等待页面更新:每次操作(搜索、排序)后,等待表格元素更新,确保后续爬取的是最新数据。
内容的提问来源于stack exchange,提问作者TomDekkard
相关产品推荐
相关产品推荐

