记录一次从https接口提取25G大文件csv并落表的经历

这里写自定义目录标题

背景

某日下班后,领导临时分配了一个任务,有一个https接口提供的csv格式数据,量级比较大,需要提取并落表,解析成结构化的数据,用于做一些数据分析。

业务方提供了几天的接口文件url,格式如下:https://*****file.csv,直接点击即进入浏览器下载状态,一个文件量级达二十多G,预计需要两个小时下载完成;

同时,业务方也提供了一些清洗及指标统计规则,但未提供数据原始字段格式。

尝试用python来解决问题

这个需求很明确,主要困难点在于数据量级非常大,用常规的下载后导入数仓的方式,已无法实现,所以寄希望于脚本工具,期望分批次下载导入数据表。

初步想法是,用司内封装好的notebook来写python脚本,实现脚本化的数据下载及写入。

首先,想到的是用pandas库里的数据处理模块,于是按如下脚本来实现:

python 复制代码
import pandas as pd
from sqlalchemy import create_engine
# 读取 CSV 文件
url = "https://*****file.csv"
data = pd.read_csv(url)
# 创建数据库连接(请替换为您的数据库连接信息)
db_url = "mysql+pymysql://username:password@host:port/database"  # 替换为您的 MySQL 连接信息
engine = create_engine(db_url)
# 将数据写入数据库(请替换为目标表名)
data.to_sql('target_table_name', con=engine, if_exists='replace', index=False)
print("数据成功入库!")

请确保安装了所需的库:

bash 复制代码
pip install pandas sqlalchemy pymysql

随之,又想到数据量过大,写到mysql可能会存在一些问题,于是想写到hive里。

python 复制代码
import pandas as pd
from pyhive import hive
# 读取 CSV 文件
url = "https://****file.csv"
data = pd.read_csv(url)
# Hive 连接参数
host = 'your_hive_host'
port = 10000  # Hive 默认端口
username = 'your_username'
database = 'your_database'
# 创建 Hive 连接
conn = hive.Connection(host=host, port=port, username=username, database=database)
# 写入数据到 Hive
table_name = 'your_table_name'
data.to_sql(table_name, con=conn, if_exists='replace', index=False)
print("数据成功入库!")

请将 your_hive_hostyour_usernameyour_databaseyour_table_name 替换为您的具体信息。

注意事项

  • 确保 Hive 服务正在运行,并且可以通过提供的连接参数访问。
  • Hive 表需要提前创建,或者可以使用 if_exists='replace' 创建新表。

接着,还需要创建一个表,用于写入数据,于是需要知道源头数据里的表结构,那么需要提取到数据后,能打印出几行来,这样就能知道源头数据的格式,于是加了一句:

python 复制代码
import pandas as pd
# 假设 df 是你的 DataFrame
df = pd.read_csv('your_data.csv')  # 读取数据
# 查看前十行
print(df.head(10))

以上,本以为问题就轻松解决了,没想到,报了如下错误:

URLError: <urlopen error [Errno 110] Connection timed out>

咨询了AI,得到答案如下:

可能的原因和解决方法包括:

  1. 网络问题:检查你的网络连接是否正常。

  2. URL错误:确认URL地址是否正确。

  3. 服务器问题:目标服务器可能出现故障或正在维护。

  4. 防火墙或代理:有可能是防火墙或代理阻止了连接,检查相关设置。

  5. 超时设置 :可以尝试增加超时时间,例如:

    python 复制代码
    import urllib.request
    url = 'http://example.com'
    response = urllib.request.urlopen(url, timeout=10)  # 设置超时为10秒
  6. 使用其他库 :如果问题持续,可以尝试使用requests库,它通常更易于处理HTTP请求:

    python 复制代码
    import requests
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()  # 检查请求是否成功
    except requests.exceptions.RequestException as e:
        print(e)

根据具体情况检查并调整相应的设置。

到这里,以为是由于资源不足导致的,毕竟刚开始运行,并没有做任何特殊的资源配置,而平台对普通python并没有提供资源配置选择的入口,但pyspark可以,于是切换到pyspark的资源,同时考虑了资源配置,脚本如下:

python 复制代码
from pyspark.sql import SparkSession
spark = SparkSession.builder \
    .appName("创建读取任务") \
    .config("spark.executor.memory", "16g") \
    .config("spark.driver.memory", "16g") \
    .config("spark.executor.instances", "8") \
    .config("spark.executor.cores", "4") \
    .config("spark.sql.shuffle.partitions", "100") \
    .config("spark.default.parallelism", "100") \
    .config("spark.sql.parquet.compression.codec", "snappy") \
    .getOrCreate()

# CSV 文件的 URL,Spark 和 Hadoop 默认不支持通过 `https` 访问文件。
url = "https://****file.csv"

# 读取 CSV 数据
df = spark.read.csv(url, header=True, inferSchema=True)
print("数据成功读取!")

