22. 听说你想要用爬虫采集我的手机号?哎 ~ 我展示用的是图片

举报
梦想橡皮擦 发表于 2023/03/30 18:06:11 2023/03/30
【摘要】 本篇博客我们实现图片渲染手机号码案例,用于防止爬虫直接采集文字信息。爬虫训练场本案例实现的效果如下所示@[toc] bootstrap5 实现名片样式卡片在 Bootstrap5 中实现一个名片样式,可以直接使用卡片模板,示例代码如下。<div class="card" style="width: 18rem;"> <img src="image.jpg" class="card-img-...

本篇博客我们实现图片渲染手机号码案例,用于防止爬虫直接采集文字信息。
爬虫训练场
本案例实现的效果如下所示
image.png

@[toc]

bootstrap5 实现名片样式卡片

在 Bootstrap5 中实现一个名片样式,可以直接使用卡片模板,示例代码如下。

<div class="card" style="width: 18rem;">
  <img src="image.jpg" class="card-img-top" alt="image" />
  <div class="card-body">
    <h5 class="card-title">梦想橡皮擦</h5>
    <p class="card-text">爬虫训练场项目主导人</p>
    <a href="#" class="btn btn-primary">点击去他的博客</a>
  </div>
</div>

该例子使用了 .card 类来创建名片卡片,但我们还需要进行一下修改,将图片修改为圆形,可以使用 Bootstrap 的 .avatar 类。

<div class="card" style="width: 18rem;">
  <img src="image.jpg" class="avatar avatar-sm" alt="image" />
  <div class="card-body">
    <h5 class="card-title">梦想橡皮擦</h5>
    <p class="card-text">爬虫训练场项目主导人</p>
    <a href="#" class="btn btn-primary">点击去他的博客</a>
  </div>
</div>

这里使用了 .avatar 类和 .avatar-sm 类来创建头像。.avatar 类用于创建圆形图像,而 .avatar-sm 类用于调整头像的大小。

还需要手动添加一些样式,圆角,阴影和背景色。

.card {
  border-radius: 10px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
  background-color: white;
}

简单的调整样式之后,就可以编写核心代码环节了,重点是 user/index.py 文件的修改,该文件承接所有页面数据逻辑。

补充数据生成逻辑

本部分代码由三部分组成,分别是:

  1. 生成用户 5 个汉字的昵称;
  2. 用昵称调用头像生成 API,生成头像
  3. 调用随机手机号接口,生成手机号,并将其转换为图片。

步骤罗列完毕,下面开始逐一实现。

生成用户 5 个汉字的昵称

在过往的博客中,我们已经实现了随机汉字的生成,参考文章为 《Python 随机生成一个汉字》,在这篇文章中,重点函数为 get_random_common_char(),接下来将其进行封装,并在 user/index.py 中进行导入。

from ..apis.index import get_random_common_char, generate_phone_number,static_path

特别提醒:爬虫训练场项目为综合项目,前后有很强的承接性,大家在阅读学习的时候,尽量中间不要有停顿。

可以看到在模块导入时,我们将 apis.index 模块中的 get_random_common_char()generate_phone_number() 函数 和 static_path 变量都进行了导入,然后调用对应函数即可完成目标需求。

例如,生成 5 个汉字昵称:

name = "".join([get_random_common_char() for i in range(5)])

调用头像 API,生成图片

本步骤相对简单,仅修改 免费头像 API 博客对应的接口逻辑即可。

在视图函数中补充接口参数解析逻辑,如果传递 name 参数,则获取前 2 个汉字,示例代码如下:

name = request.args.get("name", '空值')
han_char = ''  # 待生成的字符串

if name == '空值':
	# 执行默认逻辑
else:
	# 截取前2个汉字

最后只需要在模板页面,调用该接口传入参数即可。

<img
  src="{{url_for('apis.index')}}?name={{item.name}}"
  class="avatar avatar-sm"
  alt="image"
/>

将手机号码生成图片

该步骤是本案例的核心逻辑,为了防止爬虫采集数据,需要将文字内容转换成图片形式展现。文字转图片依旧使用 pillow 库。

这里首先封装一个基本函数,在 user/index.py 中编写代码即可。

# 手机号码转换为图片
def phone_to_img(phone):
    # 生成图片
    image = Image.new('RGB', (110, 20), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    font = ImageFont.truetype(os.path.join(static_path, 'font/msyh.ttf'), 16)


    draw.text((0, 0), phone, font=font, fill=(0, 0, 0))

    buf = io.BytesIO()
    image.save(buf, format='png')
    buf.seek(0)
    b64_image = base64.b64encode(buf.getvalue()).decode('utf-8')

    # 转为 base64 编码

    return b64_image

可以看到,上述代码实例化了一个长 110 像素,宽 20 像素的白色背景区域,然后在其上部绘制手机号码,特别需要注意的地方是我们需要将图片转换为 BLOB,即二进制图片格式。

buf = io.BytesIO()
image.save(buf, format='png')
buf.seek(0)

但是 _io.BytesIO 对象是无法在模板引擎中进行图像渲染的,还需要将其转换为 base64 编码。

所有的代码编写完毕,我们就可以在模板中,使用 data: URL 格式来显示图像,示例代码如下:

<img src="data:image/png;base64, {{ item.phone }}" />

完整案例可以下载源码之后,查看 templates/user/index.html 文件内容。

此外,这里还可以使用 jinja2 自定义过滤器实现,首先在项目 app 目录中建立 filter_fun.py 文件,用于放置所有过滤器代码,然后编写 datauri() 函数,内容如下。

def datauri(uri):
    return f'data:image/png;base64,{uri}'

最后一个步骤就是在 flask 中注册该过滤器,打开 app/__init__.py 文件,输入如下代码。

# 导入过滤器
from .filter_fun import datauri
app.jinja_env.filters['datauri'] = datauri

回到模板文件中,手机号码图片的加载就可以使用过滤器展示。

<img src="{{ item.phone|datauri  }}" alt="phone" />

本案例到此结束,已更新到 爬虫训练场 欢迎大家访问学习。
项目同步到代码仓库 https://gitcode.net/hihell/spider_playground

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 826 篇原创博客

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。