起因
本来想爬取全国水雨情信息的数据的但是字体都加密了,很造蛋,哥爬不下来,哥很懊恼,哥很鲁莽的试了很多种解密方法,哥像个无能的丈夫失败了无数次。哥无奈想去海鲜市场找找大佬,发现海鲜小测佬们按条数出售数据,价格贵的离谱。哥没钱。
后面尝试纯视觉解析,发现可以搞,效果如下图(太长了部分截图),图片可以使用OCR进行识别整理然后入库(这里不做教程,网上一搜一大堆),完整代码放最后了
快速上手
拿到代码
- 安装依赖:
pip install selenium pillow
- 直接运行:
python main.py
- 跑完后你会在仓库根目录看到
table_expanded.png,这是整张表格的图片。
参数怎么填(就这仨)
url:目标网页地址,比如全国水雨情页面。table_id:表格在页面里的id,默认是hdtable。output_file:输出图片文件名,默认table_fullpage.png。
如果你想在自己的脚本里调用,示例如下:
from table_to_image import capture_with_full_page_method
url = "http://xxfb.mwr.cn/sq_djdh.html?v=1.0" # 目标网页地址(必须能直接访问)
table_id = "hdtable" # 表格的 ID(用浏览器开发者工具确认)
output_file = "table_expanded.png" # 输出图片名(PNG 格式)
# 一次性把完整表格截成图片
capture_with_full_page_method(url, table_id, output_file)
原理一眼看懂 )
- 把表格和它所有父元素的高度/滚动限制统统去掉(
height/maxHeight/overflow改成可见)。 - 读表格的完整内容尺寸(
scrollWidth/scrollHeight),拿到真实宽高。 - 把浏览器窗口临时放大到足够包住整张表的大小。
- 对准表格做元素级截图(
table.screenshot_as_png),用 Pillow 保存成 PNG。
适用场景
- 报表归档与分享:把每天的水雨情表格留存为图片,发群里一张图就够。
- 例行巡检/质检:截图记录页面状态,方便回溯和对账。
- 自动化日报:定时任务跑一遍,自动生成当日表格图片推送到频道。
- OCR 联动:得到干净的表格图片后,再去做文字/结构识别。
常见坑与解决
-
找不到驱动:Chrome 与 ChromeDriver 版本要匹配,确保驱动在
PATH里。 -
表格定位失败:确认页面里真的有这个
id,或者改用By.CSS_SELECTOR定位更稳。 -
表格太长被截断:Chrome 的窗口/截图有极限,超极限时请改用“分段滚动 + 图片拼接”。
-
页面虚拟化/懒加载:很多页面只渲染可见行,得滚动加载后再截,或者按段拼。
-
反爬/无头异常:必要时换 UA、用非无头模式、加等待和模拟交互。
-
快速排查:看
error_screenshot.png,一图看出是没加载、被遮罩还是脚本没生效。
结语
我与海鲜市场不同代天!!!!!!!!!!!!!!!!!!
代码 (代码MIT哈,大家自便)
"""
网页表格视觉识别截图工具 - 支持滚动表格完整截图
通过分段截图并拼接的方式获取整个表格内容
"""
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from PIL import Image
import io
def capture_with_full_page_method(url, table_id="hdtable", output_file="table_fullpage.png"):
"""
备选方案:尝试移除滚动条限制直接截取完整内容
参数:
url: 网页URL
table_id: 表格的ID
output_file: 输出的PNG文件名
"""
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(options=chrome_options)
try:
print(f"正在访问: {url}")
driver.get(url)
# 等待表格加载
wait = WebDriverWait(driver, 20)
table = wait.until(EC.presence_of_element_located((By.ID, table_id)))
time.sleep(5)
# 移除表格及父元素的高度限制和滚动条
print("移除滚动限制...")
driver.execute_script("""
var table = document.getElementById(arguments[0]);
var element = table;
// 移除所有父元素的高度限制
while (element) {
element.style.maxHeight = 'none';
element.style.height = 'auto';
element.style.overflow = 'visible';
element = element.parentElement;
if (element === document.body) break;
}
// 确保表格本身没有限制
table.style.maxHeight = 'none';
table.style.height = 'auto';
table.style.overflow = 'visible';
""", table_id)
time.sleep(2)
# 获取表格实际尺寸
dimensions = driver.execute_script("""
var table = document.getElementById(arguments[0]);
return {
width: table.scrollWidth,
height: table.scrollHeight
};
""", table_id)
print(f"表格尺寸: {dimensions['width']}x{dimensions['height']}")
# 调整窗口大小
driver.set_window_size(
max(1920, dimensions['width'] + 100),
max(1080, dimensions['height'] + 100)
)
time.sleep(2)
# 截图
print("截取完整表格...")
png_bytes = table.screenshot_as_png
image = Image.open(io.BytesIO(png_bytes))
image.save(output_file)
print(f"✓ 截图已保存: {output_file}")
print(f" 图片尺寸: {image.size}")
return output_file
except Exception as e:
print(f"✗ 发生错误: {str(e)}")
driver.save_screenshot("error_screenshot.png")
raise
finally:
driver.quit()
if __name__ == "__main__":
url = "http://xxfb.mwr.cn/sq_djdh.html?v=1.0"
print("=" * 60)
print("网页表格完整截图工具 - 支持滚动表格")
print("=" * 60)
print("\n 尝试移除滚动限制方式...")
try:
capture_with_full_page_method(url, "hdtable", "table_expanded.png")
except Exception as e:
print(f"失败: {e}\n")
print("\n" + "=" * 60)
print("处理完成!请检查生成的图片文件")
print("=" * 60)