使用 Python 实现 ETL 流程:从文本文件提取到数据处理的全面指南

文章大纲:

引言:什么是 ETL 以及其重要性

ETL(提取-转换-加载)是数据处理领域中的核心概念,代表了从源数据到目标系统的三个关键步骤:**提取(Extract)**数据、**转换(Transform)数据以符合业务需求,以及加载(Load)**数据到最终存储位置。ETL 流程在数据集成、数据仓库构建和业务分析中扮演着重要角色,它确保数据从分散、异构的来源被整理为统一、可用的形式,从而支持决策和洞察生成。在现代数据驱动的环境中,ETL 的高效实现直接影响企业的数据质量和运营效率。

本文将聚焦于使用 Python 这一强大且灵活的编程语言来实现 ETL 流程,特别关注从文本文件提取数据的技巧和实践。无论是处理简单的日志文件还是复杂的非结构化文本,Python 提供了丰富的工具和库来应对挑战。我们将从基础的文本读取开始,逐步深入到编码问题、数据清洗和结构化解析,帮助读者掌握构建高效 ETL 流程的关键技能。无论是数据分析师还是开发者,本文都将为你提供实用指导。

ETL 流程概述:提取、转换与加载的三个阶段

ETL 流程是数据处理的核心框架,包含三个关键阶段:提取(Extract)转换(Transform)加载(Load)。在提取阶段,数据从各种来源(如文本文件、数据库或 API)被读取到处理环境中。这一阶段的挑战包括处理异构数据格式、确保数据完整性以及优化读取效率,例如避免一次性加载大文件导致的内存问题。转换阶段是对提取的数据进行清洗、格式化或重组,以满足目标系统的需求。这一过程可能涉及去除重复值、标准化文本、转换数据类型或应用业务规则,旨在提高数据质量和一致性。加载阶段则是将处理后的数据存储到目标位置,如数据仓库、数据库或文件系统,需确保数据准确无误地写入,并考虑性能和存储结构的优化。

每个阶段在数据处理中都有独特作用:提取决定了数据获取的可靠性,转换直接影响数据可用性,而加载则关乎数据最终的可访问性。挑战在于如何平衡效率与准确性,例如在转换阶段处理缺失值或异常值时需谨慎,以免引入偏差。通过 Python 实现 ETL 流程,可以利用其丰富的库和灵活性应对这些挑战,为数据分析和业务决策奠定坚实基础。

文本文件读取的基础:提取阶段的起点

在 ETL 流程的提取阶段,读取源数据是整个过程的起点,而文本文件作为常见的数据载体,广泛应用于日志记录、数据交换和存储等领域。使用 Python 读取文本文件非常简单,但对于大规模数据或复杂文件,内存管理和读取效率成为关键问题。Python 提供了多种方法来处理文本文件,既适用于小型文件,也能应对大文件挑战。

最基本的方法是使用 open() 函数以只读模式('r')打开文件,并通过 read() 方法一次性读取全部内容。例如:

with open('example.txt', 'r') as file:content = file.read()print(content)

然而,对于大文件,这种一次性读取的方式可能导致内存溢出,因为所有数据都会被加载到内存中。为了解决这一问题,逐行读取是一个更高效的选择。使用 for 循环或 readline() 方法,可以每次仅读取一行数据,显著降低内存占用:

with open('large_file.txt', 'r') as file:for line in file:print(line.strip())

这里的 strip() 方法用于去除每行末尾的换行符(\n),以便于后续处理。逐行读取不仅节省内存,还允许在读取过程中即时处理数据,非常适合 ETL 流程中的提取阶段。此外,with 语句确保文件在操作完成后自动关闭,避免资源泄漏。

在处理大文件时,还需注意文件路径的正确性以及异常处理。例如,若文件不存在,程序会抛出 FileNotFoundError,因此建议使用 try-except 结构来捕获潜在错误:

try:with open('data.txt', 'r') as file:for line in file:print(line.strip())
except FileNotFoundError:print("文件未找到,请检查路径。")

通过上述方法,Python 为文本文件的读取提供了灵活且高效的解决方案,为 ETL 流程的提取阶段奠定了基础。在后续处理中,如何应对编码问题和文件结构差异将成为关注的重点,但掌握逐行读取和异常处理是迈向更复杂数据提取的第一步。

