
本文讲解如何使用 selenium 替代 requests + beautifulsoup,稳定抓取依赖 javascript 渲染的动态表格,并将“偶数行作标题、奇数行作内容”的交替结构自动转换为字典格式的结构化数据。
本文讲解如何使用 selenium 替代 requests + beautifulsoup,稳定抓取依赖 javascript 渲染的动态表格,并将“偶数行作标题、奇数行作内容”的交替结构自动转换为字典格式的结构化数据。
在网页爬虫实践中,许多现代网站(如 modernarmor.worldoftanks.com)采用 JavaScript 动态加载表格内容,导致 requests + BeautifulSoup 无法获取真实 DOM —— 这正是原代码始终无法正确提取表头与数据的根本原因。此时,Selenium 成为更可靠的选择:它通过真实浏览器驱动执行渲染,确保所有 <tr> 元素(包括 JS 注入的)均被完整加载。<p>以下是一个完整、健壮的解决方案:</p>
<h3>✅ 核心逻辑说明</h3>
<ul>
<li>表格结构为严格交替:第 0、2、4… 行是分类标题(如 <code>"World War II: Battle Tiers 1-2"),第 1、3、5… 行是该分类下的地图名称列表(换行分隔);
WebDriverWait 确保元素加载完成,避免 NoSuchElementException;dict[str, list[str]],天然支持后续导出 CSV、JSON 或 Pandas DataFrame。✅ 完整可运行代码
from selenium.webdriver import Chrome
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import json
URL = "https://modernarmor.worldoftanks.com/en/cms/guides/map-labels-tiers-eras/"
def reject_cookies(driver):
"""点击 'Reject All' 按钮关闭 Cookie 提示(若存在)"""
wait = WebDriverWait(driver, 3)
try:
button = wait.until(EC.element_to_be_clickable((By.ID, "onetrust-reject-all-handler")))
button.click()
except: # 超时或元素不存在则跳过
pass
def scrape_map_labels(driver):
"""主解析函数:按行交替提取标题与地图列表"""
wait = WebDriverWait(driver, 5)
# 精确匹配表格行(基于实际页面 class)
rows = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "tr.news_post-widget-table-tr")))
result = {}
header = None
for i, row in enumerate(rows):
text = row.text.strip()
if not text: # 跳过空行
continue
if i % 2 == 0: # 偶数索引 → 标题行
header = text
else: # 奇数索引 → 数据行 → 按换行符切分为地图名列表
if header and text:
result[header] = [item.strip() for item in text.split("\n") if item.strip()]
return result
# 启动浏览器并执行
with Chrome() as driver:
driver.get(URL)
reject_cookies(driver)
data = scrape_map_labels(driver)
# 输出结构化结果(便于调试与后续处理)
print(json.dumps(data, indent=2, ensure_ascii=False))
⚠️ 注意事项与优化建议
-
驱动准备:需提前安装匹配版本的 ChromeDriver,或使用
webdriver-manager自动管理(推荐):pip install webdriver-manager
并替换
with Chrome()为:from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager with Chrome(service=Service(ChromeDriverManager().install())) as driver:
-
反爬适配:若页面增加检测,可添加
options.add_argument("--headless=new")静默运行,或设置User-Agent; -
数据清洗增强:对
result[header]中每个地图名,可追加.replace(" [MERGE]", "")或正则清理(如re.sub(r'[^\w\s]', '', name)); -
扩展用途:该字典可直接转为 Pandas DataFrame:
import pandas as pd df = pd.DataFrame([(k, v) for k, vs in data.items() for v in vs], columns=["Era_Tier", "Map"])
该方案摒弃了脆弱的字符串计数(如 stringCount == 2)和正则预处理,转而依托 DOM 结构本身进行语义化解析,显著提升可维护性与准确性。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











