自动计算正文偏移量。 逻辑优化: 1. 先随机取 5 页。 2. 统计众数,若众数数量 < 4,则再随机取 5 页(不重复),共 10 页一起统计。 3. 将所有过程的图片、原始响应、解析结果保存到 initial_data/offset_log.json。
(pdf_path: str, client: AsyncOpenAI, model: str, initial_data_dir: str)
| 559 | 2. 统计众数,若众数数量 < 4,则再随机取 5 页(不重复),共 10 页一起统计。 |
| 560 | 3. 将所有过程的图片、原始响应、解析结果保存到 initial_data/offset_log.json。 |
| 561 | """ |
| 562 | log_entries = [] |
| 563 | try: |
| 564 | doc = fitz.open(pdf_path) |
| 565 | total_pages = len(doc) |
| 566 | start_idx = int(total_pages * 0.2) |
| 567 | end_idx = int(total_pages * 0.8) |
| 568 | if end_idx <= start_idx: |
| 569 | end_idx = total_pages - 1 |
| 570 | start_idx = 0 |
| 571 | |
| 572 | pool = list(range(start_idx, end_idx + 1)) |
| 573 | if len(pool) < 5: |
| 574 | doc.close() |
| 575 | return None |
| 576 | |
| 577 | # 第一轮:取 5 页 |
| 578 | selected_pages_1 = random.sample(pool, 5) |
| 579 | remaining_pool = [p for p in pool if p not in selected_pages_1] |
| 580 | |
| 581 | all_selected_indices = selected_pages_1[:] |
| 582 | |
| 583 | # 如果需要第二轮 |
| 584 | need_second_round = False |
| 585 | |
| 586 | # 临时存储第一轮结果用于判断 |
| 587 | first_round_results = [] |
| 588 | |
| 589 | # 定义目标长边像素 |
| 590 | TARGET_LONG_EDGE = 1500 |
| 591 | |
| 592 | for p in selected_pages_1: |
| 593 | page = doc[p] |
| 594 | rect = page.rect |
| 595 | max_dim = max(rect.width, rect.height) |
| 596 | |
| 597 | # 修正逻辑:始终计算缩放比例 |
| 598 | if max_dim == 0: |
| 599 | continue |
| 600 | zoom = TARGET_LONG_EDGE / max_dim |
| 601 | |
| 602 | mat = fitz.Matrix(zoom, zoom) |
| 603 | pix = page.get_pixmap(matrix=mat) |
| 604 | img_data = pix.tobytes("jpeg") |
| 605 | base64_image = base64.b64encode(img_data).decode('utf-8') |
| 606 | |
| 607 | raw_res = await fetch_single_offset(client, model, p + 1, base64_image) |
| 608 | |
| 609 | # 记录日志数据 |
| 610 | entry = { |
| 611 | "physical_page": p + 1, |
| 612 | "raw_response": raw_res, |
| 613 | "parsed_offset": None, |
| 614 | "image_base64_preview": base64_image[:100] + "..." # 仅存预览,避免 JSON 过大,实际图片可单独存如需 |
| 615 | } |
| 616 | |
| 617 | if raw_res.isdigit() or (raw_res.startswith('-') and raw_res[1:].isdigit()): |
| 618 | val = int(raw_res) |
no test coverage detected