文本编码问题:ASCII、Unicode 和 UTF-8 的处理

在 ETL 流程的提取阶段,文本编码问题是不可忽视的挑战。文本文件通常以特定编码格式存储,如 ASCII、Unicode 或 UTF-8,而不同编码之间的差异可能导致数据读取错误或乱码。理解并正确处理编码问题,是确保数据完整性和准确性的关键。

ASCII(American Standard Code for Information Interchange)是最早的编码标准,使用 7 位二进制数表示 128 个字符,主要涵盖英文字符和基本符号。虽然 ASCII 简单且高效,但其局限性在于无法表示非英文字符,如中文、日文或其他语言的特殊符号。为了解决这一问题,Unicode 应运而生,它是一个通用的字符编码标准,旨在覆盖全球所有语言的字符。UTF-8 作为 Unicode 的实现方式之一,使用变长编码(1 到 4 个字节)表示字符,既兼容 ASCII(单字节表示常用字符),又能表示复杂字符,是目前互联网和数据存储中最广泛使用的编码格式。相比之下,ASCII 的局限性在于字符集过小,而 UTF-8 的优势在于其灵活性和兼容性,但处理复杂字符时可能增加存储和计算开销。

在 Python 中,读取文本文件时需要指定正确的编码,否则可能导致 UnicodeDecodeError。默认情况下,open() 函数会尝试以系统默认编码读取文件,但这往往不适用于所有情况。通过指定 encoding 参数,可以明确文件编码,例如:

with open('text.txt', 'r', encoding='utf-8') as file:content = file.read()print(content)

然而,即使指定了编码,仍可能遇到编码错误,例如文件中包含不支持的字符或编码声明与实际不符。为此,Python 提供了 errors 参数来处理错误,常见的选项包括 ignore(忽略错误字符)、replace(用占位符替换错误字符)和 strict(默认值,抛出异常)。以下示例展示了不同选项的效果:

# 忽略编码错误
with open('text.txt', 'r', encoding='ascii', errors='ignore') as file:content = file.read()print("忽略错误:", content)# 替换编码错误字符
with open('text.txt', 'r', encoding='ascii', errors='replace') as file:content = file.read()print("替换错误:", content)

使用 errors='ignore' 时,Python 会跳过无法解码的字符,这可能导致数据丢失;而 errors='replace' 会用 符号替换错误字符,保留数据结构但丢失原始内容。开发者需根据具体场景选择合适的处理方式,例如在数据分析中可能更倾向于记录错误而不是忽略。

此外,检测文件编码也是一个实用技巧。Python 的第三方库 chardet 可以帮助识别文件的实际编码,避免手动尝试多种编码:

import chardetwith open('text.txt', 'rb') as file:raw_data = file.read()result = chardet.detect(raw_data)print("检测到的编码:", result['encoding'])

通过理解 ASCII、Unicode 和 UTF-8 的差异,并掌握 Python 中编码处理的工具和参数,开发者可以在 ETL 流程的提取阶段有效避免数据损坏或读取失败的问题。正确的编码处理不仅是技术要求,也是确保数据质量的重要环节。

非结构化文本处理:挑战与方法

非结构化文本,如小说、新闻文章或社交媒体内容,通常缺乏固定的格式或分隔符,这为 ETL 流程中的提取和转换阶段带来了显著挑战。与结构化数据(如 CSV 文件)不同,非结构化文本的数据边界不明确,内容可能包含噪声(如无关符号或格式不一致),且逻辑单元(如段落或句子)的分割往往依赖上下文而非固定规则。这些特性使得直接解析和处理变得困难,容易导致数据丢失或误解。

在处理非结构化文本时,一个常见的任务是根据逻辑单元分割文本,例如将小说按段落划分。段落通常由空行分隔,但不同文件可能有不同的分隔方式(如多个空行或特定符号)。Python 提供了灵活的工具来应对这一挑战,例如使用 split() 方法结合特定的分隔符来分割文本。以经典小说《白鲸记》(Moby-Dick)为例,假设其文本文件使用双空行(\n\n)分隔段落,可以通过以下代码实现分割:

