电影/游戏墙(手风琴动态)及自动生成脚本

效果展示 跳转链接:电影墙 游戏墙



手风琴样式的展示墙,鼠标移上去图片会显示完全并且展示描述文字。点击图片会跳转到对应的豆瓣链接

前端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.contain {
position: relative;
width: 90%;
max-width: 1050px;
margin: 100px auto;
overflow: hidden;
background: #fff;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
.contain > ul {
display: flex;
height: calc(100vh / 2.9);
justify-content: space-between;
list-style: none;
padding: 0;
margin: 0;
gap: 10px;
}
.contain > ul > li {
position: relative;
width: calc(100% / 6 - 10px);
height: 100%;
transition: width 0.5s;
overflow: hidden;
border-left: 2px solid rgba(255, 255, 255, 0.8);
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
}
.contain > ul > li:first-child {
border-left: none;
}
.contain > ul > li:hover {
width: 500px;
}
.contain a {
color: #fff;
text-decoration: none;
display: flex;
height: 100%;
border-radius: 10px;
overflow: hidden;
}
.contain > ul > li > a > img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s;
}
.contain > ul > li:hover img {
transform: scale(1.1);
}
.info {
display: none;
flex-direction: column;
justify-content: center;
padding: 20px;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(10px);
color: white;
transition: opacity 0.5s;
opacity: 0;
}
.contain > ul > li:hover .info {
display: flex;
opacity: 1;
}
.info h2 {
margin: 0;
font-size: 24px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
line-height: 1.5;
}

.info p {
margin: 10px 0 0;
font-size: 16px;
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
line-height: 1.5;
}

body {
/* 暗色主题 */
background-color: #333;
color: #fff;
}

.contain {
background: #444;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
}

.contain > ul > li {
border-left: 2px solid rgba(255, 255, 255, 0.2);
}

.info h2,
.info p {
color: #fff;
}
.rounded-title {
color: white;
border-radius: 10px;
padding: 10px 20px;
text-align: center;
display: inline-block;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
font-size: 30px;
}
</style>

<script>
/* 提示手机无法很好加载页面 */
if (
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
)
) {
alert(
"嘿,这个页面在手机上显示效果可能不太好哦!建议切换到电脑上查看~"
);
}
</script>
</head>

<body>
<div class="contain">
<h2 class="rounded-title">
那些年看过的影视剧 <i class="fa-solid fa-face-grin-hearts"></i>
</h2>

<ul>
<li>
<a href="https://movie.douban.com/subject/1297110/">
<img
src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1833029967.webp"
referrerpolicy="no-referrer"
style="width:auto;height:auto;"
/>
<div class="info">
<h2>睡美人</h2>
<p>Sleeping Beauty</p>
</div>
</a>
</li>

<li>
<a href="https://movie.douban.com/subject/1294408/">
<img
src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p453788577.webp"
referrerpolicy="no-referrer"
style="width:auto;height:auto;"
/>
<div class="info">
<h2>音乐之声</h2>
<p>神!</p>
</div>
</a>
</li>

<li>
<a href="https://movie.douban.com/subject/1305697/">
<img
src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2576327873.webp"
referrerpolicy="no-referrer"
style="width:auto;height:auto;"
/>
<div class="info">
<h2></h2>
<p>啊,朋友再见</p>
</div>
</a>
</li>

<li>
<a href="https://movie.douban.com/subject/1303075/">
<img
src="https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2549456054.webp"
referrerpolicy="no-referrer"
style="width:auto;height:auto;"
/>
<div class="info">
<h2>这里的黎明静悄悄</h2>
<p>А зори здесь тихие</p>
</div>
</a>
</li>

<li>
<a href="https://movie.douban.com/subject/1291860/">
<img
src="https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2556873379.webp"
referrerpolicy="no-referrer"
style="width:auto;height:auto;"
/>
<div class="info">
<h2>瓦尔特保卫萨拉热窝</h2>
<p>看,这座城市就是瓦尔特</p>
</div>
</a>
</li>

<li>
<a href="https://movie.douban.com/subject/1293838/">
<img
src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2500865872.webp"
referrerpolicy="no-referrer"
style="width:auto;height:auto;"
/>
<div class="info">
<h2>星球大战</h2>
<p>梦开始的地方</p>
</div>
</a>
</li>
</ul>
<!-- 六个为一组,如此重复即可 -->
</div>
</body>
</html>