# 显示数据
df.show()
# 关闭 Spark 会话
spark.stop()

配置参数说明:

  • spark.executor.memory:每个 executor 分配的内存大小。
  • spark.driver.memory:Driver 程序使用的内存。
  • spark.executor.instances:启动的 executor 数量。
  • spark.executor.cores:每个 executor 使用的 CPU 核心数。
  • spark.sql.shuffle.partitions:Shuffle 操作时使用的分区数,通常设置为较高值以提高并行度。
  • spark.default.parallelism:默认的并行度,用于某些操作的并行化。
  • spark.sql.parquet.compression.codec:指定 Parquet 文件的压缩方式,snappy 是一种常用的高效压缩格式。
    根据实际集群的资源情况和数据特点,适当调整这些参数。

依然读取报错,

TimeoutError: [Errno 110] Connection timed out

这时AI对报错的解释有所不同:

复制代码
这个错误是由于 Apache Spark 无法识别 `https` 协议的文件系统。Spark 和 Hadoop 默认不支持通过 `https` 访问文件。
解决方法:
1. **使用 `hdfs` 或 `file` 协议**:如果可能,尝试将文件移动到 HDFS 或本地文件系统中。
2. **添加支持**:如果需要通过 `https` 访问,可以尝试添加相应的 Hadoop 依赖,例如 `hadoop-aws`,并配置 AWS S3 等存储。
3. **配置 Spark**:确保在 Spark 的配置中正确设置了相关的文件系统类,例如在 `spark-defaults.conf` 中添加:
   ```plaintext
   spark.hadoop.fs.azure.NativeAzureFileSystem
4. **检查 URL**:确保提供的 URL 是有效的,并且服务器允许访问。
根据具体使用环境选择合适的方法进行调整。

于是,又切换回普通的python来运行,并且寄希望于在脚本里配置资源分配:

python 复制代码
要从 HTTPS 接口提取 100GB 的 CSV 数据,可以使用 Python 的 `requests` 库和 `pandas` 库。以下是一个基本的示例,展示了如何逐步下载和保存大文件:
```python
import requests
import pandas as pd
url = 'https://example.com/largefile.csv'  # 替换为实际的 URL
chunk_size = 1024 * 1024  # 每次下载 1MB
# 创建一个空的 DataFrame,用于存储数据
df = pd.DataFrame()
# 逐块下载数据
with requests.get(url, stream=True) as response:
    response.raise_for_status()  # 检查请求是否成功
    for chunk in response.iter_content(chunk_size=chunk_size):
        # 将每个块解码为字符串,然后再转换为 DataFrame
        chunk_data = pd.read_csv(pd.compat.StringIO(chunk.decode('utf-8')), header=None)
        df = pd.concat([df, chunk_data], ignore_index=True)
# 保存为 CSV 文件
df.to_csv('largefile.csv', index=False)

注意事项:
1. 确保服务器允许大文件下载。
2. 根据实际情况调整 `chunk_size` 以优化内存使用。
3. 处理 CSV 解析时,确保数据格式正确。
4. 如果 CSV 数据过大,考虑直接写入文件而不是加载到内存中。

此时的报错更明确了,依然是连接失败:

python 复制代码
MaxRetryError: HTTPSConnectionPool(host='*****.com', port=***): Max retries exceeded with url: ***file.csv (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at ***>, 'Connection to *****.com timed out. (connect timeout=None)'))

AI对此的解释是:

这个报错表示在尝试连接到指定的 HTTPS 服务器时,连接超时。可能的原因包括:

  1. 网络问题:无法访问互联网或目标服务器。
  2. 服务器故障:目标服务器可能已关闭或出现故障。
  3. 防火墙设置:防火墙可能阻止了该连接。
  4. URL 错误 :提供的 URL 可能不正确。
    建议检查网络连接,确认服务器是否在线,并验证 URL 的正确性。

至此,放弃用python来从该接口提取数据,考虑用其他方式。

非python方式解决

python 复制代码
要快速从 HTTPS 接口提取 25GB 的大文件,可以考虑以下方法:
1. **分块下载**:
   - 使用 `Range` 请求头分块下载文件。可以将文件分成多个部分并并行下载,然后在本地合并。
2. **多线程/多进程下载**:
   - 使用库(如 `requests` 和 `concurrent.futures`)创建多个线程或进程同时下载不同部分。
3. **使用专门的下载工具**:
   - 使用 `wget` 或 `curl` 等工具,支持断点续传和多线程下载。
4. **优化网络设置**:
   - 确保带宽没有被其他应用占用,使用有线连接而不是无线连接。
5. **检查服务器限制**:
   - 确保服务器允许大文件下载,检查是否有速率限制或并发连接限制。
6. **使用 CDN**:
   - 如果可能,使用内容分发网络 (CDN) 来提高下载速度。