with open('moby_dick.txt', 'r', encoding='utf-8') as file:text = file.read()paragraphs = text.split('\n\n')for i, para in enumerate(paragraphs[:3], 1):  # 仅显示前三个段落print(f"段落 {i}: {para.strip()[:100]}...")  # 限制每个段落显示前100个字符

在上述代码中,split('\n\n') 将文本按双空行分割为段落列表,strip() 方法去除每段开头和结尾的空白字符,确保数据整洁。然而,这种方法存在局限性:如果文本的分隔规则不一致(如部分段落仅用单空行分隔),分割结果可能不准确。为此,可以结合正则表达式(re 模块)进一步优化处理,匹配更复杂的分隔模式:

import rewith open('moby_dick.txt', 'r', encoding='utf-8') as file:text = file.read()paragraphs = re.split(r'\n\s*\n', text)  # 匹配一个或多个空行for i, para in enumerate(paragraphs[:3], 1):print(f"段落 {i}: {para.strip()[:100]}...")

使用 re.split(r'\n\s*\n', text) 可以处理空行中可能夹杂空格或制表符的情况,提高分割的鲁棒性。此外,非结构化文本处理还需考虑其他挑战,如去除无关内容(页眉、页脚或注释)或处理特殊字符,这些通常需要在转换阶段进一步清洗。

非结构化文本的处理不仅是技术问题,也是数据理解问题。开发者需结合具体文本的特点设计分割和清洗逻辑,避免盲目应用通用方法。例如,《白鲸记》中可能包含对话引号或章节标题,这些内容是否需要单独提取取决于 ETL 流程的目标。通过灵活运用 Python 的字符串方法和正则表达式,可以有效应对非结构化文本的复杂性,为后续数据分析或存储奠定基础。

文本数据规范化:为后续处理做准备

在 ETL 流程的转换阶段,文本数据规范化是确保数据一致性和可用性的重要步骤。未经处理的原始文本往往包含不一致的大小写、冗余的标点符号或特殊字符,这些都可能影响后续分析或机器学习模型的准确性。规范化旨在将文本转换为统一格式,减少噪声,为进一步处理(如分词、特征提取或存储)奠定基础。常见规范化操作包括统一大小写、移除标点符号、处理多余空格以及标准化特殊字符。

Python 提供了多种内置方法来实现文本规范化,最基础的操作是将文本转换为小写或大写,以消除大小写差异对文本匹配或比较的影响。例如,使用 lower() 方法可以将所有字符转换为小写:

text = "Hello, World! This Is A Test."
normalized_text = text.lower()
print(normalized_text)  # 输出: hello, world! this is a test.

这一操作在处理用户输入或搜索功能时尤为重要,因为它确保“HELLO”和“hello”被视为相同内容。类似地,upper() 方法可用于转换为大写,具体选择取决于应用场景。

另一个常见的规范化任务是移除标点符号和特殊字符,这些字符通常对文本分析无意义,但可能干扰分词或模式匹配。Python 的 replace() 方法可以逐个替换特定字符,但对于大量不同字符,这种方式效率较低。例如:

text = "Hello, World! How are you?"
cleaned_text = text.replace(',', '').replace('!', '').replace('?', '')
print(cleaned_text)  # 输出: Hello World How are you

更高效的方法是使用 translate() 方法结合 str.maketrans(),可以一次性移除或替换多个字符。以下示例展示了如何移除所有标点符号:

import stringtext = "Hello, World! How are you?"
# 创建一个映射表,将所有标点符号映射为空字符
translator = str.maketrans('', '', string.punctuation)
cleaned_text = text.translate(translator)
print(cleaned_text)  # 输出: Hello World How are you

这里,string.punctuation 提供了所有常见标点符号的集合,translate() 方法通过映射表一次性处理所有匹配字符,性能远优于多次调用 replace()。此外,translate() 还可用于更复杂的替换操作,例如将特定字符标准化(如将“é”替换为“e”),适用于处理多语言文本。

多余空格的处理也是规范化的一部分,文本中可能包含多个连续空格或制表符,使用 strip() 方法可以去除首尾空格,而正则表达式(re 模块)可将多个空格替换为单个空格:

