
简介一份围绕环境议题整理的香港大学面试问答PDF面向备战港大本科面试及英文面试的考生可快速积累环境类题目的观点与表达。内容以环境污染为主线覆盖对污染现状的英文描述、城市减少污染的具体措施、发达国家向发展中国家转移垃圾的利弊讨论并延伸至低碳生活与节能建议每题均含中英对照参考回答。预览中详细梳理了地表水富营养化、空气质量下降、近海赤潮、垃圾围城等现实问题并给出可背诵的英文句型方便临场组织语言。回答中嵌入2011年污染损失超2万亿元、GDP占比超6%等数据及“开宝马喝污水”等经典表述可直接作为论证支撑。资源为单个PDF文件大小84KB内容紧凑便于打印和考前速览。已有469人学习下载题目覆盖典型适合考前一周突击使用也可作为面试口语模板与答题逻辑参考。1. 拿到一份面试题PDF先别急着双击打印遇到一份“香港大学面试题(三)打印.pdf”这种以“打印”命名的PDF很多人第一反应是直接CtrlP然后发现页面里有底色打印出来一片黑或者从浏览器打开复制粘贴全是乱码又或者这是一份扫描图片文字根本选不中。我处理过不少这类来源不一的PDF它们往往不是干净的“文字版”而是混合了嵌入字体、扫描图像、甚至加密权限的复杂文档。这篇博文就以这类面试题PDF为案例走一遍PDF解析、文本提取、虚拟打印、OCR识别、格式转换和打印优化的完整流程每一步给出现成可用的命令和参数既能应急也能放入日常文档处理工具箱。2. PDF文本提取从pdfplumber到pdftotext的取舍处理PDF的第一步是搞清楚它到底是不是文字版。用pdfplumber打开如果提取出的文本是完整的说明是原生文字PDF如果提取出来是空或乱码说明可能是扫描版。下面从两个角度讲提取方案。2.1 用pdfplumber提取段落与表格pdfplumber是目前处理文本型PDF最顺手的Python库它对坐标、表格和字符间距的支持比PyPDF2好得多。以下代码可以提取每一页的文字块import pdfplumber with pdfplumber.open(hk_interview.pdf) as pdf: for i, page in enumerate(pdf.pages): text page.extract_text() or # 按行输出便于后续对比 print(f--- Page {i1} ---) print(text) # 如果有表格结构可以单独提取 tables page.extract_tables() if tables: print(fFound {len(tables)} table(s))这段代码的逻辑是依次打开每一页调用extract_text()从页面对象中抽取文本层空页面会返回None所以加了一个or 兜底。extract_tables()是pdfplumber的特色它基于线条和字符位置还原表格比直接正则匹配更可靠。参数说明pdf.pages是页面对象列表PDF页码从0开始extract_text()可以传layoutTrue参数用于保留相对版面处理双栏文档时很有用。如果发现提取出的文本顺序错乱通常是因为PDF的文本流不是按阅读顺序写入的此时可以把layoutFalse默认模式改成layoutTrue再试。2.2 处理CID字体导致的乱码很多从在线打印服务生成的PDF用的是子集化CID字体直接提取会得到一堆类似\x00\x01的乱码。这时候换用PyMuPDFfitz往往能直接拿到正确Unicodeimport fitz # PyMuPDF doc fitz.open(hk_interview.pdf) for page_num in range(doc.page_count): page doc.load_page(page_num) text page.get_text(text) print(text)PyMuPDF内部有自己的字体解码器对CID字体的兼容性比pdfplumber好。如果仍然乱码可以在get_text()中指定sortTrue让文本按阅读顺序排序dict模式可以拿到每个字符的字体信息用于定位是哪个字体出了问题。提示遇到乱码不要急着换库先看是不是字体子集问题。用page.get_fonts()查看页面字体列表如果看到CIDFontType0或Type0字样基本就是CID字体PyMuPDF的成功率更高。2.3 命令行方案pdftotext与pdftoppm如果不想写Python代码系统装了Poppler工具的话直接用命令行更快。Poppler是Linux下常用的PDF渲染工具集Windows需要自己编译或下载预编译包macOS可用brew install poppler。# 提取文本到txt文件保留布局 pdftotext -layout hk_interview.pdf hk_interview.txt # 查看第一页内容 head -50 hk_interview.txt # 如果PDF有密码输入密码后转图片 pdftoppm -png -r 150 -f 1 -l 1 hk_interview.pdf page1pdftotext -layout保留换行和缩进适合面试题这种问答结构的文档-r 150指定渲染分辨率150dpi-f 1 -l 1表示只转换第一页。对于扫描版pdftotext返回空这时候就需要走第4章的OCR流程。三种文本提取方案的核心区别可以看这张表工具适合场景输出形式关键参数pdfplumber文本型PDF、表格提取文本、表格、坐标layoutTruePyMuPDFCID字体乱码、页面级操作文本、图片、页面对象get_text(dict)、sortTruepdftotext批量处理、无Python环境纯文本文件-layout、-f -l3. 虚拟打印用Microsoft Print to PDF解决打印乱码与页面异常PDF文件有时会被设计成“只可打印不可复制”或者字体未嵌入导致打印时替换成默认字体、出现方块。这时候把PDF“打印”成另一份PDF既能去掉权限限制又能强制嵌入字体。这在Windows上直接用内置的Microsoft Print to PDF驱动就能做。3.1 手工操作从任意程序打印到PDF用Edge或Chrome打开PDF按CtrlP在“目标打印机”里选择“Microsoft Print to PDF”然后在“打印”对话框里可以设置纸张大小、页边距和缩放百分比。关键参数是“缩放”默认100%如果内容过宽可选择“适应打印页面”如果想节省纸张可以选“每张纸打印2页”或“4页”。这一步会把原PDF重新光栅化并编码为新的PDF新文件中很多权限限制会丢失字体也会以嵌入形式保留。实际工作中我经常用这个操作来处理那些在排版软件里生成的“佯装打印”文件。3.2 用命令行控制虚拟打印Microsoft Print to PDF的自动化Windows上可以用PowerShell调用原生打印接口把任意文件送往虚拟打印机生成PDF。以下脚本用于批量打印多个文件到PDF$printers Get-Printer -Name Microsoft Print to PDF if (-not $printers) { Write-Error 未找到Microsoft Print to PDF请先在控制面板中启用该功能 exit 1 } $word New-Object -ComObject Word.Application $word.Visible $false Get-ChildItem C:\interview_questions\*.pdf | ForEach-Object { $doc $word.Documents.Open($_.FullName) $outName $_.BaseName _printed.pdf $doc.PrintOut([ref]$false, [ref]$false, [ref]0, [ref]$outName, [ref]1) $doc.Close() } $word.Quit()逻辑说明先检查系统是否安装了Microsoft Print to PDF驱动没有则报错退出然后通过Word COM对象打开每个PDFWord能显示PDF调用PrintOut方法参数含义分别是背景打印、不显示对话框、页码范围0表示全部、输出文件名、是否打印到文件1为是。最后关闭Word释放COM资源。这个脚本适合批量处理几十份同类PDF比手动一个个打印高效得多。注意Word打开PDF时会转换格式如果原PDF是扫描图片打印出的PDF仍然只有图片不会变成文字。若想同时获得文本层应该使用第4章的OCR方法。3.3 深入虚拟打印的DPI与颜色管理Microsoft Print to PDF默认输出质量取决于当前驱动设置。在“打印机属性”-“高级”里可以看到“打印质量”选项如600x600 DPI。对于文字文档300 DPI就够了图片多可以调到600。调高DPI会增加PDF体积但清晰度不一定线性提升。如果你要长期处理面试题这类纯文字文档建议保持默认300 DPI打印速度与文件体积更均衡。提示Microsoft Print to PDF生成的PDF一般没有书签目录如果原PDF有目录结构打印后目录会丢失。这时优先用后续的编程方式重建。4. 扫描版PDF用Tesseract把图片变成可搜索文本如果这份面试题PDF是别人扫描后合集的那么任何文本提取工具都拿不到内容。这时候只能走OCR。目标是把每一页渲染成图片再用OCR引擎识别文字最后生成带文本层的PDF。4.1 渲染图片pdf2image与Poppler先将PDF转成高分辨率PNG这一步用pdf2image库封装Popplerfrom pdf2image import convert_from_path images convert_from_path( hk_interview_scan.pdf, dpi300, fmtpng, output_folderocr_pages, first_page1, last_page10 ) print(fConverted {len(images)} pages)参数说明dpi300是OCR的基准分辨率低于200会丢失细节高于400会拖慢速度fmtpng确保无损output_folder指定图片输出目录first_page和last_page可以只转换需要的页面用于快速测试。这里要注意pdf2image需要系统安装PopplerWindows用户需将bin目录添加到PATH环境变量。4.2 中英文混合OCRTesseract语言包与参数Tesseract是目前开源免费OCR里对中英文混合支持较好的引擎。安装后需要下载中文语言包Windows/Linux都可以在GitHub的tessdata仓库获取chi_sim.traineddata放到tesseract安装目录的tessdata下。# 识别第一页指定中英文两种语言 tesseract ocr_pages/1.png page1_text -l chi_simeng --psm 3 # 输出文本文件查看 cat page1_text.txt-l chi_simeng表示同时加载简体中文和英文语言包加号表示并行识别--psm 3是页面分割模式3代表全自动不做任何版面假设。对于面试题这种段落清晰的文档还可以试--psm 6统一文本块或--psm 4单列多段各有优劣。如果识别结果中英文字母混在一起可以在调用时增加白名单参数tesseract ocr_pages/1.png out -l chi_simeng --psm 3 -c tessedit_char_whitelistABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.!? -c tessedit_char_whitelist强制只识别指定的字符集能有效过滤噪声但也会误伤中文所以只适合纯英文或代码场景。面试题是中文为主不建议加白名单而应该用默认全字符。4.3 用OCR结果重建可搜索PDFOCR识别出的文本要和原稿图片合并成新的PDF方便检索和复制。可以用img2pdf把图片打包成PDF再用pypdf在每页图片上叠加透明文本层。另一种更省事的方式是使用ocrmypdf它把Tesseract的OCR结果直接内嵌到原PDF里ocrmypdf --language chi_simeng --deskew --optimize 1 \ hk_interview_scan.pdf hk_interview_searchable.pdf参数说明--deskew自动矫正歪斜页面--optimize 1表示轻度压缩输出PDF每一页都有隐藏文本层CtrlF可以搜索复制粘贴也是正常的文字。这是处理扫描面试题PDF的最终方案一步到位。5. PDF格式转换与批量拆分把面试题按主题拆成独立文件拿到一份几十页的面试题PDF往往需要按章节拆开给不同的人看或者转成Word做二次编辑。这里给出两个实用操作用pdf2docx转Word用PyMuPDF按页码范围拆分。5.1 pdf2docx保留版面的转Word方案pdf2docx是国内开源的优秀库它根据PDF中的文字块坐标重建Word文档结构对标准版式PDF还原度很高。from pdf2docx import Converter cv Converter(hk_interview.pdf) cv.convert(hk_interview.docx, start0, end-1) cv.close()start和end参数指定转换的页码范围-1表示到末尾。转换时如果原PDF有页眉页脚默认会作为段落流入Word可以在convert()之前设置cv.enable_markdown(False)关闭markdown语法解析避免特殊字符被误转。注意pdf2docx依赖PyMuPDF如果原PDF是扫描版转出来的Word只是一页一张图片没有文字。所以扫描版必须先做第4章的OCR可搜索化再转Word。5.2 按主题标签拆分页面面试题PDF通常每个主题占据若干页我们可以先提取文本再用关键词定位页号最后按页号范围拆分。以下脚本把“五、环境”到“六、科技”之间的页面拆出来import fitz doc fitz.open(hk_interview.pdf) start_page None end_page None for i in range(doc.page_count): text doc.load_page(i).get_text() if 五、环境 in text and start_page is None: start_page i if 六、科技 in text: end_page i break if start_page is not None and end_page is not None: new_doc fitz.open() for j in range(start_page, end_page): new_doc.insert_pdf(doc, from_pagej, to_pagej) new_doc.save(environment_section.pdf) print(fSaved pages {start_page1} to {end_page}) else: print(未找到关键词请检查文本中是否包含空格)逻辑是遍历每页文本找到“五、环境”出现的第一个页作为起始页找到“六、科技”出现的页作为结束页然后用insert_pdf把这段页码插入新文档。这里有个坑如果某一页里既有环境结尾又有科技开头end_page会等于start_page导致拆出空文档。解决办法是要求end_page start_page并且用if 六、科技 in text and i start_page来限定。5.3 批量重命名与归档拆出来的文件建议按主题自动重命名。可以在同一脚本中提取每章的第一个标题作为文件名import re section_titles [] for i in range(doc.page_count): text doc.load_page(i).get_text() # 匹配“五、环境”“六、科技”之类的小标题 for m in re.finditer(r[一二三四五六七八九十]、[\u4e00-\u9fa5A-Za-z0-9], text): if len(m.group()) 20: section_titles.append((i, m.group()))re.finditer会按页返回所有匹配到的小标题len(m.group()) 20是为了过滤掉正文里的长句误匹配。拿到(页号, 标题)列表后就可以在保存拆分文件时直接用标题命名避免手工改名。6. 打印优化用Ghostscript压缩PDF与页边距控制最后分享一个针对“打印”场景的技巧。PDF直接打印经常会遇到体积过大、打印慢、或页面缩放导致文字过小的问题。用Ghostscript可以快速压缩、合并PDF同时控制分辨率。6.1 Ghostscript压缩命令gs -sDEVICEpdfwrite -dCompatibilityLevel1.5 \ -dPDFSETTINGS/ebook -dNOPAUSE -dBATCH \ -dQUIET -sOutputFilecompressed.pdf input.pdf-dPDFSETTINGS/ebook表示按电子书质量压缩图像分辨率降为150dpi适合打印草稿如果要更高质量用/printer保持300dpi。-dCompatibilityLevel1.5生成 PDF 1.5 格式兼容性好。如果只需要打印其中某几页可以在输入文件名前加-dFirstPage3 -dLastPage5gs -sDEVICEpdfwrite -dFirstPage3 -dLastPage5 \ -dPDFSETTINGS/printer -sOutputFilepages_3_5.pdf input.pdf6.2 打印页边距调整有些PDF默认页边距很小打印出来文字贴近纸张边缘。Ghostscript不能直接设置页边距但可以用pdfjam或psutil。Linux下常用的pdfjam命令pdfjam --paper a4paper --margin 1cm 1.5cm 1cm 1.5cm \ --outfile margin_1cm.pdf input.pdf--margin四个值分别表示上、右、下、左边距单位可以是cm、mm或pt。pdfjam本质上是调用了pdfpagesLaTeX宏包如果系统没有LaTeX环境可以用Python的PyPDF2添加裁剪框模拟边距from pypdf import PdfReader, PdfWriter reader PdfReader(input.pdf) writer PdfWriter() for page in reader.pages: page.cropbox.lower_left (72, 72) # 左边距1英寸 page.cropbox.upper_right (page.mediabox.upper_right[0] - 72, page.mediabox.upper_right[1] - 72) writer.add_page(page) with open(margin.pdf, wb) as f: writer.write(f)这段代码将每一页的显示区域缩小1英寸打印时内容会整体内缩。不过裁剪后字体大小不变只是可见区域变小如果原页面本身内容紧凑裁剪会截掉边缘文字。要正确处理边距应该重新排版这就超出PDF库的范围了日常应急用Ghostscript的-dDEVICEWIDTHPOINTS和-dDEVICEHEIGHTPOINTS直接设置输出页面尺寸再把内容缩放居中但过程比较繁琐还是用Word或LaTeX重排更稳妥。验证打印效果的方法很简单把压缩后的PDF用PDF阅读器打开按实际尺寸显示用空格键快速翻页看是否有乱码和丢字再用尺子量一下A4纸上的页边距和预期对标一遍。最后用pdfinfo检查页面大小和文件大小确认输出参数与预期一致。本文还有配套的精品资源点击获取