python 自动生成脚本

movieConvert.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import pandas as pd
df = pd.read_excel(r'。。。。。。.xlsx') # 读取Excel文件
# HTML模板
html_template = """
<ul>
{items}
</ul>
"""

item_template = """
<li>
<a href="{link}">
<img src="{img}" referrerpolicy="no-referrer" style="width:auto;height:auto;" />
<div class="info">
<h2>{title}</h2>
<p>{description}</p>
</div>
</a>
</li>
"""

# 创建HTML内容
all_html_content = ""
group_html_content = ""

for index, row in df.iterrows():
movie_titles = row[0].split('/')
title = movie_titles[0] if len(movie_titles) > 0 else ""
description = movie_titles[1] if len(movie_titles) > 1 else ""
link = row[1]
img = row[2]

group_html_content += item_template.format(title=title, description=description, link=link, img=img)

# 每六个为一组
if (index + 1) % 6 == 0 or index + 1 == len(df):
all_html_content += html_template.format(items=group_html_content)
group_html_content = ""

# 输出
with open('output.html', 'w', encoding='utf-8') as file:
file.write(all_html_content)

print('Done!')

前提是有一个从豆瓣页面爬取下来的看过的电影 excel 表格。即可自动化转换为特定的 HTML 格式,直接复制粘贴到源代码里即可

音乐墙 + 音乐播放器 以及自动生成脚本 (Deprecated)

效果展示


实现专辑墙的效果,点击播放,进度条调整播放进度

前端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Music Playlist</title>
<style>
.music {
width: 200px;
height: 200px;
border: 1px solid #ccc;
text-align: center;
margin: 10px;
float: left;
cursor: pointer;
position: relative;
transition: transform 0.3s;
}

.music img {
max-width: 100%;
max-height: 100%;
}

.music:hover {
transform: scale(1.1);
}

.music-info {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
display: none;
}

.music:hover .music-info {
display: block;
}

#playlist {
display: flex;
flex-wrap: wrap;
justify-content: center;
}

#progress {
width: 100%;
height: 10px;
border-radius: 5px;
background: linear-gradient(to right, #ff7e5f, #feb47b);
}

input[type="range"] {
-webkit-appearance: none;
appearance: none;
}

input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 15px;
height: 15px;
border-radius: 50%;
background: #ff7e5f;
cursor: pointer;
}
#playPauseButton {
background: #ff7e5f;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
}

</style>
</head>
<body>

<div id="playlist">

<div class="music" data-music="https://ws6.stream.qqmusic.qq.com/C400002pSMav050h1b.m4a?guid=7104432948&vkey=B74730F1151F22AAEB27427BD0580BEE5B08953D4A30C7FB9F61785BA7AD3731F22483DD7319B802F32B11B2C19F236EC20ABA44170318E8&uin=1152921504695982864&fromtag=120032">
<img src="https://y.qq.com/music/photo_new/T002R300x300M0000041GPv63o2YjS.jpg?max_age=2592000" alt="Album Cover">
<div class="music-info">
<h3>Life Will Change<h3>
<p>偷心的小曲</p>
</div>
</div>

<div class="music" data-music="https://ws6.stream.qqmusic.qq.com/C400002HjpE82ZHxgP.m4a?guid=5402269082&vkey=14E912D5D8B2AFD36B8F9D6C6D13C446F273AFF5E8EDB9FF4D51B8D4F75FF2E7BF42CD04705076AF6861F6612E75CB7491AF6837B1C3849A&uin=1152921504695982864&fromtag=120032">
<img src="https://y.qq.com/music/photo_new/T002R300x300M000001mmP543eChhy.jpg?max_age=2592000" alt="Album Cover">
<div class="music-info">
<h3>Sogno di Volare<h3>
<p>飞天梦</p>
</div>
</div>

<div class="music" data-music="https://ws6.stream.qqmusic.qq.com/C4000029rUxI0mAMF1.m4a?guid=7779539200&vkey=182B987983B145090ABE2276E112C79D5EBF267B1DE606FA983381DB8F002AE5F80D746BC19EB1B16E4E1659830D4D93B90378B4C6E1A4ED&uin=1152921504695982864&fromtag=120032&src=C400002eIhPp1rMKw9.m4a">
<img src="https://y.qq.com/music/photo_new/T002R300x300M000000AlbzG4DewiX.jpg?max_age=2592000" alt="Album Cover">
<div class="music-info">
<h3>Tifa's Theme<h3>
<p>Tifa's Theme</p>
</div>
</div>

