feat(extractor): Add Excel conversion and post-processing capabilities
Add comprehensive post-processing features to convert downloaded Excel files into structured data and merge them into a single output file. New modules: - extractor_core.py: Stateless pure functions for web operations - excel_converter.py: Excel to DataFrame conversion utility - tests/test_extractor_real.py: Real data extraction test suite Enhanced features: - post_process_downloads(): Convert and merge multiple Excel files - extract_and_process(): Complete workflow in single call - cleanup_temp_files(): Optional cleanup of temporary downloaded files - Field name mapping for standardized output columns Dependencies: - pandas>=2.0.0 for data manipulation - openpyxl>=3.1.0 for Excel file handling Documentation: - Updated CLAUDE.md with new module references - Added API documentation for extractor components Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -144,6 +144,7 @@ def post_process_downloads(
|
||||
downloaded_files: List[str],
|
||||
output_file: str,
|
||||
verbose: bool = True,
|
||||
cleanup_temp_files: bool = True,
|
||||
) -> Tuple[str, pd.DataFrame]:
|
||||
"""
|
||||
Convert and merge downloaded Excel files into structured DataFrame.
|
||||
@@ -154,6 +155,7 @@ def post_process_downloads(
|
||||
downloaded_files: List of paths to downloaded Excel files
|
||||
output_file: Path to save merged Excel result
|
||||
verbose: Whether to print progress messages
|
||||
cleanup_temp_files: Whether to delete temporary downloaded files after processing (default: True)
|
||||
|
||||
Returns:
|
||||
Tuple of (output_file_path, merged_dataframe)
|
||||
@@ -162,7 +164,8 @@ def post_process_downloads(
|
||||
>>> output_path, df = post_process_downloads(
|
||||
... downloaded_files=["batch_1.xlsx", "batch_2.xlsx"],
|
||||
... output_file="merged.xlsx",
|
||||
... verbose=True
|
||||
... verbose=True,
|
||||
... cleanup_temp_files=True
|
||||
... )
|
||||
"""
|
||||
from .excel_converter import ExcelConverter
|
||||
@@ -194,9 +197,37 @@ def post_process_downloads(
|
||||
print(f"Merged result saved to: {output_path}")
|
||||
print(f"Total rows: {len(merged_df)}")
|
||||
|
||||
# Cleanup temporary downloaded files
|
||||
if cleanup_temp_files:
|
||||
_cleanup_temp_files(downloaded_files, verbose)
|
||||
|
||||
return str(output_path), merged_df
|
||||
|
||||
|
||||
def _cleanup_temp_files(downloaded_files: List[str], verbose: bool = True) -> int:
|
||||
"""
|
||||
Remove temporary downloaded files.
|
||||
|
||||
Args:
|
||||
downloaded_files: List of file paths to delete
|
||||
verbose: Whether to print progress messages
|
||||
|
||||
Returns:
|
||||
Number of files successfully deleted
|
||||
"""
|
||||
deleted_count = 0
|
||||
for file_path in downloaded_files:
|
||||
try:
|
||||
Path(file_path).unlink()
|
||||
deleted_count += 1
|
||||
if verbose:
|
||||
print(f"Deleted temp file: {file_path}")
|
||||
except Exception as e:
|
||||
if verbose:
|
||||
print(f"Warning: Could not delete {file_path}: {e}")
|
||||
return deleted_count
|
||||
|
||||
|
||||
def extract_and_post_process(
|
||||
work_frame: Frame,
|
||||
page: Page,
|
||||
@@ -205,6 +236,7 @@ def extract_and_post_process(
|
||||
output_file: str,
|
||||
batch_size: int = 10,
|
||||
verbose: bool = True,
|
||||
cleanup_temp_files: bool = True,
|
||||
) -> Tuple[str, pd.DataFrame]:
|
||||
"""
|
||||
Complete extraction workflow: download batches + post-process to merged Excel.
|
||||
@@ -220,6 +252,7 @@ def extract_and_post_process(
|
||||
output_file: Path for final merged Excel output
|
||||
batch_size: Maximum order IDs per batch
|
||||
verbose: Whether to print progress messages
|
||||
cleanup_temp_files: Whether to delete temporary downloaded files after processing (default: True)
|
||||
|
||||
Returns:
|
||||
Tuple of (output_file_path, merged_dataframe)
|
||||
@@ -229,7 +262,8 @@ def extract_and_post_process(
|
||||
>>> browser, context, page, main_frame = login(...)
|
||||
>>> work_frame, page1 = navigate_to_discrete_material_page(main_frame, page)
|
||||
>>> output_path, df = extract_and_post_process(
|
||||
... work_frame, page1, order_ids, "/downloads", "output.xlsx"
|
||||
... work_frame, page1, order_ids, "/downloads", "output.xlsx",
|
||||
... cleanup_temp_files=True
|
||||
... )
|
||||
>>> context.close()
|
||||
>>> browser.close()
|
||||
@@ -254,6 +288,7 @@ def extract_and_post_process(
|
||||
downloaded_files=downloaded_files,
|
||||
output_file=output_file,
|
||||
verbose=verbose,
|
||||
cleanup_temp_files=cleanup_temp_files,
|
||||
)
|
||||
|
||||
return output_path, merged_df
|
||||
@@ -292,6 +327,7 @@ def extract_from_file(
|
||||
output_file: str,
|
||||
batch_size: int = 10,
|
||||
verbose: bool = True,
|
||||
cleanup_temp_files: bool = True,
|
||||
) -> Tuple[str, pd.DataFrame]:
|
||||
"""
|
||||
Extract data from order IDs in a file and post-process to merged Excel.
|
||||
@@ -306,6 +342,7 @@ def extract_from_file(
|
||||
output_file: Path for final merged Excel output
|
||||
batch_size: Maximum order IDs per batch
|
||||
verbose: Whether to print progress messages
|
||||
cleanup_temp_files: Whether to delete temporary downloaded files after processing (default: True)
|
||||
|
||||
Returns:
|
||||
Tuple of (output_file_path, merged_dataframe)
|
||||
@@ -315,7 +352,8 @@ def extract_from_file(
|
||||
>>> order_ids = read_order_ids_from_file("orders.txt")
|
||||
>>> # Extract and process
|
||||
>>> output_path, df = extract_from_file(
|
||||
... "orders.txt", work_frame, page, "/downloads", "output.xlsx"
|
||||
... "orders.txt", work_frame, page, "/downloads", "output.xlsx",
|
||||
... cleanup_temp_files=True
|
||||
... )
|
||||
"""
|
||||
order_ids = read_order_ids_from_file(id_file)
|
||||
@@ -331,4 +369,5 @@ def extract_from_file(
|
||||
output_file=output_file,
|
||||
batch_size=batch_size,
|
||||
verbose=verbose,
|
||||
cleanup_temp_files=cleanup_temp_files,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user