如何用Selenium/BeautifulSoup为Collatinus生成层级化表格标题
解决方案
核心思路
针对你的三个问题,核心是遍历每个表格,回溯查找其前置的所有相关标题元素,处理层级拼接,再通过计数实现多表格编号。以下是具体实现步骤和代码:
步骤1:定义标题元素的筛选规则
首先,明确需要抓取的标题标签(h4、p、a),并通过文本或类名过滤掉非标题的元素(比如Collatinus中标题通常包含语法术语,如"actif"、"subjonctif",或带有特定class)。
步骤2:遍历表格,回溯获取前置标题
对每个表格,使用XPath的preceding轴获取其之前所有符合条件的标题元素,然后按DOM中的出现顺序(父级在前,子级在后)拼接成完整标题。
步骤3:处理多表格编号
用字典记录每个完整标题的出现次数,每次遇到重复标题时递增编号,生成带序号的标题。
完整代码示例
from selenium import webdriver from selenium.webdriver.common.by import By from collections import defaultdict # 初始化浏览器和工具页面 driver = webdriver.Chrome() # 替换为Collatinus在线工具的URL driver.get("工具页面URL") # 输入单词并触发分析(假设你已经完成这部分) input_box = driver.find_element(By.ID, "formMot") input_box.send_keys("amo") driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click() # 记录每个标题的出现次数 title_counts = defaultdict(int) # 获取所有结果表格 tables = driver.find_elements(By.TAG_NAME, "table") for table in tables: # 查找表格之前的所有标题元素(h4、p、a,且文本是语法术语) # 这里可根据实际页面结构调整筛选条件,比如添加class判断 preceding_titles = table.find_elements(By.XPATH, "./preceding::*[self::h4 or self::p or self::a][normalize-space(text()) != '' and contains(text(), 'actif') or contains(text(), 'passif') or contains(text(), 'indicatif') or contains(text(), 'subjonctif') or contains(text(), 'infinitif')]" ) # 提取标题文本,按DOM顺序(父级在前)拼接 # 只保留最近的层级(避免抓取过远的无关标题),比如取最后2个或根据内容判断 # 这里取最近的2个标题元素,适配层级 title_parts = [] for elem in reversed(preceding_titles[-2:]): # 取最近的2个标题元素,适配层级 text = elem.text.strip() if text not in title_parts: title_parts.insert(0, text) full_title = " ".join(title_parts) # 处理多表格编号 title_counts[full_title] += 1 if title_counts[full_title] > 1: final_title = f"{full_title} #{title_counts[full_title]}" else: final_title = full_title # 输出结果(这里可替换为你存储表格数据的逻辑) print(f"表格标题: {final_title}") # 提取表格内容的逻辑... driver.quit()
关键细节说明
- 标题标签不统一:通过XPath的
self::h4 or self::p or self::a覆盖所有可能的标签,再通过文本内容过滤掉非标题元素,确保只抓取语法相关的标题。 - 层级关系处理:通过取表格最近的N个前置标题(示例中取2个),按DOM出现顺序拼接,自动实现父级+子级的格式(比如"actif subjonctif")。如果层级更多,可调整
[-2:]的数值,或根据标题文本的语法逻辑动态判断(比如判断是否是语态/时态等类别)。 - 多表格编号:使用
defaultdict计数,每次遇到相同的完整标题时递增序号,自动生成带编号的标题。
优化建议
- 如果页面中标题有特定class(比如
titre-grammaire),可在XPath中添加contains(@class, 'titre-grammaire'),提升筛选准确性。 - 若层级关系复杂,可通过标题元素的CSS样式(如字体大小)判断层级优先级,比如h4是一级标题,p是二级,a是三级,再按优先级拼接。
内容的提问来源于stack exchange,提问作者Mufarrid Ansari
相关产品推荐
相关产品推荐

