使用WeasyPrint导出PDF无法正常显示原网页大部分内容如何修复
WeasyPrint 生成市政数据PDF显示异常的修复方案
核心问题定位
现有代码的逻辑存在硬伤,直接导致PDF渲染不全:
- 你在Selenium中完成页面打开、「过去30天」筛选点击、动态内容加载的全流程后,没有把Selenium端已经渲染完毕的完整DOM内容传给WeasyPrint,反而让WeasyPrint直接请求原始站点URL
- WeasyPrint是纯静态渲染工具,本身不执行JavaScript逻辑,独立请求原始URL时,既拿不到你点击筛选后生成的动态表格数据,也无法抓取站点通过JS动态加载的页面元素,最终就会出现PDF里大部分内容空白的问题
- 额外的干扰因素:WeasyPrint独立发起请求时,受站点反爬规则、静态资源跨域限制影响,会出现CSS样式、图片资源加载失败的问题,进一步加剧排版错乱
分步修复实现
1. 核心逻辑调整:传递Selenium渲染后的完整DOM给WeasyPrint
不要让WeasyPrint自行发起URL请求,直接从Selenium实例中提取经过交互、动态加载完成的完整页面源码,同时带上页面的基础URL解决相对路径资源加载问题:
from classes.main import * import weasyprint import datetime from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By url = "https://www.dnv.org/property-development/look-building-and-trades-permits" with Display(visible=False, size=(1200,1500)): print("display initiated") browser.get(url) print("browser loaded") # 等待页面核心元素加载完成 WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.ID, "main-content"))) print("Page loaded") # 执行过去30天筛选交互 browser.find_element(By.XPATH, '//*[@id="lastcalendardays"]').click() # 替换固定sleep,用显式等待判断目标表格完全渲染 WebDriverWait(browser, 10).until( EC.presence_of_element_located((By.XPATH, "//*[contains(text(), 'Permits Issued in the past 30 days')]/following::table[1]")) ) sleep(1) # 提取当前已渲染完成的完整HTML源码 rendered_html = browser.page_source current_base_url = browser.current_url # 处理文件名中的非法字符 current_time = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S") save_path = f'/bm/data/{current_time} - northvandistrict.pdf' # 生成PDF,传入基础URL解决静态资源路径问题,追加适配PDF的自定义样式 pdf = weasyprint.HTML( string=rendered_html, base_url=current_base_url ).write_pdf( stylesheets=[weasyprint.CSS(string=""" body {width: 1200px; margin: 0; padding: 10px;} /* 强制表格适配PDF宽度,避免内容溢出裁切 */ table {width: 100% !important; page-break-inside: avoid; border-collapse: collapse;} /* 隐藏PDF中不需要的交互类元素,减少排版干扰 */ .site-navigation, .filter-controls, .site-footer {display: none;} """)] ) with open(save_path, 'wb') as f: f.write(pdf) print("PDF生成完成") browser.quit()
2. 常见残留异常的补充处理
- 如果仍出现表格内容空白:可在提取DOM前执行JS代码强制触发页面懒加载,确保所有表格行元素都渲染到DOM树中
- 如果出现CSS样式错乱:可在生成PDF前,提取页面加载完成的所有外链、内联CSS资源,统一传入WeasyPrint的
stylesheets参数,避免资源加载失败 - 等待逻辑优化:全程使用显式等待判断目标元素加载状态,替代固定时长的
sleep,避免因页面加载速度波动提取到不完整的DOM
内容的提问来源于stack exchange,提问作者decoy24601
相关产品推荐
相关产品推荐

