You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需使用search_for(),如何用PyMuPDF获取PDF文本坐标并高亮?

无需使用search_for()的PyMuPDF精准文本高亮方案

针对search_for()忽略空格、大小写及仅支持ASCII的问题,可通过直接解析页面文本的字符/单词坐标来实现精准高亮,以下是两种可行方案:

方法1:逐字符解析定位

利用page.get_text("chars")获取每个字符的坐标和内容,通过拼接字符匹配目标文本,再计算目标文本的整体包围矩形实现高亮。

示例代码

import fitz

def highlight_exact_text(page, target_text):
    chars = page.get_text("chars")  # 获取所有字符的坐标与内容,格式:(x0,y0,x1,y1,char, ...)
    current_text = ""
    target_len = len(target_text)

    for idx, char_info in enumerate(chars):
        current_text += char_info[4]
        # 匹配到目标文本时计算高亮区域
        if current_text.endswith(target_text):
            # 提取目标文本对应字符的坐标
            start_idx = idx - target_len + 1
            target_chars = chars[start_idx:idx+1]
            # 生成包围矩形
            rect = fitz.Rect(
                min(c[0] for c in target_chars),
                min(c[1] for c in target_chars),
                max(c[2] for c in target_chars),
                max(c[3] for c in target_chars)
            )
            page.add_highlight_annot(rect)
            # 重置当前文本,避免重复匹配(需多次匹配可调整逻辑)
            current_text = ""
        # 文本长度超过目标时,截断头部继续匹配
        elif len(current_text) > target_len:
            current_text = current_text[1:]

# 使用示例
doc = fitz.open("input.pdf")
target = "需要精准匹配的带空格、中文的语句"
for page in doc:
    highlight_exact_text(page, target)
doc.save("output_highlighted.pdf")

方法2:基于单词序列匹配

如果目标文本是由多个单词组成的短语,可通过page.get_text("words")获取单词坐标,匹配连续单词序列来定位高亮区域。

示例代码

import fitz

def highlight_exact_phrase(page, target_phrase):
    words = page.get_text("words")  # 获取所有单词的坐标与内容,格式:(x0,y0,x1,y1,word, ...)
    target_words = target_phrase.split()
    target_word_count = len(target_words)
    total_words = len(words)

    for i in range(total_words - target_word_count + 1):
        # 拼接连续单词,匹配目标短语
        current_phrase = " ".join([words[i+j][4] for j in range(target_word_count)])
        if current_phrase == target_phrase:
            # 计算单词序列的包围矩形
            rect = fitz.Rect(
                min(words[i+j][0] for j in range(target_word_count)),
                min(words[i+j][1] for j in range(target_word_count)),
                max(words[i+j][2] for j in range(target_word_count)),
                max(words[i+j][3] for j in range(target_word_count))
            )
            page.add_highlight_annot(rect)

# 使用示例
doc = fitz.open("input.pdf")
target = "Hello World 带空格的英文+中文短语"
for page in doc:
    highlight_exact_phrase(page, target)
doc.save("output_highlighted_words.pdf")

关键说明

  • 两种方法均保留原始文本的空格、大小写和非ASCII字符,完全匹配目标内容
  • 若目标文本跨多行或多个文本块,需调整代码逻辑处理跨块匹配(比如在逐字符方案中,不重置current_text,而是继续拼接后续块的字符)
  • 复杂排版PDF(分栏、文本框)推荐使用逐字符方案,鲁棒性更强

内容的提问来源于stack exchange,提问作者user34088

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:05:23