前言
我从以前就有搭过好几次博客,有一次发现博客的随机图片网页可以直接打开,遂发现了api,也尝试过存下来,不过是取base64的最后5个字母。现在我重新看到这个接口,翻两下甚至还有不少熟悉的,感到十分怀念,然后就想写一个脚本保存一下。
接口: https://www.dmoe.cc/random.php
请爱惜使用,不要暴力爬取呦。
一些废话:以前还觉得是害羞的见不得光的什么"二次元",现在再看居然有不少我已经看过了,都是前朝遗老了,不由感叹。我也变成老登了。
脚本
import requests
import time
import random
import hashlib
while True:
res=requests.get("https://www.dmoe.cc/random.php")
content=res.content
img_md5 = hashlib.md5(content).hexdigest()
with open(f"wallpaper/{str(img_md5)}.jpg", "wb") as f:
f.write(content)
print(img_md5)
time.sleep(random.random()*1.5)爬虫逻辑
很简单,直接使用requests.get(),连header和Content-Type都不用设置。
文件保存逻辑
我们可以使用python自带的hashlib来实现hash算法
注意,md5是hash的一种,不止md5可以实现hash功能
type(res.content)是<class 'bytes'>hashlib.md5()的传入类型要求是<class 'bytes'>hashlib.md5().digest()的返回值是<class 'bytes'>返回hash后的二进制结果hashlib.md5().digest()的返回值是<class 'str'>返回hash后的十六进制字符串结果
当然也可以把二进制图片base64编码一下,再encode然后hashlib。比如
import base64,hashlib
b64_str = base64.b64encode(img_bytes).decode("utf-8") # bytes -> base64字符串
hash_value = hashlib.sha256(b64_str.encode("utf-8")).hexdigest()hash算法简介
主要用于:数据校验,文件指纹,签名
特点:
结果稳定
- 同样输入永远得到同样输出
- 通常输出为十六进制字符串
MD5
- 输出 128 位
- 很快
- 已不安全
- 已经可以构造碰撞
适合:
- 普通去重
- 非安全场景的内容标识
不适合:
- 数字签名
- 安全校验
- 密码存储
SHA1
- 输出 160 位
- 比 MD5 强一些
- 也已不安全
- 也存在实际碰撞攻击
- 一般也不建议用于安全场景。
SHA256
- 输出 256 位
- 安全性高很多
- 目前广泛使用
- 速度比 MD5/SHA1 稍慢,但通常完全够用
适合:
- 文件完整性校验
- 签名
- 安全摘要
SHA512
- 输出 512 位
- 更长、更强
- 摘要更大
- 在某些 64 位平台上不一定比 SHA256 慢很多
适合:
- 需要更长摘要的场景
- 高安全需求场景
python实现
import hashlib
s = "hello"
print("md5 =", hashlib.md5(s.encode()).hexdigest())
print("sha1 =", hashlib.sha1(s.encode()).hexdigest())
print("sha256=", hashlib.sha256(s.encode()).hexdigest())
print("sha512=", hashlib.sha512(s.encode()).hexdigest())但这些仍然不安全,密码存储应该用:
bcrypt
scrypt
argon2
或 hashlib.pbkdf2_hmac
python内置hash函数
print(hash("hello"))
适合:
- 放到 set
- 作为 dict 的键
- 程序内部快速比较/索引
注意:
Python 的字符串哈希 默认每次运行可能不同。你今天运行和下次运行,结果可能不一样。这是 Python 的安全机制(hash 随机化)。
所以:
- 适合程序内部使用
- 不适合做持久化、签名、跨进程一致的值(不能存数据库)
有点类似C++的std::mt19937,适合用在算法里。
拓展:一个数学问题
我们假设图片样本空间有限;每次调用api等概率地返回一张图片。
那么:
- 假设一共有5000张图片,爬取k次,有几张重复?
- 假设我们爬取k次,重复了n张,我们可以估计样本集有多大?
- 假设我们要k张图片,样本集有N张图片,我们要抽X次,X的期望是多少?
不过,概率终归是概率,脸黑起来也没办法。
后记:一些唠叨
本来就想写个小脚本的,没想到东看看西瞧瞧写了那么多有意思的东西。写代码也许就是为了打发时间,没什么理由或者意义。有什么有趣的,看到就去琢磨一下。也不用定什么目标,先写个小脚本。最近想看看汪曾祺的《人间草木》,单琢磨一些草草树树,他一个文人也能看得那么起劲,也许就是打发时间吧。不过我一个工科生也不太懂啦。主要最近实在没什么好看的,也许是录取通知书还没下来,心焦吧。



































































































































