selenium用try-except嵌套处理抓取异常(新闻抓取案例三)

本文通过一个新闻抓取案例,介绍如何利用Python Selenium的try-except嵌套处理NoSuchElementException异常。当目标网页的某些段落不存在时,程序能够智能地根据存在的元素进行抓取,避免程序崩溃。通过尝试定位并抓取前三段内容,如果第三段不存在,则只抓取前两段。对于更复杂的场景,如需抓取更多段落,作者提出try-except嵌套可能变得冗长,并期待找到更简洁的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天练习的是新闻内容局部抓取,不需要打印全文,只需要打印前面两三段,所以可以直接定位到前三段的p标签

content1=driver.find_element_by_xpath("//*[@id='newsmain-ej']/div/div[1]/div[1]/div[4]/div/p[1]").text
content2=driver.find_element_by_xpath("//*[@id='newsmain-ej']/div/div[1]/div[1]/div[4]/div/p[2]").text
content3=driver.find_element_by_xpath("//*[@id='newsmain-ej']/div/div[1]/div[1]/div[4]/div/p[3]").text

但是实际抓取的时候有一篇文章报错了,因为它很短,没有第三段——selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element:

于是想到能不能用try-except来处理异常,判断有没有第三段。查了一下确实有这个异常NoSuchElementException,要用到这个NoSuchElementException异常,要在开头导入from selenium.common.exceptions import NoSuchElementException。

如果没有第三段,也就是说p[3]不存在,那就只打印第一和第二段,如果没有异常,则打印前三段:


                
<think>好的,我现在需要帮助用户理解如何在Python Selenium中实现循环和递归。首先,用户提到的是“循环递归”,可能是指循环和递归两种不同的结构,或者他们想结合使用两者。我得先理清楚这两个概念在Selenium中的应用场景。 首先,循环在Selenium中很常见,比如遍历多个页面元素,例如表格中的每一行,或者分页导航中的每一页。用户可能需要知道如何用循环结构来处理重复的任务,比如点击每个链接或提取多个数据项。这时候,我应该考虑举例说明,比如使用for循环遍历find_elements返回的列表,然后对每个元素执行操作。 然后是递归。递归在Selenium中的应用可能不太常见,但用户可能有特定的需求,比如处理嵌套的DOM结构,或者不断深入子页面直到满足某个条件。例如,爬取多层级的菜单,或者不断点击“下一页”直到没有更多内容。这时候需要递归函数,但要注意终止条件,避免无限递归和栈溢出。不过,递归在深度较大时可能不如循环高效,所以也要提醒用户根据情况选择。 接下来,我需要考虑用户可能的实际场景。比如,用户可能想爬取一个分页的网页,这时候循环更适合,每次循环处理一页,直到最后一页。而递归可能用在处理类似树形结构的导航菜单,每个菜单项可能有子菜单,这时候递归函数可以展开每个节点。 同时,要提醒用户注意Selenium中的常见问题,比如元素定位的时效性(StaleElementReferenceException),特别是在循环或递归过程中,页面元素可能发生变化,导致之前找到的元素失效。解决办法是在每次循环内部重新定位元素,或者使用显式等待确保元素可用。 另外,循环和递归都可能遇到性能问题,特别是网页加载时间较长时,需要合理设置等待时间,可能使用WebDriverWait配合expected_conditions,确保元素加载完成再进行操作。 还需要考虑代码的结构,比如在递归中,每次调用自身时需要传递必要的参数,比如当前的页面元素或深度限制。而在循环中,可能需要维护一个队列或栈结构,特别是处理广度优先或深度优先遍历时。 可能的代码示例方面,循环的例子可以是用while循环点击“下一页”按钮,直到按钮消失。递归的例子可以是遍历一个嵌套的ul列表,每个li元素可能有子ul,递归处理每个层级。 最后,要总结两者的适用场景,循环适合已知或可预测次数的情况,递归适合问题可分解为相同结构的子问题的情况,但要注意终止条件和性能影响。同时,给出注意事项,比如异常处理和等待机制的重要性。</think>在Python Selenium中实现循环和递归操作,通常用于处理网页元素的遍历、分页抓取嵌套结构解析。以下是分步说明和示例: --- ### **一、循环的应用场景** 适用于已知重复次数或可预测终止条件的场景,如遍历列表、分页操作等。 #### **1. 基础循环示例:遍历元素列表** ```python from selenium import webdriver driver = webdriver.Chrome() driver.get("https://example.com/table") # 定位表格中的所有行 rows = driver.find_elements("xpath", "//table//tr") # 使用for循环遍历每一行 for row in rows: cells = row.find_elements("tag name", "td") for cell in cells: print(cell.text) driver.quit() ``` #### **2. 分页抓取(while循环)** ```python while True: # 抓取当前页内容 items = driver.find_elements("class name", "item") for item in items: print(item.text) # 尝试点击下一页按钮 try: next_button = driver.find_element("xpath", "//a[text()='下一页']") next_button.click() except NoSuchElementException: break # 无下一页时退出循环 ``` --- ### **二、递归的应用场景** 适用于嵌套结构解析(如树形菜单)或不确定深度的层级遍历。 #### **1. 递归遍历嵌套菜单** ```python def parse_menu(element, depth=0): # 展开当前菜单项(假设有展开按钮) element.click() # 定位子菜单项 sub_items = element.find_elements("xpath", "./following-sibling::ul/li") # 递归处理子菜单 for sub_item in sub_items: print(" " * depth + sub_item.text) parse_menu(sub_item, depth + 1) # 递归调用 # 初始化:从顶级菜单开始 top_menu = driver.find_element("id", "main_menu") parse_menu(top_menu) ``` #### **2. 递归终止条件** 必须明确终止条件,例如: - 当元素没有子节点时停止递归 - 设置最大递归深度(防止栈溢出) --- ### **、注意事项** 1. **元素过期问题** 在循环/递归中,若页面DOM更新(如点击后加载新内容),需重新查找元素,避免`StaleElementReferenceException`。 2. **性能优化** - 循环:优先使用显式等待(`WebDriverWait`)确保元素加载完成。 - 递归:限制递归深度(如`if depth > 5: return`)。 3. **替代方案** 对于深度嵌套结构,可用循环+栈(Stack)模拟递归,避免栈溢出: ```python stack = [root_element] while stack: element = stack.pop() # 处理当前元素 children = element.find_elements("xpath", "./child") stack.extend(children) ``` --- ### **四、总结** - **循环**:适合分页、列表遍历等线性操作。 - **递归**:适合树形菜单、嵌套JSON等层级结构。 - **混合使用**:例如用循环处理分页,递归处理每页内的嵌套内容。 根据实际需求选择合适方法,并结合异常处理(`try-except`)和显式等待提升稳定性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值