攸县网站开发网站浮动窗口怎么做的
攸县网站开发,网站浮动窗口怎么做的,怎样制作软件程序,lol做直播网站LightOnOCR-2-1B实战教程#xff1a;Python调用API实现批量PDF截图文字提取
1. 引言
你有没有遇到过这样的烦恼#xff1f;手头有一堆PDF文件#xff0c;里面全是扫描的图片或者截图#xff0c;想提取里面的文字#xff0c;要么得手动一个字一个字敲#xff0c;要么用传…LightOnOCR-2-1B实战教程Python调用API实现批量PDF截图文字提取1. 引言你有没有遇到过这样的烦恼手头有一堆PDF文件里面全是扫描的图片或者截图想提取里面的文字要么得手动一个字一个字敲要么用传统的OCR工具识别率不高还经常乱码。特别是当文档里混合了中文、英文甚至还有其他语言时很多工具直接就罢工了。今天要介绍的这个工具能帮你彻底解决这个问题。LightOnOCR-2-1B一个专门为多语言OCR设计的模型支持包括中文、英文、日文、法文等在内的11种语言。更重要的是它提供了简单易用的API接口让你能用Python脚本批量处理PDF截图自动提取文字效率提升不止十倍。这篇文章我会手把手带你从零开始学会怎么用Python调用LightOnOCR-2-1B的API搭建一个属于自己的批量文字提取工具。无论你是数据分析师、研究人员还是需要处理大量文档的办公人员这套方法都能让你事半功倍。2. 准备工作与环境搭建在开始写代码之前我们需要先把环境准备好。LightOnOCR-2-1B已经提供了预置的镜像服务这让我们的部署变得非常简单。2.1 服务访问信息当你通过镜像部署好LightOnOCR-2-1B之后会得到两个重要的访问地址Web操作界面http://你的服务器IP:7860这是一个图形化的操作页面你可以直接上传图片点击按钮就能看到识别结果。适合偶尔用用或者测试模型效果。后端API接口http://你的服务器IP:8000/v1/chat/completions这才是我们今天的主角。通过这个API我们可以用程序自动发送请求、获取结果实现批量处理。2.2 检查服务状态在开始写代码之前先确认服务已经正常启动。登录到你的服务器执行下面这个命令ss -tlnp | grep -E 7860|8000如果看到类似下面的输出说明服务运行正常LISTEN 0 128 *:8000 *:* users:((python,pid1234,fd3)) LISTEN 0 128 *:7860 *:* users:((python,pid1235,fd3))2.3 Python环境准备在你的本地开发环境或者另一台服务器上确保安装了Python 3.7或更高版本。然后安装必要的Python库pip install requests pillow PyPDF2 pdf2image简单解释一下这几个库的作用requests用来发送HTTP请求调用APIpillowPython的图像处理库处理图片PyPDF2处理PDF文件pdf2image把PDF页面转换成图片3. 核心原理从PDF到文字的完整流程在开始写代码之前我们先理清楚整个处理流程。理解了这个流程后面的代码就很容易看懂了。3.1 处理流程四步走整个批量提取的过程可以分为四个步骤PDF转图片把PDF的每一页都转换成图片图片预处理调整图片大小、格式为OCR做准备调用OCR API把图片发送给LightOnOCR模型识别结果整理把识别出的文字按页面顺序保存3.2 为什么选择LightOnOCR-2-1B你可能会问OCR工具那么多为什么选这个我实际测试后发现几个明显的优势多语言支持强大传统的OCR工具往往对中文支持不好或者中英文混合时就识别不准。LightOnOCR-2-1B专门针对11种语言优化特别是中文和英文的混合文本识别准确率很高。表格和公式识别很多OCR工具遇到表格就乱套数字对不齐公式识别不了。这个模型对表格、收据、表单这类结构化文档的支持很好甚至能识别一些简单的数学公式。API调用方便提供了标准的HTTP API接口和我们熟悉的OpenAI API格式很像学习成本低集成简单。4. 基础操作单张图片文字提取我们先从最简单的开始学会怎么用Python提取单张图片的文字。掌握了这个批量处理就是加个循环的事儿。4.1 把图片转换成Base64编码OCR API需要把图片数据放在请求里发送最常用的方式就是把图片转换成Base64编码的字符串。Base64是一种把二进制数据比如图片转换成文本格式的方法这样就能直接在JSON数据里传输了。import base64 from PIL import Image import io def image_to_base64(image_path): 把图片文件转换成Base64编码的字符串 参数: image_path: 图片文件的路径 返回: Base64编码的字符串 with open(image_path, rb) as image_file: # 读取图片二进制数据 image_data image_file.read() # 转换成Base64 base64_str base64.b64encode(image_data).decode(utf-8) # 添加数据头告诉API这是PNG格式的图片 return fdata:image/png;base64,{base64_str}4.2 调用OCR API获取文字有了Base64编码的图片现在我们可以调用API了。LightOnOCR的API格式和OpenAI的很像用起来很顺手。import requests import json def extract_text_from_image(api_url, image_base64): 调用LightOnOCR API提取图片中的文字 参数: api_url: API地址比如 http://你的服务器IP:8000/v1/chat/completions image_base64: Base64编码的图片数据 返回: 识别出的文字 # 准备请求数据 payload { model: /root/ai-models/lightonai/LightOnOCR-2-1B, messages: [{ role: user, content: [{ type: image_url, image_url: { url: image_base64 } }] }], max_tokens: 4096 # 最多返回4096个字符 } # 设置请求头 headers { Content-Type: application/json } try: # 发送POST请求 response requests.post(api_url, headersheaders, datajson.dumps(payload)) response.raise_for_status() # 如果请求失败会抛出异常 # 解析返回结果 result response.json() extracted_text result[choices][0][message][content] return extracted_text except requests.exceptions.RequestException as e: print(fAPI请求失败: {e}) return None except (KeyError, IndexError) as e: print(f解析响应数据失败: {e}) return None4.3 完整示例提取单张图片文字把上面的两个函数组合起来就是一个完整的单张图片文字提取程序def single_image_ocr_demo(): 单张图片OCR演示 # 你的服务器IP地址 server_ip 你的服务器IP api_url fhttp://{server_ip}:8000/v1/chat/completions # 图片路径 image_path example.png print(f正在处理图片: {image_path}) # 第一步图片转Base64 print(转换图片为Base64编码...) image_base64 image_to_base64(image_path) # 第二步调用OCR API print(调用OCR API识别文字...) extracted_text extract_text_from_image(api_url, image_base64) if extracted_text: print(识别成功提取的文字内容) print(- * 50) print(extracted_text) print(- * 50) # 保存到文件 with open(extracted_text.txt, w, encodingutf-8) as f: f.write(extracted_text) print(文字已保存到 extracted_text.txt) else: print(识别失败)运行这个程序你就能看到图片里的文字被提取出来了。很简单对吧但这只是开始真正的威力在于批量处理。5. 实战进阶批量处理PDF截图现在进入正题怎么批量处理PDF文件。我会带你一步步构建一个完整的批量处理工具。5.1 把PDF转换成图片首先我们需要把PDF的每一页都转换成图片。这里用pdf2image库它底层调用的是poppler工具转换效果很好。from pdf2image import convert_from_path import os def pdf_to_images(pdf_path, output_foldertemp_images): 把PDF文件转换成多张图片每页一张 参数: pdf_path: PDF文件路径 output_folder: 临时保存图片的文件夹 返回: 图片文件路径的列表 # 创建临时文件夹 os.makedirs(output_folder, exist_okTrue) print(f正在转换PDF: {pdf_path}) # 转换PDF为图片 # dpi参数控制图片质量300是比较高的质量 images convert_from_path(pdf_path, dpi300) image_paths [] # 保存每一页为图片 for i, image in enumerate(images): # 生成图片文件名比如 page_001.png image_filename fpage_{i1:03d}.png image_path os.path.join(output_folder, image_filename) # 保存图片 image.save(image_path, PNG) image_paths.append(image_path) print(f 已保存第 {i1} 页: {image_filename}) print(f转换完成共 {len(image_paths)} 页) return image_paths5.2 批量OCR处理核心逻辑有了图片现在我们可以批量调用OCR API了。这里有几个关键点需要注意控制请求频率不要一下子发送太多请求可能会把服务器搞垮。我们加个简单的延迟。错误处理网络请求可能会失败图片可能有问题要做好错误处理避免一个失败就全盘停止。进度显示批量处理时间可能比较长显示进度让用户知道进行到哪了。import time def batch_process_pdf(pdf_path, api_url, output_text_fileoutput.txt): 批量处理PDF文件提取所有页面的文字 参数: pdf_path: PDF文件路径 api_url: OCR API地址 output_text_file: 输出文本文件路径 print( * 60) print(f开始处理PDF文件: {pdf_path}) print( * 60) # 第一步PDF转图片 print(\n1. 转换PDF为图片...) temp_folder temp_pdf_images image_paths pdf_to_images(pdf_path, temp_folder) if not image_paths: print(错误没有生成图片文件) return # 第二步逐页OCR识别 print(f\n2. 开始OCR识别共 {len(image_paths)} 页) all_texts [] # 保存所有页面的文字 for i, image_path in enumerate(image_paths): page_num i 1 print(f\n 处理第 {page_num}/{len(image_paths)} 页...) try: # 转换图片为Base64 image_base64 image_to_base64(image_path) # 调用OCR API print(f 调用API识别文字...) start_time time.time() text extract_text_from_image(api_url, image_base64) elapsed_time time.time() - start_time if text: # 添加页面标记 page_text f\n{*40}\n第 {page_num} 页\n{*40}\n\n{text}\n all_texts.append(page_text) print(f 识别成功用时 {elapsed_time:.2f} 秒识别 {len(text)} 字符) else: error_msg f\n{*40}\n第 {page_num} 页 [识别失败]\n{*40}\n\n本页识别失败请手动处理\n all_texts.append(error_msg) print(f 识别失败) # 每处理一页后稍微等待一下避免请求过于频繁 if i len(image_paths) - 1: # 不是最后一页 time.sleep(1) # 等待1秒 except Exception as e: print(f 处理第 {page_num} 页时出错: {e}) error_msg f\n{*40}\n第 {page_num} 页 [处理出错]\n{*40}\n\n错误信息: {str(e)}\n all_texts.append(error_msg) # 第三步保存结果 print(f\n3. 保存识别结果到文件...) # 合并所有文字 full_text .join(all_texts) # 写入文件 with open(output_text_file, w, encodingutf-8) as f: f.write(full_text) print(f处理完成结果已保存到: {output_text_file}) # 第四步清理临时图片文件可选 print(f\n4. 清理临时文件...) for image_path in image_paths: try: os.remove(image_path) except: pass # 尝试删除空文件夹 try: os.rmdir(temp_folder) except: pass print(所有处理完成)5.3 完整可用的批量处理脚本把上面的所有功能整合起来就是一个完整的批量PDF OCR工具#!/usr/bin/env python3 批量PDF OCR处理工具 使用LightOnOCR-2-1B模型提取PDF截图中的文字 import os import sys import time import json import base64 import requests from pdf2image import convert_from_path from PIL import Image class PDFOCRProcessor: PDF OCR处理器 def __init__(self, server_ip): 初始化处理器 参数: server_ip: LightOnOCR服务器IP地址 self.api_url fhttp://{server_ip}:8000/v1/chat/completions self.server_ip server_ip def check_server_status(self): 检查服务器状态 try: response requests.get(fhttp://{self.server_ip}:7860, timeout5) return response.status_code 200 except: return False def image_to_base64(self, image_path): 图片转Base64编码 with open(image_path, rb) as f: return fdata:image/png;base64,{base64.b64encode(f.read()).decode(utf-8)} def extract_text(self, image_base64): 调用OCR API提取文字 payload { model: /root/ai-models/lightonai/LightOnOCR-2-1B, messages: [{ role: user, content: [{ type: image_url, image_url: {url: image_base64} }] }], max_tokens: 4096 } try: response requests.post( self.api_url, headers{Content-Type: application/json}, datajson.dumps(payload), timeout30 ) response.raise_for_status() return response.json()[choices][0][message][content] except Exception as e: print(fOCR识别失败: {e}) return None def process_pdf(self, pdf_path, output_diroutput): 处理单个PDF文件 参数: pdf_path: PDF文件路径 output_dir: 输出目录 # 创建输出目录 os.makedirs(output_dir, exist_okTrue) # 生成输出文件名 pdf_name os.path.splitext(os.path.basename(pdf_path))[0] output_file os.path.join(output_dir, f{pdf_name}_extracted.txt) print(f\n{*60}) print(f处理文件: {pdf_path}) print(f输出到: {output_file}) print(f{*60}) # 创建临时目录 temp_dir temp_ocr_images os.makedirs(temp_dir, exist_okTrue) try: # 转换PDF为图片 print(\n1. 转换PDF为图片...) images convert_from_path(pdf_path, dpi200) # 200 DPI足够清晰 all_text [] total_pages len(images) print(f2. 开始OCR识别共 {total_pages} 页) # 逐页处理 for i, image in enumerate(images): page_num i 1 print(f\n 处理第 {page_num}/{total_pages} 页...) # 保存临时图片 temp_image_path os.path.join(temp_dir, fpage_{page_num:03d}.png) image.save(temp_image_path, PNG) # 转换并识别 image_base64 self.image_to_base64(temp_image_path) text self.extract_text(image_base64) if text: page_content f\n{*40}\n第 {page_num} 页\n{*40}\n\n{text}\n all_text.append(page_content) print(f 识别成功: {len(text)} 字符) else: error_msg f\n{*40}\n第 {page_num} 页 [识别失败]\n{*40}\n\n all_text.append(error_msg) print(f 识别失败) # 清理临时图片 os.remove(temp_image_path) # 进度显示 progress (page_num / total_pages) * 100 print(f 进度: {progress:.1f}%) # 延迟一下避免请求过快 if page_num total_pages: time.sleep(0.5) # 保存结果 print(f\n3. 保存结果...) with open(output_file, w, encodingutf-8) as f: f.write(.join(all_text)) print(f✓ 处理完成结果保存到: {output_file}) except Exception as e: print(f✗ 处理过程中出错: {e}) return False finally: # 清理临时目录 try: os.rmdir(temp_dir) except: pass return True def batch_process(self, pdf_folder, output_diroutput): 批量处理文件夹中的所有PDF文件 参数: pdf_folder: 包含PDF文件的文件夹路径 output_dir: 输出目录 # 检查文件夹 if not os.path.exists(pdf_folder): print(f错误文件夹不存在 - {pdf_folder}) return # 查找所有PDF文件 pdf_files [] for file in os.listdir(pdf_folder): if file.lower().endswith(.pdf): pdf_files.append(os.path.join(pdf_folder, file)) if not pdf_files: print(f在 {pdf_folder} 中没有找到PDF文件) return print(f找到 {len(pdf_files)} 个PDF文件) # 逐个处理 success_count 0 for i, pdf_file in enumerate(pdf_files): print(f\n处理文件 {i1}/{len(pdf_files)}) if self.process_pdf(pdf_file, output_dir): success_count 1 print(f\n{*60}) print(f批量处理完成) print(f成功: {success_count}/{len(pdf_files)}) print(f输出目录: {output_dir}) print(f{*60}) def main(): 主函数 print(LightOnOCR-2-1B PDF批量处理工具) print( * 50) # 配置服务器IP server_ip input(请输入LightOnOCR服务器IP地址: ).strip() # 创建处理器 processor PDFOCRProcessor(server_ip) # 检查服务器状态 print(\n检查服务器连接...) if processor.check_server_status(): print(✓ 服务器连接正常) else: print( 无法连接到服务器请检查IP地址和网络) if input(是否继续(y/n): ).lower() ! y: return # 选择处理模式 print(\n请选择处理模式:) print(1. 处理单个PDF文件) print(2. 批量处理文件夹中的所有PDF) choice input(请输入选择 (1 或 2): ).strip() if choice 1: # 单个文件处理 pdf_path input(请输入PDF文件路径: ).strip() if os.path.exists(pdf_path): processor.process_pdf(pdf_path) else: print(f文件不存在: {pdf_path}) elif choice 2: # 批量处理 folder_path input(请输入PDF文件夹路径: ).strip() processor.batch_process(folder_path) else: print(无效选择) if __name__ __main__: main()这个脚本可以直接运行它会提示你输入服务器IP地址然后选择是处理单个PDF还是批量处理整个文件夹。6. 实用技巧与优化建议在实际使用中你可能会遇到各种情况。这里分享一些实用技巧能让你的OCR处理更加顺畅。6.1 图片质量优化OCR的识别准确度和图片质量直接相关。下面是一些优化建议def optimize_image_for_ocr(image_path, output_pathNone): 优化图片以提高OCR识别率 参数: image_path: 原始图片路径 output_path: 优化后图片保存路径可选 返回: 优化后的图片对象 from PIL import Image, ImageEnhance # 打开图片 img Image.open(image_path) # 1. 调整大小如果图片太大 max_size 1540 # LightOnOCR推荐的最大边长 width, height img.size if max(width, height) max_size: # 等比例缩放 if width height: new_width max_size new_height int(height * (max_size / width)) else: new_height max_size new_width int(width * (max_size / height)) img img.resize((new_width, new_height), Image.Resampling.LANCZOS) # 2. 转换为灰度图彩色对OCR帮助不大还增加数据量 if img.mode ! L: img img.convert(L) # 3. 增强对比度 enhancer ImageEnhance.Contrast(img) img enhancer.enhance(1.5) # 增强1.5倍 # 4. 增强锐度 enhancer ImageEnhance.Sharpness(img) img enhancer.enhance(1.2) # 保存优化后的图片 if output_path: img.save(output_path, PNG, optimizeTrue) return img6.2 处理大文件的策略如果PDF文件很大比如上百页一次性处理可能会遇到内存问题。这时候可以分批处理def process_large_pdf_in_batches(pdf_path, api_url, batch_size10): 分批处理大型PDF文件 参数: pdf_path: PDF文件路径 api_url: API地址 batch_size: 每批处理的页数 # 先获取总页数 from PyPDF2 import PdfReader reader PdfReader(pdf_path) total_pages len(reader.pages) print(fPDF总页数: {total_pages}) print(f分批处理每批 {batch_size} 页) # 分批处理 for batch_start in range(0, total_pages, batch_size): batch_end min(batch_start batch_size, total_pages) batch_pages list(range(batch_start, batch_end)) print(f\n处理批次: 第 {batch_start1}-{batch_end} 页) # 这里可以调用之前写的处理函数 # 注意需要修改处理函数支持指定页面范围 # 每批处理完后可以保存中间结果 intermediate_file fbatch_{batch_start//batch_size 1}.txt print(f中间结果保存到: {intermediate_file})6.3 错误处理与重试机制网络请求可能会失败添加重试机制能提高稳定性def extract_text_with_retry(api_url, image_base64, max_retries3): 带重试机制的OCR识别 参数: api_url: API地址 image_base64: Base64编码的图片 max_retries: 最大重试次数 返回: 识别结果或None for attempt in range(max_retries): try: text extract_text_from_image(api_url, image_base64) if text: return text else: print(f第 {attempt1} 次尝试识别返回空结果) except Exception as e: print(f第 {attempt1} 次尝试失败: {e}) # 如果不是最后一次尝试等待后重试 if attempt max_retries - 1: wait_time 2 ** attempt # 指数退避1, 2, 4秒... print(f等待 {wait_time} 秒后重试...) time.sleep(wait_time) print(f经过 {max_retries} 次尝试后仍然失败) return None7. 实际应用场景示例了解了基本用法我们来看看在实际工作中怎么应用这个工具。7.1 场景一学术论文批量处理如果你是研究人员需要从大量PDF论文中提取文字进行分析def process_academic_papers(papers_folder, output_folderpapers_text): 处理学术论文PDF提取摘要和正文 参数: papers_folder: 论文PDF文件夹 output_folder: 输出文件夹 import re processor PDFOCRProcessor(你的服务器IP) # 获取所有PDF文件 pdf_files [f for f in os.listdir(papers_folder) if f.endswith(.pdf)] for pdf_file in pdf_files: pdf_path os.path.join(papers_folder, pdf_file) print(f\n处理论文: {pdf_file}) # 提取文字 text processor.process_pdf(pdf_path, output_folder) if text: # 尝试提取摘要简单正则匹配 # 实际应用中可能需要更复杂的方法 abstract_patterns [ r摘要[:]\s*(.*?)(?\n\n|\n关键词|$), rAbstract[:]\s*(.*?)(?\n\n|\nKeywords|$), rSUMMARY[:]\s*(.*?)(?\n\n|$) ] abstract None for pattern in abstract_patterns: match re.search(pattern, text, re.DOTALL) if match: abstract match.group(1).strip() break # 保存摘要 if abstract: abstract_file os.path.join( output_folder, f{os.path.splitext(pdf_file)[0]}_abstract.txt ) with open(abstract_file, w, encodingutf-8) as f: f.write(abstract) print(f 摘要已提取: {len(abstract)} 字符)7.2 场景二扫描文档数字化公司有大量纸质文档需要数字化def digitize_scanned_documents(input_folder, output_folderdigitized): 批量数字化扫描文档 参数: input_folder: 扫描件PDF文件夹 output_folder: 数字化文本输出文件夹 import shutil processor PDFOCRProcessor(你的服务器IP) # 创建输出文件夹结构 os.makedirs(output_folder, exist_okTrue) os.makedirs(os.path.join(output_folder, text), exist_okTrue) os.makedirs(os.path.join(output_folder, backup), exist_okTrue) # 处理所有PDF for filename in os.listdir(input_folder): if filename.lower().endswith(.pdf): pdf_path os.path.join(input_folder, filename) print(f数字化处理: {filename}) # 提取文字 text_file os.path.join(output_folder, text, f{os.path.splitext(filename)[0]}.txt) success processor.process_pdf(pdf_path, text_file) if success: # 备份原文件 backup_path os.path.join(output_folder, backup, filename) shutil.copy2(pdf_path, backup_path) print(f ✓ 完成原文件已备份) else: print(f ✗ 处理失败) print(f\n数字化完成) print(f文本文件保存在: {os.path.join(output_folder, text)}) print(f原文件备份在: {os.path.join(output_folder, backup)})7.3 场景三多语言文档处理处理包含多种语言的文档def detect_and_process_multilingual(pdf_path, output_filemultilingual_output.txt): 处理多语言混合的PDF文档 参数: pdf_path: PDF文件路径 output_file: 输出文件 import langdetect from collections import Counter processor PDFOCRProcessor(你的服务器IP) print(处理多语言文档...) # 提取文字 text processor.process_pdf(pdf_path, output_file) if text: # 简单语言检测需要安装langdetect库 try: # 采样检测 samples text.split()[:100] # 取前100个词 languages [] for word in samples: if len(word) 2: # 只检测长度大于2的词 try: lang langdetect.detect(word) languages.append(lang) except: pass # 统计语言分布 if languages: lang_counts Counter(languages) print(检测到的语言分布:) for lang, count in lang_counts.most_common(): print(f {lang}: {count} 个词) except ImportError: print(未安装langdetect库跳过语言检测) # 按段落分割并标记简单实现 paragraphs [p.strip() for p in text.split(\n\n) if p.strip()] with open(output_file, w, encodingutf-8) as f: f.write(多语言文档提取结果\n) f.write( * 50 \n\n) for i, para in enumerate(paragraphs[:20]): # 只处理前20段 f.write(f[段落 {i1}]\n) f.write(para \n) f.write(- * 40 \n\n) print(f多语言文档处理完成保存到: {output_file})8. 总结通过这篇文章我们完整地走了一遍使用LightOnOCR-2-1B进行批量PDF文字提取的流程。从最基础的API调用到完整的批量处理脚本再到实际应用场景你应该已经掌握了这套工具的使用方法。让我简单总结一下关键点技术核心很简单其实就是三步PDF转图片 → 图片转Base64 → 调用API识别。理解了这三点你就能根据自己的需求定制各种处理流程。批量处理是王道单张图片识别虽然有用但真正的效率提升来自批量处理。我提供的完整脚本可以直接用也可以根据你的需求修改。实际应用广泛无论是学术研究、文档数字化还是多语言处理这套方法都能派上用场。关键是理解原理然后灵活应用。优化让效果更好图片预处理、错误重试、分批处理这些小技巧能让整个流程更加稳定可靠。特别是图片质量优化对识别准确率影响很大。最后提醒一下LightOnOCR-2-1B对图片分辨率有要求最长边1540像素效果最好。如果遇到识别不准的情况可以尝试调整图片大小和对比度。现在你已经有了一个强大的OCR工具接下来就是把它用到你的实际工作中去。无论是处理几十页的文档还是成百上千的PDF文件这套方法都能帮你节省大量时间。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。