示例代码(使用 `requests` 和分块下载):
```python
import requests
url = 'https://example.com/largefile'
response = requests.head(url)
file_size = int(response.headers['Content-Length'])
chunk_size = 1024 * 1024  # 1 MB
num_chunks = (file_size // chunk_size) + 1
with open('largefile', 'wb') as f:
    for i in range(num_chunks):
        headers = {'Range': f'bytes={i * chunk_size}-{(i + 1) * chunk_size - 1}'}
        chunk = requests.get(url, headers=headers)
        f.write(chunk.content)

根据具体情况调整参数和方法。

但,这个方案同样会遇到连接不上接口服务器的问题,所以放弃读取接口服务器。

发现,已经通过浏览器下载成功了一个csv文件,只是量级特别大,无法通过常规方式入数据库,所以接下来,只需要解决如何该大数据,写到表里。

如何用python读取本地文件,再写入到hive表中?

要将本地文件读取并写入到 Hive 表中,可以使用 PyHive 库或类似的库。以下是一个简单的示例,展示如何使用 Pandas 和 PyHive 将 CSV 文件读取到 Hive 表中。

首先,确保安装了必要的库:

bash 复制代码
pip install pandas pyhive

然后,可以使用以下代码:

python 复制代码
import pandas as pd
from pyhive import hive
# 读取本地文件
file_path = 'path/to/your/file.csv'
df = pd.read_csv(file_path)
# 连接到 Hive
conn = hive.Connection(host='your_hive_host', port=10000, username='your_username')
cursor = conn.cursor()
# 创建 Hive 表(如果尚未创建)
create_table_query = """
CREATE TABLE IF NOT EXISTS your_table_name (
    column1 STRING,
    column2 INT,
    ...
) 
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',' 
STORED AS TEXTFILE
"""
cursor.execute(create_table_query)
# 将数据写入 Hive 表
for index, row in df.iterrows():
    insert_query = f"""
    INSERT INTO your_table_name (column1, column2, ...)
    VALUES ('{row['column1']}', {row['column2']}, ...)
    """
    cursor.execute(insert_query)
# 关闭连接
cursor.close()
conn.close()

说明:
1. 替换 `file_path`、`your_hive_host`、`your_username`、`your_table_name` 和列名以符合你的实际情况。
2. 确保 Hive 表的结构与 CSV 文件的结构相匹配。
3. 如果数据量大,建议使用批量插入或更高效的方法。

最终解决方案

在寻找hive数据库的连接信息时,突然想到,为啥不直接舍弃python?

用终端命令行的方式,将大文件拆分为n个小文件,一个个小文件导入hive表中,如此简单直接,只是无法例行化了。

1、找到mac文件的文件url:

  • 打开Finder,找到文件或文件夹。
  • 右键点击文件或文件夹,选择"显示简介",在弹出的信息窗口中可以看到路径,选择并复制该路径,能得到具体的url。
    2、打开电脑自带的终端,输入:
    bash
    split -b 380m /Users/****file.csv newfile_prefix_
    3、开始执行后,就能在该文件链路里查到n个以"newfile_prefix_"开头的小文件了,其中380m,是根据导入文件限制,自行设置的小文件大小。

在进行实际导入前,还需要手动给每个小文件,加上文件后缀,比如csv、txt等,重命名文件名就可以实现。

未解决从https接口提取数据的问题,征集解法~~

相关推荐
喵手2 小时前
Python爬虫零基础入门【第三章:Requests 静态爬取入门·第1节】你的第一个爬虫:抓取页面并保存 HTML!
爬虫·python·爬虫实战·python爬虫工程化实战·requests静态爬取·抓取网页并保存html·零基础入门python爬虫
喵手2 小时前
Python爬虫零基础入门【第三章:Requests 静态爬取入门·第2节】伪装与会话:Headers、Session、Cookie(合规使用)!
爬虫·python·python爬虫实战·python爬虫工程化实战·requests静态爬取·伪装与会话·零基础python爬虫入门
lkbhua莱克瓦242 小时前
深入理解HTTP协议:从理论到SpringBoot实践
网络·笔记·后端·网络协议·http·javaweb
小白学大数据3 小时前
绕过拼多多 App 反抓包机制的综合逆向解决方案
开发语言·爬虫·python·自动化
使者大牙3 小时前
【单点知识】 Python装饰器介绍
开发语言·数据库·python
Jackson@ML3 小时前
2026最新版Sublime Text 4安装使用指南
java·python·编辑器·sublime text
TonyLee0173 小时前
半监督学习介绍
人工智能·python·深度学习·机器学习
kong79069283 小时前
Python核心语法-Python自定义模块、Python包
开发语言·python·python核心语法
OLOLOadsd1233 小时前
基于Mask-RCNN和RegNetX的茎蛀虫检测识别系统详解
python