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]不存在,那就只打印第一和第二段,如果没有异常,则打印前三段:

try:
    content3=driver.find_element_by_xpath("//*[@id='newsmain-ej']/div/div[1]/div[1]/div[4]/div/p[3]").text
except NoSuchElementException:   #如果没有第三段
<think>首先,用户的问题是关于使用Python编写脚本从HTTP地址获取网页内容,提取API接口,并测试RESTful API。我需要根据系统级指令来构建我的回答。 系统级指令关键点: - 所有行内数学表达式必须使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考站内引用(提供了一些库和概念)。 用户意图:通过Python编写程序,从指定的HTTP地址访问网页并抓取API接口进行测试。 我的回答需要覆盖以下步骤: 1. 访问HTTP地址获取网页内容。 2. 提取API接口(可能从HTML中解析)。 3. 测试RESTful API(使用提取的API进行请求)。 参考提供的引用: - 引用[1]:提到了网页内容提取库,如requests, BeautifulSoup, lxml, newspaper等。 - 引用[2]:关于HTTP请求方法(GET, POST等)。 - 引用[3]:GET请求的形式。 - 引用[4]:网页可读内容抽取API。 我会使用这些引用来支持我的回答。 回答结构: 1. **介绍**:简要解释整个过程。 2. **步骤分解**: a. 使用Python库(如requests)获取网页内容。 b. 解析HTML内容以提取API接口(使用BeautifulSoup或类似库)。 c. 测试提取的API(使用requests库发送HTTP请求)。 3. **代码示例**:提供Python代码片段。 4. **生成相关问题**:在最后添加相关问题。 确保使用中文回答。 关于数学表达式:用户的问题不涉及数学,所以我可能不需要使用数学表达式,除非在解释概念时涉及。但指令说所有行内数学表达式必须用$...$,所以我应该避免不必要的数学内容。如果需要,比如在解释API测试时涉及参数,可以适当使用。 引用标识:在回答中引用段落末尾添加引用标识,如[^1]。例如,提到库时引用引用[1]。 现在,规划回答内容: - **步骤1: 获取网页内容** - 使用requests库发送GET请求获取网页。 - 引用引用[1]和[2]。 - **步骤2: 提取API接口** - 解析HTML,可能使用BeautifulSoup。 - API接口可能隐藏在链接、JavaScript或特定标签中。需要根据网页结构提取。 - 引用引用[1]中的库如newspaper或textract,但更适用于内容提取;对于API提取,可能需要更通用的方法。 - **步骤3: 测试RESTful API** - 使用requests库发送GET、POST等请求到提取的API。 - 检查响应状态码、内容等。 - 引用引用[2]关于HTTP方法。 代码示例: - 一个简单的脚本演示整个过程。 相关问题: - 基于主题生成3-5个相关问题。 最终输出格式: - 回答部分。 - 代码块(使用```python)。 - §§相关问题§§列表。</think>### 使用Python访问HTTP地址、提取API接口并测试RESTful API 您的需求是通过Python脚本从指定HTTP地址获取网页内容,从中提取API接口(如RESTful端点),并进行测试。这个过程涉及个核心步骤:(1) 使用HTTP库访问网页并获取内容;(2) 解析HTML以提取API接口;(3) 发送测试请求验证API功能。下面我将逐步解释每个步骤,并提供完整代码示例。整个过程基于Python标准库和流行第方库(如requests和BeautifulSoup),这些库在网页抓取和API测试中广泛应用[^1][^2]。 #### 步骤1: 访问HTTP地址获取网页内容 首先,使用Python的`requests`库发送HTTP GET请求到目标URL,获取网页HTML内容。GET请求将参数附加在URL后,以`?key=value&...`格式传输数据[^3]。确保处理网络异常(如超时或404错误),并检查响应状态码(如200表示成功)。以下是关键代码部分: ```python import requests # 目标HTTP地址(示例URL) url = "https://example.com/api-docs" # 替换为您的实际URL try: # 发送GET请求,设置超时防止卡死 response = requests.get(url, timeout=10) response.raise_for_status() # 检查HTTP错误(如404) # 获取网页内容(HTML格式) html_content = response.text print(f"成功获取网页内容,长度: {len(html_content)} 字节") except requests.exceptions.RequestException as e: print(f"请求失败: {e}") html_content = None if html_content: # 后续步骤在此添加... ``` **关键点**: - `requests`库简化了HTTP请求处理,支持GET、POST等方法(引用RESTful接口常用方法如GET和POST[^2])。 - 超时设置(`timeout=10`)避免脚本因网络问题无限等待。 - 状态码检查确保响应有效(例如,200 OK表示成功)。 #### 步骤2: 提取API接口 获取HTML内容后,使用`BeautifulSoup`库解析HTML并提取API接口。API接口通常隐藏在特定标签中,如`<a>`(链接)、`<script>`(JavaScript变量)或`<div>`(文档描述)。您需要根据网页结构定位元素,例如查找包含"api"或"endpoint"关键词的链接。以下是解析代码: ```python from bs4 import BeautifulSoup if html_content: # 解析HTML内容 soup = BeautifulSoup(html_content, 'html.parser') # 提取API接口:假设接口在<a>标签的href属性中 api_endpoints = [] for link in soup.find_all('a', href=True): href = link['href'] if 'api' in href or 'endpoint' in href: # 根据实际关键词调整 api_endpoints.append(href) # 如果未找到,尝试从JavaScript或JSON中提取(更复杂,需正则表达式) if not api_endpoints: # 示例:搜索JSON格式的API定义 import re json_pattern = re.compile(r'\"url\":\s*\"(https?://[^\"]+)\"') matches = json_pattern.findall(html_content) api_endpoints = list(set(matches)) # 去重 print(f"提取到的API接口: {api_endpoints}") else: api_endpoints = [] ``` **关键点**: - `BeautifulSoup`是HTML解析的黄金标准,能处理嵌套标签和属性[^1]。 - 如果网页动态加载API(如通过JavaScript),可能需要结合`Selenium`库,但静态解析在大多数文档页有效。 - 提取策略需定制:例如,API文档页常将接口放在`/api/v1/...`路径中(引用通用数据提取方法[^4])。 #### 步骤3: 测试RESTful API 提取API接口后,使用`requests`发送测试请求(如GET或POST)。验证响应状态码(200-299表示成功)、响应内容(如JSON数据)和性能。以下是测试代码示例: ```python if api_endpoints: # 选择一个API端点测试(示例用第一个) test_url = api_endpoints[0] print(f"测试API: {test_url}") try: # 发送GET请求(可改为POST、PUT等[^2]) api_response = requests.get(test_url, timeout=10) api_response.raise_for_status() # 检查响应 print(f"状态码: {api_response.status_code}") if api_response.headers['Content-Type'] == 'application/json': data = api_response.json() print(f"API响应数据: {data}") else: print(f"响应内容: {api_response.text[:200]}...") # 截断长文本 except requests.exceptions.RequestException as e: print(f"API测试失败: {e}") else: print("未提取到API接口,请检查网页结构") ``` **关键点**: - 测试方法包括GET(获取数据)、POST(创建资源)等(引用HTTP/1.1定义的请求方法[^2])。 - 响应处理:JSON数据用`.json()`解析,文本数据直接查看。 - 扩展性:添加参数(如`params={'key':'value'}`)或头部(如`headers={'Authorization':'Bearer token'}`)模拟真实场景。 #### 完整脚本示例 将上述步骤整合为一个Python脚本: ```python import requests from bs4 import BeautifulSoup import re def fetch_and_test_api(url): # Step 1: 获取网页内容 try: response = requests.get(url, timeout=10) response.raise_for_status() html_content = response.text print(f"网页获取成功") except requests.exceptions.RequestException as e: print(f"请求错误: {e}") return # Step 2: 提取API接口 soup = BeautifulSoup(html_content, 'html.parser') api_endpoints = [] for link in soup.find_all('a', href=True): href = link['href'] if href.startswith(('http://', 'https://')) and ('api' in href or 'endpoint' in href): api_endpoints.append(href) if not api_endpoints: json_pattern = re.compile(r'\"(?:url|endpoint)\":\s*\"(https?://[^\"]+)\"') api_endpoints = list(set(json_pattern.findall(html_content))) if not api_endpoints: print("未找到API接口") return print(f"提取到 {len(api_endpoints)} 个API接口") # Step 3: 测试API(示例测试第一个) test_url = api_endpoints[0] try: api_response = requests.get(test_url, timeout=10) api_response.raise_for_status() print(f"测试成功! 状态码: {api_response.status_code}") # 输出部分响应内容 print(f"响应预览: {api_response.text[:100]}...") except Exception as e: print(f"API测试失败: {e}") # 运行脚本(替换为您的目标URL) if __name__ == "__main__": target_url = "https://example.com/api-docs" # 修改此行 fetch_and_test_api(target_url) ``` **使用说明**: 1. 安装依赖库:运行`pip install requests beautifulsoup4`。 2. 将`target_url`替换为您的实际HTTP地址(如API文档页)。 3. 执行脚本:`python script.py`。 4. 输出包括提取的API列表和测试结果。 **注意事项**: - **合法性**:仅测试您有权访问的API,避免违反网站条款(如robots.txt)。 - **错误处理**:脚本包含基本异常捕获,但实际中可添加重试逻辑或日志记录。 - **性能优化**:对于大规模抓取,使用异步库(如`aiohttp`)提升效率。 - 如果API需要认证,添加头部参数(如`headers={'Authorization': 'Bearer YOUR_TOKEN'}`)[^2]。 此方法适用于大多数静态网页。如果网页内容动态生成(如React应用),需结合`Selenium`或直接分析网络请求(使用浏览器开发者工具)。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值