<div class="music" data-music="https://api.liumingye.cn/m/api/link?id=d3f636iePH3nJMVUD1wHoQ2G0euQyv-U1R9WjW8zZeUIIj3mccA&quality=128&_t=1720351608093&token=20240531.2354a7d0ee396c5ff495bb89bfaa334f">
<img src="https://y.qq.com/music/photo_new/T002R300x300M000002QETBK4JYkmb.jpg?max_age=2592000" alt="Album Cover">
<div class="music-info">
<h3>The Wolven Storm<h3>
<p>The Wolven Storm</p>
</div>
</div>

<div class="music" data-music="https://ws6.stream.qqmusic.qq.com/C400002Uob6p0hkBSb.m4a?guid=543775640&vkey=1C868FE1F472808CB646D3B65416DFA5B8BB5F97BDEBEC1CB740BAB5559808832C2312F174C60772CB9FB3BFEBD047D16A13BD6228C50EF7&uin=1152921504695982864&fromtag=120032">
<img src="https://y.qq.com/music/photo_new/T002R300x300M000003E43vM1ZG6XB.jpg?max_age=2592000" alt="Album Cover">
<div class="music-info">
<h3>Ezio's Family<h3>
<p>刺客信条</p>
</div>
</div>

<div class="music" data-music="https://ws6.stream.qqmusic.qq.com/C4000012S7kP4cT9fF.m4a?guid=5938620496&vkey=0B8BC643868950E58A120AD874A6C4A08117DEB31B4344F51192D7FE7405AA5EF7036FAAB235F2405139DE8BF2749AC2E1D416E193AF3BCF&uin=1152921504695982864&fromtag=120032">
<img src="https://y.qq.com/music/photo_new/T002R300x300M000003kSOKf1RdYr8.jpg?max_age=2592000" alt="Album Cover">
<div class="music-info">
<h3>Main Theme<h3>
<p>钢铁雄心</p>
</div>
</div>

<div class="music" data-music="https://ws6.stream.qqmusic.qq.com/C400003B5hh30XZz38.m4a?guid=7024553980&vkey=653752A81F7ADD154A3F95339D2ABC1B6B0AE5D877B2D7790BE21C9A25D3613F26F3D79781929EBFFA41DD1A92F4BD709339EADC7744F4EB&uin=1152921504695982864&fromtag=120032">
<img src="https://y.qq.com/music/photo_new/T002R300x300M000000K79PQ1MPzdB_2.jpg?max_age=2592000" alt="Album Cover">
<div class="music-info">
<h3>I Really Want to Stay at Your House<h3>
<p>Lucy…</p>
</div>
</div>

<div class="music" data-music="https://ws6.stream.qqmusic.qq.com/C400002YWRfw1pH18h.m4a?guid=4599792750&vkey=6342535075BD87206289BF080A23E857323BAEFBDA86182B331D3B5535A8430A747CDA736C86F8E01C50DB6E25BF473811B3CD6D58AF50F1&uin=1152921504695982864&fromtag=120032">
<img src="https://y.qq.com/music/photo_new/T002R300x300M000000zpV4e0Rpecf.jpg?max_age=2592000" alt="Album Cover">
<div class="music-info">
<h3>Promise<h3>
<p>寂静岭2</p>
</div>
</div>

</div>

<input type="range" id="progress" value="0" step="1">
<button id="playPauseButton">Play</button>

<script>
var audio = new Audio();
var progress = document.getElementById("progress");
var playPauseButton = document.getElementById("playPauseButton");

var musicList = document.querySelectorAll('.music');
musicList.forEach(function(music) {
music.addEventListener("click", function() {
audio.src = music.getAttribute('data-music');
audio.play();
playPauseButton.textContent = "Pause";
});
});

progress.addEventListener("input", function() {
audio.currentTime = progress.value;
});

audio.addEventListener("timeupdate", function() {
progress.value = audio.currentTime;
});

audio.addEventListener("canplay", function() {
progress.max = audio.duration;
});

playPauseButton.addEventListener("click", function() {
if (audio.paused) {
audio.play();
playPauseButton.textContent = "Pause";
} else {
audio.pause();
playPauseButton.textContent = "Play";
}
});
</script>