import retext = "Hello    World   !   How   are   you?"
cleaned_text = re.sub(r'\s+', ' ', text.strip())
print(cleaned_text)  # 输出: Hello World ! How are you?

通过上述方法,文本数据规范化可以显著提高数据质量,确保后续 ETL 阶段(如加载到数据库或用于分析)的一致性和可靠性。开发者应根据具体需求选择合适的规范化策略,例如在情感分析中可能保留标点符号以捕捉语气,而在关键词提取中则需彻底移除无关字符。掌握 Python 的字符串处理工具和正则表达式,是实现高效文本规范化的关键。

结构化文本文件:分隔符文件的基础

结构化文本文件是一种以固定格式组织数据的数据存储方式,通常使用分隔符来区分不同的字段或记录。相比于非结构化文本,结构化文本文件(如 CSV、TSV 或其他平面文件)具有清晰的字段边界和记录分隔,使得数据提取和解析更加简单和可靠。这类文件广泛应用于数据交换、日志存储和简单的数据库替代场景,是 ETL 流程中常见的源数据格式。在提取阶段,理解和处理分隔符文件的基础知识至关重要。

分隔符是结构化文本文件的核心元素,用于分隔字段或列。常见的分隔符包括逗号(,,如 CSV 文件)、制表符(\t,如 TSV 文件)以及管道符(|)等。选择分隔符通常取决于数据的特性和应用场景,例如逗号适用于简单数据,但如果字段中本身包含逗号,则可能导致解析错误,此时制表符或管道符可能是更好的选择。分隔符文件的每一行通常代表一条记录,而每条记录中的字段则由分隔符分隔,形成类似于表格的结构。例如,一个简单的 CSV 文件可能如下:

name,age,city
Alice,25,New York
Bob,30,Los Angeles

在 Python 中,解析分隔符文件可以通过手动使用 split() 方法实现。split() 方法将字符串按指定分隔符分割为列表,非常适合处理简单的结构化文本文件。以下是一个示例,展示如何读取并解析一个逗号分隔的文本文件:

with open('data.csv', 'r', encoding='utf-8') as file:for line in file:fields = line.strip().split(',')print(fields)

在上述代码中,strip() 方法用于去除每行末尾的换行符,split(',') 则将每行按逗号分割为字段列表。输出可能是 ['Alice', '25', 'New York'] 这样的列表,代表一条记录的各个字段。然而,手动解析存在局限性:如果字段中本身包含分隔符(如 New York, NY 中的逗号),split() 会错误地将字段进一步分割,导致数据不完整。此外,字段中可能包含引号或换行符,这些复杂情况也难以通过简单的 split() 处理。

因此,尽管 split() 方法适用于简单的分隔符文件,但对于更复杂的数据,建议使用 Python 的标准库模块(如 csv)来处理。这些模块能够正确处理引号包围的字段、嵌入的分隔符和其他边界情况,确保数据解析的准确性。在 ETL 流程中,选择合适的解析方法不仅影响提取阶段的效率,还直接关系到后续转换和加载阶段的数据质量。掌握分隔符文件的基础知识和手动解析方法,是进一步学习高级工具的前提。

使用 CSV 模块处理分隔符文件:高效与可靠

在 ETL 流程的提取阶段,处理结构化文本文件(如 CSV 文件)时,Python 的标准库 csv 模块是一个强大且可靠的工具。虽然手动使用 split() 方法可以解析简单的分隔符文件,但它无法有效处理复杂情况,例如字段中嵌入了分隔符、包含引号的文本或换行符等边界问题。csv 模块专门为处理此类问题而设计,支持多种分隔符和格式选项,确保数据解析的准确性和效率,特别适合在 ETL 流程中处理大规模或格式复杂的数据文件。

csv 模块提供了 csv.reader 对象,用于逐行读取 CSV 文件并将其解析为字段列表。默认情况下,csv.reader 假设文件使用逗号作为分隔符,但可以通过参数自定义分隔符、引号字符等设置。以下是一个使用 csv.reader 解析 CSV 文件的基本示例:

import csvwith open('data.csv', 'r', encoding='utf-8') as file:reader = csv.reader(file)for row in reader:print(row)

