2024-02-13 10:22:44 +00:00
|
|
|
|
import re
|
2024-09-14 12:27:15 +00:00
|
|
|
|
import json
|
|
|
|
|
import os
|
|
|
|
|
import time
|
2024-02-13 10:22:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 提取两个字符串之间的内容
|
|
|
|
|
def extract_string_between(source_string, start_string, end_string):
|
|
|
|
|
start_index = source_string.find(start_string) + len(start_string)
|
|
|
|
|
end_index = source_string.find(end_string)
|
|
|
|
|
extracted_string = source_string[start_index:-37]
|
|
|
|
|
return extracted_string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 去除多余的空格
|
|
|
|
|
def replace_multiple_spaces(string):
|
|
|
|
|
pattern = r'\s+'
|
|
|
|
|
replaced_string = re.sub(pattern, ' ', string)
|
|
|
|
|
return replaced_string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 替换十六进制编码
|
|
|
|
|
def process_old_html(message):
|
|
|
|
|
def replace_hex(match):
|
|
|
|
|
hex_value = match.group(0)
|
|
|
|
|
byte_value = bytes(hex_value, 'utf-8').decode('unicode_escape')
|
|
|
|
|
return byte_value
|
|
|
|
|
|
|
|
|
|
new_text = re.sub(r'\\x[0-9a-fA-F]{2}', replace_hex, message)
|
|
|
|
|
start_string = "html:'"
|
2024-02-13 12:47:18 +00:00
|
|
|
|
end_string = "',opuin"
|
2024-02-13 10:22:44 +00:00
|
|
|
|
new_text = extract_string_between(new_text, start_string, end_string)
|
|
|
|
|
new_text = replace_multiple_spaces(new_text).replace('\\', '')
|
|
|
|
|
return new_text
|
2024-09-12 15:10:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def show_author_info():
|
|
|
|
|
CYAN = '\033[36m'
|
|
|
|
|
YELLOW = '\033[33m'
|
|
|
|
|
BLUE = '\033[34m'
|
|
|
|
|
RESET = '\033[0m'
|
|
|
|
|
RED = '\033[31m'
|
2024-09-14 12:27:15 +00:00
|
|
|
|
|
2024-09-12 15:10:29 +00:00
|
|
|
|
author_art = r'''
|
|
|
|
|
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░
|
|
|
|
|
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░
|
|
|
|
|
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░
|
|
|
|
|
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓███████▓▒░ ░▒▓████████▓▒░ ░▒▓████████▓▒░ ░▒▓███████▓▒░
|
|
|
|
|
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
|
|
|
|
|
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
|
|
|
|
|
░▒▓████████▓▒░ ░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
print(CYAN + author_art + RESET)
|
2024-09-14 12:27:15 +00:00
|
|
|
|
|
2024-09-12 15:10:29 +00:00
|
|
|
|
author_info = f"{YELLOW}bilibili{RESET} {BLUE}@高数带我飞{RESET} {YELLOW}GetQzonehistory V1.0{RESET}"
|
|
|
|
|
print(author_info)
|
2024-11-08 03:31:32 +00:00
|
|
|
|
print(f'{RED}程序完全免费,且在GitHub开源!!!!{RESET}')
|
|
|
|
|
print(f'{RED}程序完全免费,且在GitHub开源!!!!{RESET}')
|
|
|
|
|
print(f'{RED}程序完全免费,且在GitHub开源!!!!{RESET}')
|
2024-09-13 01:58:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_html_template():
|
|
|
|
|
# HTML模板
|
|
|
|
|
html_template = """
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="zh-CN">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>QQ空间动态</title>
|
|
|
|
|
<style>
|
|
|
|
|
body {{
|
|
|
|
|
font-family: Arial, sans-serif;
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
}}
|
|
|
|
|
.post {{
|
|
|
|
|
background-color: #333;
|
|
|
|
|
color: #fff;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
margin: 20px;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
}}
|
|
|
|
|
.avatar {{
|
|
|
|
|
float: left;
|
|
|
|
|
margin-right: 20px;
|
|
|
|
|
}}
|
|
|
|
|
.avatar img {{
|
|
|
|
|
width: 50px;
|
|
|
|
|
height: 50px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
}}
|
2024-09-14 12:27:15 +00:00
|
|
|
|
.content {{
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}}
|
2024-09-13 01:58:51 +00:00
|
|
|
|
.nickname {{
|
|
|
|
|
font-size: 1.2em;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}}
|
|
|
|
|
.time {{
|
|
|
|
|
color: #999;
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
}}
|
|
|
|
|
.message {{
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
font-size: 1.1em;
|
|
|
|
|
}}
|
|
|
|
|
.image {{
|
|
|
|
|
margin-top: 10px;
|
2024-09-16 12:19:53 +00:00
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(3, 1fr); /* 将图片分成3列 */
|
|
|
|
|
grid-gap: 10px; /* 设置图片之间的间距 */
|
|
|
|
|
justify-items: center; /* 居中显示图片 */
|
2024-09-13 01:58:51 +00:00
|
|
|
|
}}
|
|
|
|
|
.image img {{
|
2024-09-16 12:19:53 +00:00
|
|
|
|
width: 100%; /* 图片宽度100%填充父容器 */
|
|
|
|
|
height: auto; /* 固定高度150px */
|
|
|
|
|
object-fit: cover; /* 保持比例裁剪图片 */
|
|
|
|
|
max-width: 33vw; /* 限制图片的最大宽度 */
|
|
|
|
|
max-height: 33vh; /* 限制图片的最大高度 */
|
2024-09-13 01:58:51 +00:00
|
|
|
|
border-radius: 10px;
|
2024-09-15 16:28:57 +00:00
|
|
|
|
cursor: pointer;
|
2024-09-16 12:19:53 +00:00
|
|
|
|
}}
|
2024-09-14 12:27:15 +00:00
|
|
|
|
.comments {{
|
|
|
|
|
margin-top: 5px; /* 调整这里的值来减少间距 */
|
|
|
|
|
background-color: #444;
|
|
|
|
|
padding: 2px 10px 10px 10px;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
}}
|
|
|
|
|
.comment {{
|
|
|
|
|
margin-top: 10px; /* 调整单个评论之间的间距 */
|
|
|
|
|
padding: 10px;
|
|
|
|
|
background-color: #555;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}}
|
|
|
|
|
.comment .avatar img {{
|
|
|
|
|
width: 30px;
|
|
|
|
|
height: 30px;
|
|
|
|
|
}}
|
|
|
|
|
.comment .nickname {{
|
|
|
|
|
font-size: 1em;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}}
|
|
|
|
|
.comment .time {{
|
|
|
|
|
font-size: 0.8em;
|
|
|
|
|
color: #aaa;
|
|
|
|
|
}}
|
2024-09-13 01:58:51 +00:00
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
2024-09-14 12:27:15 +00:00
|
|
|
|
|
2024-09-13 01:58:51 +00:00
|
|
|
|
{posts}
|
2024-09-15 16:28:57 +00:00
|
|
|
|
<script>
|
|
|
|
|
// 为所有图片添加点击事件
|
|
|
|
|
document.querySelectorAll(".image img").forEach(img => {{
|
|
|
|
|
img.addEventListener("click", function() {{
|
|
|
|
|
window.open(this.src, '_blank'); // 打开图片链接并在新标签页中展示
|
|
|
|
|
}});
|
|
|
|
|
}});
|
|
|
|
|
</script>
|
2024-09-13 01:58:51 +00:00
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# 生成每个动态的HTML内容
|
|
|
|
|
post_template = """
|
|
|
|
|
<div class="post">
|
|
|
|
|
<div class="avatar">
|
|
|
|
|
<img src="{avatar_url}" alt="头像">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="content">
|
|
|
|
|
<div class="nickname">{nickname}</div>
|
|
|
|
|
<div class="time">{time}</div>
|
|
|
|
|
<div class="message">{message}</div>
|
|
|
|
|
{image}
|
|
|
|
|
</div>
|
2024-09-14 12:27:15 +00:00
|
|
|
|
{comments}
|
2024-09-13 01:58:51 +00:00
|
|
|
|
</div>
|
|
|
|
|
"""
|
|
|
|
|
|
2024-09-14 12:27:15 +00:00
|
|
|
|
# 评论区HTML模板
|
|
|
|
|
comment_template = """
|
|
|
|
|
<div class="comments">
|
|
|
|
|
<div class="comment">
|
|
|
|
|
<div class="avatar">
|
|
|
|
|
<img src="{avatar_url}" alt="评论头像">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="nickname">{nickname}</div>
|
|
|
|
|
<div class="time">{time}</div>
|
|
|
|
|
<div class="message">{message}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
return html_template, post_template, comment_template
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 格式化时间
|
|
|
|
|
def format_timestamp(timestamp):
|
|
|
|
|
time_struct = time.localtime(timestamp)
|
|
|
|
|
formatted_time = time.strftime("%Y年%m月%d日 %H:%M:%S", time_struct)
|
|
|
|
|
return formatted_time
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 判断json是否合法
|
|
|
|
|
def is_valid_json(json_data):
|
|
|
|
|
try:
|
|
|
|
|
json_object = json.loads(json_data) # 尝试解析JSON数据
|
|
|
|
|
return True # 解析成功,是有效的JSON
|
|
|
|
|
except ValueError as e: # 解析失败,捕获异常
|
|
|
|
|
print(e)
|
|
|
|
|
return False # 解析失败,不是有效的JSON
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 写入信息
|
|
|
|
|
def write_txt_file(workdir, file_name, data):
|
|
|
|
|
if not os.path.exists(workdir):
|
|
|
|
|
os.makedirs(workdir)
|
|
|
|
|
base_path_file_name = os.path.join(workdir, file_name)
|
|
|
|
|
with open(base_path_file_name, 'w', encoding='utf-8') as file:
|
|
|
|
|
file.write(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 读取文件信息
|
|
|
|
|
def read_txt_file(workdir, file_name):
|
|
|
|
|
base_path_file_name = os.path.join(workdir, file_name)
|
|
|
|
|
if os.path.exists(base_path_file_name):
|
|
|
|
|
with open(base_path_file_name, 'r', encoding='utf-8') as file:
|
|
|
|
|
return file.read()
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
2024-09-16 12:16:38 +00:00
|
|
|
|
# QQ空间表情替换 [em]xxx[/em] 为 <img src="http://qzonestyle.gtimg.cn/qzone/em/xxx.gif">
|
|
|
|
|
def replace_em_to_img(match):
|
|
|
|
|
# 获取匹配的 xxx 部分
|
|
|
|
|
emoji_code = match.group(1)
|
|
|
|
|
return f'<img src="http://qzonestyle.gtimg.cn/qzone/em/{emoji_code}.gif" alt="{emoji_code}">'
|
|
|
|
|
|
2024-09-16 12:22:20 +00:00
|
|
|
|
|
|
|
|
|
def get_content_from_split(content):
|
|
|
|
|
content_split = str(content).split(":")
|
|
|
|
|
return content_split[1].strip() if len(content_split) > 1 else content.strip()
|
|
|
|
|
|
|
|
|
|
|
2024-11-18 08:25:49 +00:00
|
|
|
|
# 判断两个字符串是否相等
|
2024-09-16 12:22:20 +00:00
|
|
|
|
def is_any_mutual_exist(str1, str2):
|
|
|
|
|
str1 = get_content_from_split(str1)
|
|
|
|
|
str2 = get_content_from_split(str2)
|
2024-11-18 08:25:49 +00:00
|
|
|
|
return str1 == str2
|