@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
from os import path
|
||||||
|
from wordcloud import WordCloud
|
||||||
|
import jieba
|
||||||
|
from imageio.v3 import imread
|
||||||
|
|
||||||
|
def Bulletchat_Wordcloud():
|
||||||
|
try:
|
||||||
|
#获取当前文件路径
|
||||||
|
d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
|
||||||
|
text = open(path.join(d,r'2028.txt'), 'rb').read()
|
||||||
|
# 设置模板图
|
||||||
|
img_mask = imread(r'm1.png')
|
||||||
|
# 对弹幕进行精确模式分词
|
||||||
|
text_list = jieba.lcut(text,cut_all=False)
|
||||||
|
text_str = ' '.join(text_list)
|
||||||
|
# print(text_str)
|
||||||
|
# 设置中文字体
|
||||||
|
font_path = r'C:\Users\15653\msyh.ttc'
|
||||||
|
# 停止词设置
|
||||||
|
stopwords = set('')
|
||||||
|
stopwords.update(['的','和','又','了','都','是','什么','所以','这','呢','吧','吗','个','呀','嘛','哈'])
|
||||||
|
wc = WordCloud(
|
||||||
|
font_path=font_path,
|
||||||
|
#max_words=500, # 最多词个数
|
||||||
|
#min_font_size=15,
|
||||||
|
#max_font_size=100,
|
||||||
|
mask=img_mask,
|
||||||
|
background_color='white',
|
||||||
|
stopwords=stopwords,
|
||||||
|
colormap='copper'
|
||||||
|
)
|
||||||
|
wc.generate(text_str)
|
||||||
|
wc.to_file(r'outm1.png')
|
||||||
|
except Exception as e:
|
||||||
|
print(f"词云图生成异常: {e}")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
Bulletchat_Wordcloud()
|
@ -0,0 +1,97 @@
|
|||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
import random
|
||||||
|
import imageio
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
# 参数设置
|
||||||
|
WIDTH = 800 # 图片宽度
|
||||||
|
HEIGHT = 600 # 图片高度
|
||||||
|
FONT_SIZE = 20 # 字体大小
|
||||||
|
COL_WIDTH = FONT_SIZE
|
||||||
|
NUM_COLS = WIDTH // COL_WIDTH
|
||||||
|
MAX_TRAIL_LENGTH = 15 # 代码雨最大长度
|
||||||
|
FRAMES_PER_SUBTITLE = 10 # 每条字幕的帧数
|
||||||
|
OUTPUT_GIF = 'code_rain.gif' # 输出 GIF 文件名
|
||||||
|
|
||||||
|
def read_subtitles(filename):
|
||||||
|
"""读取字幕文件"""
|
||||||
|
with open(filename, 'r', encoding='utf-8') as f:
|
||||||
|
subtitles = f.readlines()
|
||||||
|
subtitles = [line.strip() for line in subtitles if line.strip()]
|
||||||
|
return subtitles
|
||||||
|
|
||||||
|
def extract_characters(subtitles):
|
||||||
|
"""从字幕中提取所有出现的字符"""
|
||||||
|
chars_set = set()
|
||||||
|
for line in subtitles:
|
||||||
|
chars_set.update(line)
|
||||||
|
return list(chars_set)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# 读取字幕
|
||||||
|
subtitles = read_subtitles(r'提取.txt')
|
||||||
|
|
||||||
|
# 提取字符集
|
||||||
|
CHARS = extract_characters(subtitles)
|
||||||
|
# 添加额外的字符(可选)
|
||||||
|
CHARS.extend(list('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()+-'))
|
||||||
|
|
||||||
|
# 加载字体(请确保字体文件存在)
|
||||||
|
font_path = r'msyh.ttc' # 替换为您的字体文件完整路径,确保支持中文
|
||||||
|
|
||||||
|
# 检查字体文件是否存在
|
||||||
|
if not os.path.exists(font_path):
|
||||||
|
print(f"未找到字体文件 '{font_path}'。请提供正确的字体路径。")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
font = ImageFont.truetype(font_path, FONT_SIZE)
|
||||||
|
except OSError:
|
||||||
|
print(f"无法打开字体文件 '{font_path}'。请检查文件是否损坏或权限设置。")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 初始化列的位置
|
||||||
|
column_positions = [random.randint(-HEIGHT, 0) for _ in range(NUM_COLS)]
|
||||||
|
|
||||||
|
frames = []
|
||||||
|
|
||||||
|
for subtitle in subtitles:
|
||||||
|
for _ in range(FRAMES_PER_SUBTITLE):
|
||||||
|
# 创建新图像
|
||||||
|
img = Image.new('RGB', (WIDTH, HEIGHT), color='black')
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
|
||||||
|
# 绘制代码雨
|
||||||
|
for i in range(NUM_COLS):
|
||||||
|
x = i * COL_WIDTH
|
||||||
|
y = column_positions[i]
|
||||||
|
|
||||||
|
for j in range(MAX_TRAIL_LENGTH):
|
||||||
|
char = random.choice(CHARS)
|
||||||
|
y_pos = y - j * FONT_SIZE
|
||||||
|
if y_pos < 0 or y_pos > HEIGHT:
|
||||||
|
continue
|
||||||
|
green_value = int(255 / MAX_TRAIL_LENGTH * (MAX_TRAIL_LENGTH - j))
|
||||||
|
draw.text((x, y_pos), char, font=font, fill=(0, green_value, 0))
|
||||||
|
|
||||||
|
# 更新列的位置
|
||||||
|
column_positions[i] = (y + FONT_SIZE) % (HEIGHT + FONT_SIZE * MAX_TRAIL_LENGTH)
|
||||||
|
|
||||||
|
# 绘制字幕
|
||||||
|
bbox = draw.textbbox((0, 0), subtitle, font=font)
|
||||||
|
text_width = bbox[2] - bbox[0]
|
||||||
|
text_height = bbox[3] - bbox[1]
|
||||||
|
text_x = (WIDTH - text_width) // 2
|
||||||
|
text_y = HEIGHT - text_height - 10 # 距离底部 10 像素
|
||||||
|
draw.text((text_x, text_y), subtitle, font=font, fill=(255, 255, 255))
|
||||||
|
|
||||||
|
# 添加帧
|
||||||
|
frames.append(img)
|
||||||
|
|
||||||
|
# 保存为 GIF
|
||||||
|
frames[0].save(OUTPUT_GIF, save_all=True, append_images=frames[1:], optimize=False, duration=100, loop=0)
|
||||||
|
print(f"GIF 已保存为 '{OUTPUT_GIF}'")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -0,0 +1,62 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import certifi
|
||||||
|
|
||||||
|
# 请在此处替换为您的 News API 密钥
|
||||||
|
API_KEY = '04c1848491d143f9a9af8a64655167e8'
|
||||||
|
|
||||||
|
# 定义查询参数
|
||||||
|
query = '2024 Paris Olympics AND AI technology'
|
||||||
|
language = 'en'
|
||||||
|
page_size = 100
|
||||||
|
|
||||||
|
# 定义请求 URL 和参数
|
||||||
|
url = 'https://newsapi.org/v2/everything'
|
||||||
|
params = {
|
||||||
|
'q': query,
|
||||||
|
'language': language,
|
||||||
|
'pageSize': page_size,
|
||||||
|
'apiKey': API_KEY
|
||||||
|
}
|
||||||
|
|
||||||
|
def fetch_articles():
|
||||||
|
all_articles = []
|
||||||
|
page = 1
|
||||||
|
while True:
|
||||||
|
params['page'] = page
|
||||||
|
try:
|
||||||
|
response = requests.get(url, params=params, proxies={"http": None, "https": None})
|
||||||
|
|
||||||
|
response.raise_for_status() # 检查HTTP错误
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if data['status'] != 'ok':
|
||||||
|
print(f"获取文章时出错:{data.get('message')}")
|
||||||
|
break
|
||||||
|
|
||||||
|
articles = data.get('articles', [])
|
||||||
|
if not articles:
|
||||||
|
break
|
||||||
|
|
||||||
|
all_articles.extend(articles)
|
||||||
|
print(f"已获取第 {page} 页,共 {len(all_articles)} 篇文章")
|
||||||
|
page += 1
|
||||||
|
|
||||||
|
if len(all_articles) >= 100:
|
||||||
|
break
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"请求出现异常:{e}")
|
||||||
|
break
|
||||||
|
|
||||||
|
return all_articles
|
||||||
|
|
||||||
|
def save_articles(articles, filename='articles.json'):
|
||||||
|
with open(filename, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(articles, f, ensure_ascii=False, indent=4)
|
||||||
|
print(f"已将 {len(articles)} 篇文章保存到 {filename}")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
articles = fetch_articles()
|
||||||
|
if articles:
|
||||||
|
save_articles(articles)
|
After Width: | Height: | Size: 644 KiB |
After Width: | Height: | Size: 158 KiB |
After Width: | Height: | Size: 155 KiB |
After Width: | Height: | Size: 44 MiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 351 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 276 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 6.0 KiB |
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
from os import path
|
||||||
|
from wordcloud import WordCloud
|
||||||
|
import jieba
|
||||||
|
from imageio.v3 import imread
|
||||||
|
|
||||||
|
def Bulletchat_Wordcloud():
|
||||||
|
try:
|
||||||
|
#获取当前文件路径
|
||||||
|
d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
|
||||||
|
text = open(path.join(d,r'2028.txt'), 'rb').read()
|
||||||
|
# 设置模板图
|
||||||
|
img_mask = imread(r'm1.png')
|
||||||
|
# 对弹幕进行精确模式分词
|
||||||
|
text_list = jieba.lcut(text,cut_all=False)
|
||||||
|
text_str = ' '.join(text_list)
|
||||||
|
# print(text_str)
|
||||||
|
# 设置中文字体
|
||||||
|
font_path = r'C:\Users\15653\msyh.ttc'
|
||||||
|
# 停止词设置
|
||||||
|
stopwords = set('')
|
||||||
|
stopwords.update(['的','和','又','了','都','是','什么','所以','这','呢','吧','吗','个','呀','嘛','哈'])
|
||||||
|
wc = WordCloud(
|
||||||
|
font_path=font_path,
|
||||||
|
#max_words=500, # 最多词个数
|
||||||
|
#min_font_size=15,
|
||||||
|
#max_font_size=100,
|
||||||
|
mask=img_mask,
|
||||||
|
background_color='white',
|
||||||
|
stopwords=stopwords,
|
||||||
|
colormap='copper'
|
||||||
|
)
|
||||||
|
wc.generate(text_str)
|
||||||
|
wc.to_file(r'outm1.png')
|
||||||
|
except Exception as e:
|
||||||
|
print(f"词云图生成异常: {e}")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
Bulletchat_Wordcloud()
|
@ -0,0 +1,97 @@
|
|||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
import random
|
||||||
|
import imageio
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
# 参数设置
|
||||||
|
WIDTH = 800 # 图片宽度
|
||||||
|
HEIGHT = 600 # 图片高度
|
||||||
|
FONT_SIZE = 20 # 字体大小
|
||||||
|
COL_WIDTH = FONT_SIZE
|
||||||
|
NUM_COLS = WIDTH // COL_WIDTH
|
||||||
|
MAX_TRAIL_LENGTH = 15 # 代码雨最大长度
|
||||||
|
FRAMES_PER_SUBTITLE = 10 # 每条字幕的帧数
|
||||||
|
OUTPUT_GIF = 'code_rain.gif' # 输出 GIF 文件名
|
||||||
|
|
||||||
|
def read_subtitles(filename):
|
||||||
|
"""读取字幕文件"""
|
||||||
|
with open(filename, 'r', encoding='utf-8') as f:
|
||||||
|
subtitles = f.readlines()
|
||||||
|
subtitles = [line.strip() for line in subtitles if line.strip()]
|
||||||
|
return subtitles
|
||||||
|
|
||||||
|
def extract_characters(subtitles):
|
||||||
|
"""从字幕中提取所有出现的字符"""
|
||||||
|
chars_set = set()
|
||||||
|
for line in subtitles:
|
||||||
|
chars_set.update(line)
|
||||||
|
return list(chars_set)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# 读取字幕
|
||||||
|
subtitles = read_subtitles(r'提取.txt')
|
||||||
|
|
||||||
|
# 提取字符集
|
||||||
|
CHARS = extract_characters(subtitles)
|
||||||
|
# 添加额外的字符(可选)
|
||||||
|
CHARS.extend(list('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()+-'))
|
||||||
|
|
||||||
|
# 加载字体(请确保字体文件存在)
|
||||||
|
font_path = r'msyh.ttc' # 替换为您的字体文件完整路径,确保支持中文
|
||||||
|
|
||||||
|
# 检查字体文件是否存在
|
||||||
|
if not os.path.exists(font_path):
|
||||||
|
print(f"未找到字体文件 '{font_path}'。请提供正确的字体路径。")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
font = ImageFont.truetype(font_path, FONT_SIZE)
|
||||||
|
except OSError:
|
||||||
|
print(f"无法打开字体文件 '{font_path}'。请检查文件是否损坏或权限设置。")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 初始化列的位置
|
||||||
|
column_positions = [random.randint(-HEIGHT, 0) for _ in range(NUM_COLS)]
|
||||||
|
|
||||||
|
frames = []
|
||||||
|
|
||||||
|
for subtitle in subtitles:
|
||||||
|
for _ in range(FRAMES_PER_SUBTITLE):
|
||||||
|
# 创建新图像
|
||||||
|
img = Image.new('RGB', (WIDTH, HEIGHT), color='black')
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
|
||||||
|
# 绘制代码雨
|
||||||
|
for i in range(NUM_COLS):
|
||||||
|
x = i * COL_WIDTH
|
||||||
|
y = column_positions[i]
|
||||||
|
|
||||||
|
for j in range(MAX_TRAIL_LENGTH):
|
||||||
|
char = random.choice(CHARS)
|
||||||
|
y_pos = y - j * FONT_SIZE
|
||||||
|
if y_pos < 0 or y_pos > HEIGHT:
|
||||||
|
continue
|
||||||
|
green_value = int(255 / MAX_TRAIL_LENGTH * (MAX_TRAIL_LENGTH - j))
|
||||||
|
draw.text((x, y_pos), char, font=font, fill=(0, green_value, 0))
|
||||||
|
|
||||||
|
# 更新列的位置
|
||||||
|
column_positions[i] = (y + FONT_SIZE) % (HEIGHT + FONT_SIZE * MAX_TRAIL_LENGTH)
|
||||||
|
|
||||||
|
# 绘制字幕
|
||||||
|
bbox = draw.textbbox((0, 0), subtitle, font=font)
|
||||||
|
text_width = bbox[2] - bbox[0]
|
||||||
|
text_height = bbox[3] - bbox[1]
|
||||||
|
text_x = (WIDTH - text_width) // 2
|
||||||
|
text_y = HEIGHT - text_height - 10 # 距离底部 10 像素
|
||||||
|
draw.text((text_x, text_y), subtitle, font=font, fill=(255, 255, 255))
|
||||||
|
|
||||||
|
# 添加帧
|
||||||
|
frames.append(img)
|
||||||
|
|
||||||
|
# 保存为 GIF
|
||||||
|
frames[0].save(OUTPUT_GIF, save_all=True, append_images=frames[1:], optimize=False, duration=100, loop=0)
|
||||||
|
print(f"GIF 已保存为 '{OUTPUT_GIF}'")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -0,0 +1,62 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import certifi
|
||||||
|
|
||||||
|
# 请在此处替换为您的 News API 密钥
|
||||||
|
API_KEY = '04c1848491d143f9a9af8a64655167e8'
|
||||||
|
|
||||||
|
# 定义查询参数
|
||||||
|
query = '2024 Paris Olympics AND AI technology'
|
||||||
|
language = 'en'
|
||||||
|
page_size = 100
|
||||||
|
|
||||||
|
# 定义请求 URL 和参数
|
||||||
|
url = 'https://newsapi.org/v2/everything'
|
||||||
|
params = {
|
||||||
|
'q': query,
|
||||||
|
'language': language,
|
||||||
|
'pageSize': page_size,
|
||||||
|
'apiKey': API_KEY
|
||||||
|
}
|
||||||
|
|
||||||
|
def fetch_articles():
|
||||||
|
all_articles = []
|
||||||
|
page = 1
|
||||||
|
while True:
|
||||||
|
params['page'] = page
|
||||||
|
try:
|
||||||
|
response = requests.get(url, params=params, proxies={"http": None, "https": None})
|
||||||
|
|
||||||
|
response.raise_for_status() # 检查HTTP错误
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if data['status'] != 'ok':
|
||||||
|
print(f"获取文章时出错:{data.get('message')}")
|
||||||
|
break
|
||||||
|
|
||||||
|
articles = data.get('articles', [])
|
||||||
|
if not articles:
|
||||||
|
break
|
||||||
|
|
||||||
|
all_articles.extend(articles)
|
||||||
|
print(f"已获取第 {page} 页,共 {len(all_articles)} 篇文章")
|
||||||
|
page += 1
|
||||||
|
|
||||||
|
if len(all_articles) >= 100:
|
||||||
|
break
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"请求出现异常:{e}")
|
||||||
|
break
|
||||||
|
|
||||||
|
return all_articles
|
||||||
|
|
||||||
|
def save_articles(articles, filename='articles.json'):
|
||||||
|
with open(filename, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(articles, f, ensure_ascii=False, indent=4)
|
||||||
|
print(f"已将 {len(articles)} 篇文章保存到 {filename}")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
articles = fetch_articles()
|
||||||
|
if articles:
|
||||||
|
save_articles(articles)
|