256 lines
8.7 KiB
Python
256 lines
8.7 KiB
Python
import markdown
|
||
from playwright.sync_api import sync_playwright
|
||
import os
|
||
|
||
|
||
# 将 Markdown 字符串转换为 HTML
|
||
def md_str_to_html(md_content, output_html):
|
||
"""
|
||
将 Markdown 字符串转换为 HTML 文件,并添加支持中文和 Emoji 的样式。
|
||
|
||
:param md_content: 输入的 Markdown 字符串
|
||
:param output_html: 输出的 HTML 文件路径
|
||
"""
|
||
# 转换 Markdown 为 HTML,启用额外功能(如表格、代码高亮)
|
||
html_content = markdown.markdown(md_content, extensions=['extra', 'codehilite'])
|
||
|
||
# 添加基本的 HTML 结构和样式,支持中文和 Emoji
|
||
css = """
|
||
<style>
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', 'Noto Sans CJK SC', 'Microsoft YaHei', sans-serif;
|
||
padding: 25px 30px;
|
||
line-height: 1.7;
|
||
max-width: 700px;
|
||
margin: 0 auto;
|
||
background-color: #f9f9f9;
|
||
color: #333;
|
||
border: 1px solid #f0f0f0;
|
||
}
|
||
h1, h2, h3, h4, h5, h6 {
|
||
color: #222;
|
||
margin-top: 20px;
|
||
margin-bottom: 15px;
|
||
font-weight: 600;
|
||
line-height: 1.4;
|
||
}
|
||
h1 {
|
||
font-size: 1.8em;
|
||
padding-bottom: 10px;
|
||
border-bottom: 1px solid #eee;
|
||
text-align: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
h2 {
|
||
font-size: 1.5em;
|
||
padding-bottom: 8px;
|
||
margin-top: 25px;
|
||
border-bottom: 1px solid #eee;
|
||
}
|
||
h3 {
|
||
font-size: 1.3em;
|
||
margin-top: 20px;
|
||
padding-left: 10px;
|
||
border-left: 3px solid #ddd;
|
||
}
|
||
pre, code {
|
||
background-color: #f5f5f5;
|
||
padding: 10px;
|
||
border-radius: 3px;
|
||
font-family: 'Courier New', Courier, monospace;
|
||
font-size: 0.9em;
|
||
border: 1px solid #eee;
|
||
}
|
||
table {
|
||
border-collapse: collapse;
|
||
width: 100%;
|
||
margin: 15px 0;
|
||
background-color: white;
|
||
}
|
||
th, td {
|
||
border: 1px solid #eee;
|
||
padding: 8px 10px;
|
||
text-align: left;
|
||
}
|
||
th {
|
||
background-color: #fafafa;
|
||
font-weight: 600;
|
||
}
|
||
/* 确保 Emoji 正确渲染 */
|
||
span, p, li {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', 'Noto Sans CJK SC', 'Microsoft YaHei', sans-serif;
|
||
}
|
||
p {
|
||
margin: 12px 0;
|
||
color: #333;
|
||
line-height: 1.8;
|
||
}
|
||
ul, ol {
|
||
padding-left: 22px;
|
||
margin: 15px 0;
|
||
}
|
||
li {
|
||
margin: 5px 0;
|
||
line-height: 1.7;
|
||
}
|
||
blockquote {
|
||
margin: 15px 0;
|
||
padding: 10px 15px;
|
||
background-color: #f8f8f8;
|
||
border-left: 4px solid #ddd;
|
||
color: #666;
|
||
font-size: 0.95em;
|
||
}
|
||
/* 强调样式 */
|
||
strong {
|
||
color: #333;
|
||
font-weight: 600;
|
||
}
|
||
/* 链接样式 */
|
||
a {
|
||
color: #576b95;
|
||
text-decoration: none;
|
||
}
|
||
a:hover {
|
||
text-decoration: underline;
|
||
}
|
||
/* 星级评分样式 */
|
||
h3 em {
|
||
color: #fa8c16;
|
||
font-style: normal;
|
||
}
|
||
/* 时间和标签样式 */
|
||
.time, .tag {
|
||
color: #888;
|
||
font-size: 0.9em;
|
||
}
|
||
/* 底部署名样式 */
|
||
.signature {
|
||
margin-top: 30px;
|
||
text-align: right;
|
||
color: #888;
|
||
font-size: 0.9em;
|
||
font-style: italic;
|
||
}
|
||
</style>
|
||
"""
|
||
|
||
# 写入 HTML 文件
|
||
with open(output_html, 'w', encoding='utf-8') as f:
|
||
f.write('<html><head>')
|
||
f.write('<meta charset="UTF-8">') # 确保 UTF-8 编码
|
||
f.write(css)
|
||
f.write('</head><body>')
|
||
f.write(html_content)
|
||
f.write('</body></html>')
|
||
|
||
|
||
# 使用 Playwright 将 HTML 渲染并截图
|
||
def html_to_image(html_file, output_image):
|
||
"""
|
||
使用 Playwright 加载 HTML 文件并截图。
|
||
|
||
:param html_file: 输入的 HTML 文件路径
|
||
:param output_image: 输出的图片文件路径
|
||
"""
|
||
with sync_playwright() as p:
|
||
# TODO 这里使用的比较呆的固定路径,后期优化
|
||
browser = p.chromium.launch(executable_path=r"C:\Users\Liu_WIN10\AppData\Local\Google\Chrome\Application\chrome.exe")
|
||
page = browser.new_page()
|
||
|
||
# 加载本地的 HTML 文件
|
||
page.goto(f'file://{os.path.abspath(html_file)}')
|
||
|
||
# 设置 viewport(可选,根据需要调整)
|
||
page.set_viewport_size({"width": 750, "height": 700})
|
||
|
||
# 截图
|
||
page.screenshot(path=output_image, full_page=True)
|
||
|
||
browser.close()
|
||
|
||
|
||
# 主函数:从字符串转换 Markdown 到图片
|
||
def convert_md_str_to_image(md_content, output_image):
|
||
"""
|
||
将 Markdown 字符串转换为图片。
|
||
|
||
:param md_content: 输入的 Markdown 字符串
|
||
:param output_image: 输出的图片文件路径
|
||
"""
|
||
# 中间生成的 HTML 文件
|
||
temp_html = 'temp_output.html'
|
||
|
||
# 第一步:将 Markdown 字符串转换为 HTML
|
||
md_str_to_html(md_content, temp_html)
|
||
|
||
# 第二步:将 HTML 渲染为图片
|
||
html_to_image(temp_html, output_image)
|
||
|
||
# 可选:删除临时的 HTML 文件
|
||
os.remove(temp_html)
|
||
print(f"图片已生成:{output_image}")
|
||
return os.path.abspath(output_image)
|
||
|
||
# 示例使用
|
||
if __name__ == "__main__":
|
||
# 示例 Markdown 字符串(包含中文和 Emoji)
|
||
md_content = """
|
||
# 🌟「极浪先锋体验官群 - 2023年3月24日 总结」🌟
|
||
|
||
## 📊 今日数据快报
|
||
- **总消息数**:📩 200 条
|
||
- **最活跃时段**:🔥 09:00 - 10:00 (📈 30 条/小时)
|
||
- **聊天时段**:🕒 06:52 - 15:29
|
||
|
||
## 🌌 话题总结
|
||
|
||
### 1️⃣ 【汽车与驾驶经验分享】 ⭐⭐⭐⭐⭐
|
||
🕒 **聊天时段**:09:00 - 09:30 (👥 6 人参与)
|
||
🔍 **话题回顾**:
|
||
讨论围绕 **汽车驾驶技巧**及**车主经验**展开,参与者分享了各自驾驶中的趣事与技巧。
|
||
- [郑晓杰] 提到 **“空挡溜车”**的经历,引发众人对安全驾驶的讨论。
|
||
- [BlackBear] 讲述了被大哥质问的搞笑瞬间,增加了话题热度。
|
||
> **金句回顾**:"破财免灾,大吉大利。" —— [@BlackBear]
|
||
|
||
### 2️⃣ 【群内轻松话题】 ⭐⭐⭐⭐
|
||
🕒 **聊天时段**:09:45 - 10:15 (👥 8 人参与)
|
||
🔍 **高能讨论**:
|
||
群友们开始轻松调侃,涉及 **食物与地方特产**,特别是关于[普宁豆酱]和[绿豆饼]的分享。
|
||
- [Jiojio] 提到自己带的特产,唤起了大家的食欲。
|
||
- [寸头男孩] 要求带些地方小吃,气氛轻松愉快。
|
||
📌 **实用干货**:推荐了 **地方特产和美食**,引发食物讨论的热潮。
|
||
|
||
### 3️⃣ 【生活琐事与幽默分享】 ⭐⭐⭐⭐
|
||
🕒 **聊天时段**:10:20 - 11:00 (👥 7 人参与)
|
||
🔍 **讨论亮点**:
|
||
大家分享生活中的小趣事和笑话,增加了群内的亲密感。
|
||
- [别吃,很胖了] 提到自己的幽默日常,且引发众人的共鸣。
|
||
- [郑晓杰] 也分享了自己的搞笑经历,让大家捧腹大笑。
|
||
> **精华总结**:"我只知道一个轻推的习惯。" —— [@郑晓杰]
|
||
|
||
### 4️⃣ 【求姻缘与生活感悟】 ⭐⭐⭐
|
||
🕒 **聊天时段**:12:30 - 13:00 (👥 5 人参与)
|
||
🔍 **精彩瞬间**:
|
||
群友们开始讨论 **求姻缘的经历**,分享了不同的见解与感悟。
|
||
- [别吃,很胖了] 替朋友祈福的经历引起了共鸣,大家讨论了姻缘与生活的连接。
|
||
- 参与者们分享了自己的求姻缘故事,增加了互动。
|
||
|
||
### 5️⃣ 【汽车品牌及车型讨论】 ⭐⭐⭐
|
||
🕒 **聊天时段**:14:00 - 15:00 (👥 6 人参与)
|
||
🔍 **讨论小结**:
|
||
群友们热烈讨论了 **汽车品牌与车型**,特别是极氪与特斯拉的比较。
|
||
- [Ailian] 表达了对特斯拉的看法,同时引发了对其他品牌的讨论。
|
||
- [BlackBear] 和其他成员对各自的车型进行了幽默的调侃。
|
||
|
||
## 🎖️ 今日荣誉榜
|
||
🏆 **群聊 MVP**:[@BlackBear]
|
||
👑 **获奖理由**:
|
||
✅ 发起 3 个热门话题
|
||
✅ 贡献 5 个幽默段子
|
||
✅ **创新贡献**:"破财免灾"的智慧分享,让大家倍感轻松。
|
||
|
||
✨ *本总结由 AI 自动生成,快来看看你今天是不是最靓的崽!🔥*
|
||
"""
|
||
spath = convert_md_str_to_image(md_content, "output.png")
|
||
print(spath) |