从SharePoint Excel提取数据至DataFrame:优化与行跳过方案
核心优化点与解决方案
一、效率优化
- 复用HTTP连接:使用
requests.Session代替单次请求,减少TCP握手和连接建立的开销,大幅提升批量请求速度。 - 并发请求处理:利用
concurrent.futures.ThreadPoolExecutor实现多线程并发请求,针对IO密集型的网络操作,能显著缩短总耗时。 - 减少API调用次数:直接通过索引定位第一个工作表(
worksheets(0)),无需单独请求工作表列表接口,每个文件少一次API调用。
二、跳过前3-4行实现
根据需求调整数据切片的起始索引:
- 假设前3行是冗余内容,第4行(索引3)为表头,第5行(索引4)开始为有效数据:用
file_response[3]作为列名,file_response[4:]作为数据行。 - 可通过参数化跳过行数,方便后续调整。
优化后完整代码
import requests import pandas as pd from concurrent.futures import ThreadPoolExecutor, as_completed HEADERS = "" SITE_ID = "" DRIVE_ID = "" SHAREPOINT_PATH = "" # 可根据实际情况调整跳过的行数(比如跳过前3行,表头在第4行则设置为3) SKIP_ROWS = 3 # 如果不需要指定固定range,可考虑用'usedRange'自动获取有效范围 RANGE_TO_READ = "" def process_file(session, file_item): file_id = file_item['id'] file_name = file_item['name'] if not file_name.endswith('.xlsx'): return None # 直接通过索引0定位第一个工作表,省去单独请求工作表列表的API调用 download_url = f"https://graph.microsoft.com/v1.0/drives/{DRIVE_ID}/items/{file_id}/workbook/worksheets(0)/range(address='{RANGE_TO_READ}')" try: file_response = session.get(download_url) file_response.raise_for_status() # 抛出HTTP错误 data = file_response.json()['values'] # 跳过指定行数,提取表头和数据 if len(data) <= SKIP_ROWS: print(f"文件 {file_name} 数据不足,跳过") return None headers = data[SKIP_ROWS] rows = data[SKIP_ROWS + 1:] df = pd.DataFrame(rows, columns=headers) df.columns = df.columns.map(lambda x: x.lower().strip()) return df except Exception as e: print(f"处理文件 {file_name} 出错: {str(e)}") return None def extract_from_sharepoint_(): # 创建Session复用连接 with requests.Session() as session: session.headers.update(HEADERS) folder_items_url = f"https://graph.microsoft.com/v1.0/sites/{SITE_ID}/drives/{DRIVE_ID}/root:/{SHAREPOINT_PATH}:/children" folder_items = session.get(folder_items_url).json().get('value', []) dataframes = [] # 多线程并发处理,可根据网络情况调整max_workers with ThreadPoolExecutor(max_workers=10) as executor: futures = [executor.submit(process_file, session, item) for item in folder_items] for future in as_completed(futures): result = future.result() if result is not None: dataframes.append(result) combined_df = pd.concat(dataframes, ignore_index=True) return combined_df
额外优化建议
- 如果Excel文件没有复杂公式或格式需求,可直接下载文件二进制内容,用
pd.read_excel读取,性能可能比Graph API的range接口更优:# 替换process_file中的下载逻辑 download_url = f"https://graph.microsoft.com/v1.0/drives/{DRIVE_ID}/items/{file_id}/content" file_response = session.get(download_url) df = pd.read_excel(file_response.content, skiprows=SKIP_ROWS) df.columns = df.columns.map(lambda x: x.lower().strip()) - 调整
max_workers参数:根据网络带宽和SharePoint的API限制,合理设置线程数(建议5-20之间),避免触发API限流。
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