</body>
</html>

可以实现一个专辑墙的效果,并且搭配有进度条和播放暂停按钮,可以实现音乐的播放。

python 自动生成脚本

musicWall.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import pandas as pd

# 读取Excel表格数据
df = pd.read_excel('music.xlsx')

# 生成HTML代码
html_code = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Music Playlist</title>
<style>
.music {
width: 200px;
height: 200px;
border: 1px solid #ccc;
text-align: center;
margin: 10px;
float: left;
cursor: pointer;
position: relative;
transition: transform 0.3s;
}

.music img {
max-width: 100%;
max-height: 100%;
}

.music:hover {
transform: scale(1.1);
}

.music-info {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
display: none;
}

.music:hover .music-info {
display: block;
}

#playlist {
display: flex;
flex-wrap: wrap;
justify-content: center;
}

#progress {
width: 100%;
height: 10px;
border-radius: 5px;
background: linear-gradient(to right, #ff7e5f, #feb47b);
}

input[type="range"] {
-webkit-appearance: none;
appearance: none;
}

input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 15px;
height: 15px;
border-radius: 50%;
background: #ff7e5f;
cursor: pointer;
}
#playPauseButton {
background: #ff7e5f;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
}

</style>
</head>
<body>

<div id="playlist">
"""

for index, row in df.iterrows():
html_code += f"""
<div class="music" data-music="{row['音乐url']}">
<img src="{row['专辑封面url']}" alt="Album Cover">
<div class="music-info">
<h3>{row['音乐名']}<h3>
<p>{row['描述']}</p>
</div>
</div>
"""

html_code += """
</div>

<input type="range" id="progress" value="0" step="1">
<button id="playPauseButton">Play</button>

<script>
var audio = new Audio();
var progress = document.getElementById("progress");
var playPauseButton = document.getElementById("playPauseButton");

var musicList = document.querySelectorAll('.music');
musicList.forEach(function(music) {
music.addEventListener("click", function() {
audio.src = music.getAttribute('data-music');
audio.play();
playPauseButton.textContent = "Pause";
});
});

progress.addEventListener("input", function() {
audio.currentTime = progress.value;
});

audio.addEventListener("timeupdate", function() {
progress.value = audio.currentTime;
});

audio.addEventListener("canplay", function() {
progress.max = audio.duration;
});

playPauseButton.addEventListener("click", function() {
if (audio.paused) {
audio.play();
playPauseButton.textContent = "Pause";
} else {
audio.pause();
playPauseButton.textContent = "Play";
}
});
</script>

</body>
</html>
"""

# 将生成的HTML代码保存到文件
with open('music_playlist.html', 'w', encoding='utf-8') as file:
file.write(html_code)

print("Done!")

直接把 Excel 表格中的数据读取出来,然后生成 HTML 代码,保存到文件中。
运行即可,直接得到完整的 HTML 文件。

这个功能有一个问题:在线音源比较难找,所以被废弃了(自己云储存对象的话太贵了

python 脚本: 替换图片链接

mdConvert.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import re
# 读取md文件内容
def read_md_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
return file.read()

# 替换图片链接并写入新文件
def replace_and_write(content, new_file_path):
new_content = re.sub(r'!\[\[([^]]+)\]\]', r'<img src="ae490517/\1"/>', content)
with open(new_file_path, 'w', encoding='utf-8') as file:
file.write(new_content)

def main():
md_file_path = r'......\blog1\source\_posts\课程笔记-ZJU-CTF101安全攻防实践.md'
new_file_path = r'......\blog1\source\_posts\课程笔记-ZJU-CTF101安全攻防实践.md' # 新文件路径
content = read_md_file(md_file_path)
replace_and_write(content, new_file_path)
print("Done!")

if __name__ == "__main__":
main()

同样是解决 obsidian 图片引用格式无法被 hexo 正常识别的问题

obsidian 中原生的图片引用方式为

1
![[Pasted image 20240521093347.png]]

该程序会自动进行正则匹配r'!\[\[([^]]+)\]\]'会将其更换为 HTML 中的格式

1
2
<img src="ae490517/\1" />
<!-- 其中\1为正则匹配到的内容, ae490517为图片存储的路径(文章的十六进制缩写路径, 因为使用了一个压缩文章路径的插件) -->
1
python .\mdConvert.py

执行即可一键替换该 markdwon 文件中的所有图片引用格式