假设 data.csv 文件内容如下:

name,age,city
Alice,25,"New York, NY"
Bob,30,"Los Angeles"

运行上述代码,输出将是:

['name', 'age', 'city']
['Alice', '25', 'New York, NY']
['Bob', '30', 'Los Angeles']

与手动使用 split(',') 相比,csv.reader 的优势在于它能够正确处理字段中嵌入的逗号(如 New York, NY),因为它会识别引号(")包围的字段并保留其中的内容完整性。此外,csv.reader 还可以处理字段中的换行符、引号转义(如 "" 表示单个引号)等复杂情况,避免了手动解析可能导致的数据错误。

csv 模块还支持自定义参数以适应不同格式的文件。例如,如果文件使用制表符(\t)作为分隔符,可以通过 delimiter 参数指定:

import csvwith open('data.tsv', 'r', encoding='utf-8') as file:reader = csv.reader(file, delimiter='\t')for row in reader:print(row)

其他常用参数包括 quotechar(指定引号字符,默认是 ")和 quoting(控制引号处理模式),这些参数使得 csv 模块能够灵活应对各种非标准 CSV 格式。此外,csv 模块提供了 Sniffer 类,可以自动检测文件的格式(如分隔符类型),减少手动配置的工作量:

import csvwith open('data.csv', 'r', encoding='utf-8') as file:sample = file.read(1024)  # 读取文件前1024个字符用于检测file.seek(0)  # 重置文件指针到开头dialect = csv.Sniffer().sniff(sample)reader = csv.reader(file, dialect)for row in reader:print(row)

相比手动解析,csv 模块不仅提高了代码的可靠性和可维护性,还显著降低了出错风险。手动使用 split() 方法在面对复杂数据时需要编写大量条件判断逻辑,而 csv 模块已经内置了对这些边缘情况的处理。在 ETL 流程中,数据准确性至关重要,尤其是在提取阶段,任何解析错误都可能影响后续的转换和加载操作。因此,使用 csv 模块是处理分隔符文件的推荐方式,特别是对于格式复杂或数据量较大的文件。

需要注意的是,csv 模块在处理非常大的文件时可能会有性能开销,因为它需要逐行解析并处理特殊字符。如果性能成为瓶颈,可以结合逐行读取和批量处理策略,或者考虑其他工具如 pandas 库来加速处理。但对于大多数 ETL 场景,csv 模块提供的平衡性——易用性、准确性和灵活性——使其成为首选工具。通过掌握 csv.reader 的用法,开发者可以构建更健壮的数据提取流程,为后续转换和加载阶段奠定坚实基础。

高级 CSV 处理:使用 DictReader 提升数据可读性

在 ETL 流程中,处理 CSV 文件时,数据的可读性和易用性是提升代码质量的重要因素。虽然 csv.reader 能够高效解析 CSV 文件并返回字段列表,但其输出是以位置索引访问数据的(例如 row[0] 表示第一列),这在字段较多或代码复杂时容易导致错误,且不直观。Python 的 csv 模块提供了 DictReader 类,将 CSV 文件的每一行读取为字典形式,允许开发者通过字段名而非索引访问数据,从而显著提高代码的可读性和维护性。

DictReader 的核心优势在于它会自动将 CSV 文件的第一行(通常是表头)作为字段名,并将后续每一行的数据映射为字典,键是表头名称,值是对应字段的内容。假设有一个 CSV 文件 data.csv,内容如下:

name,age,city
Alice,25,New York
Bob,30,Los Angeles

使用 DictReader 读取该文件,可以通过以下代码实现:

import csvwith open('data.csv', 'r', encoding='utf-8') as file:reader = csv.DictReader(file)for row in reader:print(f"姓名: {row['name']}, 年龄: {row['age']}, 城市: {row['city']}")

运行上述代码,输出将是:

姓名: Alice, 年龄: 25, 城市: New York
姓名: Bob, 年龄: 30, 城市: Los Angeles

通过 row['name'] 而非 row[0] 访问数据,不仅使代码更具可读性,还降低了因字段顺序变化导致的错误风险。例如,如果 CSV 文件的列顺序在未来被调整,使用索引访问的方式需要修改所有相关代码,而 DictReader 则不受影响。此外,字典形式的输出更符合人类思维习惯,特别在 ETL 流程中需要根据字段名进行数据转换或验证时,这种方式能显著减少认知负担。

DictReader 还支持自定义字段名,如果 CSV 文件没有表头行,或者表头不适合直接使用,可以通过 fieldnames 参数手动指定字段名。例如:

import csvwith open('data_no_header.csv', 'r', encoding='utf-8') as file:reader = csv.DictReader(file, fieldnames=['姓名', '年龄', '城市'])for row in reader:print(f"姓名: {row['姓名']}, 年龄: {row['年龄']}, 城市: {row['城市']}")

这种灵活性使得 DictReader 适用于各种非标准 CSV 文件。此外,DictReader 继承了 csv.reader 的所有优点,能够正确处理复杂的 CSV 格式,如字段中嵌入的分隔符或引号,确保数据解析的准确性。

然而,DictReader 也存在一些潜在缺点,主要体现在性能开销上。由于它需要为每一行构建字典对象,相比 csv.reader 返回的简单列表,内存和计算成本略高。在处理非常大的 CSV 文件(例如数百万行数据)时,这种开销可能变得显著。如果性能是首要考虑因素,可以选择 csv.reader 并手动管理字段索引,或者结合批量处理策略减少内存占用。但对于大多数 ETL 场景,尤其是数据量适中或代码可读性优先的情况下,DictReader 提供的便利性远超其性能成本。

在实际应用中,DictReader 特别适合需要频繁访问特定字段的场景,例如在转换阶段根据字段名进行数据清洗或格式化。通过将数据组织为字典形式,开发者可以轻松实现条件过滤或字段映射逻辑。例如,提取年龄大于 25 岁的人员信息:

import csvwith open('data.csv', 'r', encoding='utf-8') as file:reader = csv.DictReader(file)filtered_data = [row for row in reader if int(row['age']) > 25]for row in filtered_data:print(f"姓名: {row['name']}, 年龄: {row['age']}")

通过掌握 DictReader 的用法,开发者可以在 ETL 流程中构建更直观、更健壮的数据处理逻辑。无论是数据分析还是数据集成,按字段名访问数据的特性都能减少错误并提升效率,为后续的转换和加载阶段提供清晰的数据结构支持。

ETL 转换与加载阶段:数据清洗与存储的初步探讨

在 ETL 流程中,转换(Transform)和加载(Load)阶段是数据从原始状态到最终可用形式的关键步骤。转换阶段专注于数据清洗和格式调整,以确保数据符合业务需求或目标系统的要求。数据清洗可能包括去除重复记录、处理缺失值、标准化数据格式(如日期格式统一为 YYYY-MM-DD)以及纠正错误数据(如拼写错误或异常值)。例如,在处理从文本文件提取的数据时,可能需要将文本字段中的多余空格移除,或将数值字符串转换为整数或浮点数类型。这些操作可以通过 Python 的内置函数或第三方库(如 pandas)实现,确保数据一致性和质量。此外,转换阶段还可能涉及数据聚合或派生字段的创建,例如从日期字段计算年龄或将多个字段拼接为一个完整地址。

加载阶段则是将经过转换的数据存储到目标位置的过程,目标可以是文件系统、关系型数据库(如 MySQL、PostgreSQL)、NoSQL 数据库(如 MongoDB)或数据仓库。加载过程需要考虑目标系统的结构和性能要求,例如在写入数据库时需确保数据符合表结构和约束条件(如主键唯一性)。Python 提供了丰富的库来支持数据加载,例如 sqlite3SQLAlchemy 可用于数据库操作,而简单的文件存储则可以通过 write() 方法或 csv 模块实现。加载阶段的挑战在于如何处理大规模数据写入时的效率问题,以及如何在出错时实现回滚或错误日志记录,以避免数据丢失或损坏。

在实际应用中,转换和加载阶段往往紧密相关,开发者需根据具体场景设计流程。例如,将清洗后的数据存储为 CSV 文件可能只需要几行代码:

import csvdata = [{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]
with open('output.csv', 'w', encoding='utf-8', newline='') as file:writer = csv.DictWriter(file, fieldnames=["name", "age"])writer.writeheader()writer.writerows(data)

而对于数据库存储,则需要更多错误处理和连接管理逻辑。后续章节将深入探讨如何处理更复杂的结构化数据文件和数据库存储,包括批量写入、最佳实践以及性能优化策略。通过初步了解转换和加载阶段的核心任务,开发者可以为构建完整 ETL 流程奠定基础,确保数据从提取到最终存储的每一步都准确、高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913374.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913374.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

selenium基础知识 和 模拟登录selenium版本

前言 selenium框架是Python用于控制浏览器的技术,在Python爬虫获取页面源代码的时候,是最重要的技术之一,通过控制浏览器,更加灵活便捷的获取浏览器中网页的源代码。 还没有安装启动selenium的同志请先看我的上一篇文章进行配置启动 和 XPath基础 对selenium进行浏览器和驱动…

JS 网页全自动翻译v3.17发布,全面接入 GiteeAI 大模型翻译及自动部署

两行 js 实现 html 全自动翻译。 无需改动页面、无语言配置文件、无 API Key、对 SEO 友好! 升级说明 translate.service 深度绑定 GiteeAI 作为公有云翻译大模型算力支持translate.service 增加shell一键部署后通过访问自助完成GiteeAI的开通及整个接入流程。增加…

数据结构:数组:插入操作(Insert)与删除操作(Delete)

目录 插入操作(Inserting in an Array) 在纸上模拟你会怎么做? 代码实现 复杂度分析 删除操作(Deleting from an Array) 在纸上模拟一下怎么做? 代码实现 复杂度分析 插入操作(Inserti…

Qt之修改纯色图片的颜色

这里以修改QMenu图标颜色为例,效果如下: MyMenu.h #ifndef MYMENU_H #define MYMENU_H#include <QMenu>class MyMenu : public QMenu { public:explicit MyMenu(QWidget *parent = nullptr);protected:void mouseMoveEvent(QMouseEvent *event) override; };#endif /…

uni-app实现单选,多选也能搜索,勾选,选择,回显

前往插件市场安装插件下拉搜索选择框 - DCloud 插件市场&#xff0c;该插件示例代码有vue2和vue3代码 是支持微信小程序和app的 示例代码&#xff1a; <template><view><!-- 基础用法 --><cuihai-select-search:options"options"v-model&quo…

【机器学习深度学习】 微调的十种形式全解析

目录 一、为什么要微调&#xff1f; 二、微调的 10 种主流方式 ✅ 1. 全参数微调&#xff08;Full Fine-tuning&#xff09; ✅ 2. 冻结部分层微调&#xff08;Partial Fine-tuning&#xff09; ✅ 3. 参数高效微调&#xff08;PEFT&#xff09; &#x1f538; 3.1 LoRA&…

信刻光盘安全隔离与文件单向导入/导出系统

北京英特信网络科技有限公司成立于2005年&#xff0c;是专业的数据光盘摆渡、刻录分发及光盘存储备份领域的科技企业&#xff0c;专注为军队、军工、司法、保密等行业提供数据光盘安全摆渡、跨网交换、档案归档检测等专业解决方案。 公司立足信创产业&#xff0c;产品国产安全可…

Python-标准库-os

1 需求 2 接口 3 示例 4 参考资料 在 Python 中&#xff0c;os&#xff08;Operating System&#xff09;模块是一个非常重要的内置标准库&#xff0c;提供了许多与操作系统进行交互的函数和方法&#xff0c;允许开发者在 Python 程序中执行常见的操作系统任务&#xff0c;像文…

OpenCV CUDA模块设备层-----在 GPU 上执行类似于 std::copy 的操作函数warpCopy()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 OpenCV 的 CUDA 模块&#xff08;cudev&#xff09; 中的一个设备端内联模板函数&#xff0c;用于在 GPU 上执行类似于 std::copy 的操作&#xff…

Vue Router 中$route.path与 params 的关系

1. params 参数的本质&#xff1a;路径的动态片段在 Vue Router 中&#xff0c;params 参数是通过路由配置的动态路径片段定义的&#xff0c;例如&#xff1a;// 路由配置{ path: /user/:id, component: User }当访问/user/123时&#xff0c;/user/123是完整的路径&#xff0c;…

React 极简响应式滑块验证组件实现,随机滑块位置

&#x1f3af; 滑块验证组件 (Slider Captcha) 一个现代化、响应式的滑块验证组件&#xff0c;专为 React 应用设计&#xff0c;提供流畅的用户体验和强大的安全验证功能。 ✨ 功能特性 &#x1f3ae; 核心功能 智能滑块拖拽 – 支持鼠标和触摸屏操作&#xff0c;响应灵敏随…

STM32第十六天蓝牙模块

一&#xff1a;蓝牙模块HC-05 1&#xff1a;硬件引脚配置&#xff1a; | 标号 | PIN | 说明 | |------|-------|---------------------------------------| | 1 | START | 状态引出引脚&#xff08;未连接/连接输出信号时&#xff09; |…

时序数据库IoTDB用户自定义函数(UDF)使用指南

1. 编写UDF时序数据库IoTDB为用户提供了编写UDF的JAVA API&#xff0c;用户可以自主实现UDTF&#xff08;用户自定义转换函数&#xff09;类&#xff0c;IoTDB将通过类加载机制装载用户编写的类。Maven依赖如果使用Maven&#xff0c;可以从Maven库中搜索以下依赖&#xff0c;并…

Linux国产与国外进度对垒

Linux国产与国外进度对垒 引言国产Linux的发展现状国外Linux的发展现状技术对比国产Linux的挑战与机遇国外Linux的优势与局限结论 引言 简述Linux在全球操作系统市场中的地位国产Linux的发展背景与意义国外主流Linux发行版的现状 国产Linux的发展现状 主要国产Linux发行版介…

Jenkins-Email Extension 插件插件

Editable Email Notification Editable Email Notification 是 Jenkins 的 Email Extension 插件的核心功能&#xff0c;用于自定义邮件通知&#xff0c;包括邮件主题、内容、收件人、发件人等 属性 1.Project From 项目发件人&#xff0c;设置邮件的发件人地址 **注意&…

windows系统下将Docker Desktop安装到除了C盘的其它盘中

windows系统下安装docker会自动安装到C盘&#xff0c;可以采用下面的方法将其安装到其它盘中1、先下载Docker Desktop安装程序Docker Desktop Installer.exe&#xff0c;比如你下载到了C:\Users\YourUsername\Downloads 文件夹中。 2、打开 PowerShell 进入C:\Users\YourUser…

视频工具箱 1.1.1 |小而美的视频处理工具,支持多种常用功能

VideoTools是一款基于FFmpeg的小而美的视频处理工具&#xff0c;专为需要快速高效地进行视频编辑的用户设计。这款工具无需安装&#xff0c;体积仅约200KB&#xff0c;提供了视频压缩、格式转换、转GIF、修改分辨率、加速播放以及音频提取等多种常用功能。其用户界面简洁直观&a…

无人机集群搜索技术全面解析

无人机集群搜索是指通过多架无人机协同工作&#xff0c;实现对目标区域的高效覆盖与快速探测。这项技术通过模拟自然界生物群体的集体行为&#xff0c;利用分布式控制和自主决策算法&#xff0c;使无人机集群能够自组织地完成复杂搜索任务。下面从核心技术、应用场景、算法实现…

【Elasticsearch】深度分页及其替代方案

深度分页及其替代方案 1.深度分页2.为什么不推荐深度分页2.1 性能问题&#xff08;核心原因&#xff09;2.2 资源消耗对比2.3 实际限制 3.深度分页的替代方案3.1 方案一&#xff1a;Search After&#xff08;推荐&#xff09;3.1.1 为什么 Search After 性能更高3.1.2 技术原理…

论文阅读笔记——VGGT: Visual Geometry Grounded Transformer

VGGT 论文 输入是 N 个 RGB 图像 I i ∈ R 3 H W I_i\in\mathbb{R}^{3HW} Ii​∈R3HW 的序列 ( I i ) i 1 N (I_i)^N_{i1} (Ii​)i1N​&#xff0c;观察相同 3D 场景。 VGGT 的 Transformer 是一个映射函数&#xff0c;将此序列映射为一组对应的 3D 标注&#xff0c; f ( …