diff --git a/README.md b/README.md index 8648f8eb6f817582dab0284b6897574ba0195274..1059a3e29b8b812dedefb07cfd5a197cbac3c56b 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,11 @@ 2. [【小知识点】Python Flask 部署,生成环境的爬虫训练场项目](https://blog.csdn.net/hihell/article/details/128422613) 3. [【小知识点】给PythonWeb项目添加百度统计,爬虫训练场](https://blog.csdn.net/hihell/article/details/128448271) 4. [【小知识点】为爬虫训练场项目添加 Bootstrap5 时间轴](https://dream.blog.csdn.net/article/details/128543088) +5. [【小知识点】Python Flask 中使用 cryptography 模块实现加密](https://blog.csdn.net/hihell/article/details/128569293?spm=1001.2014.3001.5501) +6. [【小知识点】Python 随机生成一个汉字,提供了多种办法,目的竞然是用于创建头像](https://blog.csdn.net/hihell/article/details/128582632?spm=1001.2014.3001.5501) +7. [【小知识点】免费头像API,用 Python Flask 动态生成一个汉字头像](https://blog.csdn.net/hihell/article/details/128583823?spm=1001.2014.3001.5501) +8. [【小知识点】Python随机生成 Phone 号码,测试用~](https://blog.csdn.net/hihell/article/details/128594941?spm=1001.2014.3001.5501) +9. [【小知识点】Centos 自动任务,定时执行 Python 脚本](https://blog.csdn.net/hihell/article/details/128600920?spm=1001.2014.3001.5501) ## 站点数据储备博客 diff --git a/app/__init__.py b/app/__init__.py index a6a24f71c9de07dd672e0a33a1da329b62fd591e..7cd47794c6a4a8fd3cf7acd216fbce00855dbaec 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -7,9 +7,13 @@ from .config import BaseConfig # 导入配置文件 from flask_limiter import Limiter from flask_limiter.util import get_remote_address, get_ipaddr +# 导入过滤器 +from .filter_fun import datauri + app = Flask(__name__) app.config.from_object(BaseConfig) # 启用配置 +app.jinja_env.filters['datauri'] = datauri def get_real_ip(): diff --git a/app/antispider/__pycache__/__init__.cpython-36.pyc b/app/antispider/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da34b17b33ba8fd71070fe71d86303e409a12573 Binary files /dev/null and b/app/antispider/__pycache__/__init__.cpython-36.pyc differ diff --git a/app/antispider/__pycache__/index.cpython-36.pyc b/app/antispider/__pycache__/index.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a17f924b4aff2f8b8b8df998007a559a19bd40c8 Binary files /dev/null and b/app/antispider/__pycache__/index.cpython-36.pyc differ diff --git a/app/apis/__pycache__/__init__.cpython-36.pyc b/app/apis/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b7314c6394a85083fba305acd1cd07d042672d6 Binary files /dev/null and b/app/apis/__pycache__/__init__.cpython-36.pyc differ diff --git a/app/apis/__pycache__/index.cpython-36.pyc b/app/apis/__pycache__/index.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca290a7521757691335d4d1a2dd6514bd3ff3ccb Binary files /dev/null and b/app/apis/__pycache__/index.cpython-36.pyc differ diff --git a/app/apis/index.py b/app/apis/index.py index e70e0a55d0552e4b73523743e29a1f09eb0642c6..182f17a53f234105eb83c5beb2c933b94fe27249 100644 --- a/app/apis/index.py +++ b/app/apis/index.py @@ -1,4 +1,4 @@ -from flask import Blueprint, send_file, jsonify +from flask import Blueprint, send_file, jsonify, request from PIL import Image, ImageDraw, ImageFont import random @@ -8,35 +8,55 @@ import io api = Blueprint('apis', __name__, url_prefix='/api') +app_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -@api.route('/avatars') -def index(): - app_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +static_path = os.path.join(app_root, 'static') + + +# 生成随机汉字 +def get_random_common_char(): + # 读取文件中的常用汉字 + + with open(os.path.join(static_path, 'demo.txt'), 'r', encoding='utf-8') as f: + common_chars = f.read() + # 去除空格 + common_chars = common_chars.replace(' ', '') + common_chars = common_chars.strip() - static_path = os.path.join(app_root, 'static') + # 创建字符映射表 + translator = {ord(c): None for c in common_chars if unicodedata.category(c).startswith('P')} - # 生成随机汉字 - def get_random_common_char(): - # 读取文件中的常用汉字 + # 使用字符映射表去除标点符号 + s = common_chars.translate(translator) - with open(os.path.join(static_path, 'demo.txt'), 'r', encoding='utf-8') as f: - common_chars = f.read() - # 去除空格 - common_chars = common_chars.replace(' ', '') - common_chars = common_chars.strip() + return random.choice(s) - # 创建字符映射表 - translator = {ord(c): None for c in common_chars if unicodedata.category(c).startswith('P')} - # 使用字符映射表去除标点符号 - s = common_chars.translate(translator) +# 生成电话号码 +def generate_phone_number(): + # 随机生成手机号码的前缀 + prefix = random.choice(['130', '131', '132', '133', '134', '135', '136', '137', '138', '139', + '150', '151', '152', '153', '155', '156', '157', '158', '159', + '180', '181', '182', '183', '184', '185', '186', '187', '188', '189']) + # 随机生成手机号码的后缀 + suffix = ''.join(random.choice(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) for _ in range(8)) + # 将前缀和后缀组合起来,生成手机号码 + return prefix + suffix - return random.choice(s) - # 可以生成任意内容 - han_char1 = get_random_common_char() - han_char2 = get_random_common_char() - han_char = han_char1 + han_char2 +@api.route('/avatars') +def index(): + name = request.args.get("name", '空值') + han_char = '' # 待生成的字符串 + + if name == '空值': + + # 可以生成任意内容 + han_char1 = get_random_common_char() + han_char2 = get_random_common_char() + han_char = han_char1 + han_char2 + else: + han_char = name[:2] # 生成图片 image = Image.new('RGB', (64, 64), (255, 255, 255)) draw = ImageDraw.Draw(image) @@ -67,16 +87,6 @@ def index(): @api.route('/phone') def phone(): - def generate_phone_number(): - # 随机生成手机号码的前缀 - prefix = random.choice(['130', '131', '132', '133', '134', '135', '136', '137', '138', '139', - '150', '151', '152', '153', '155', '156', '157', '158', '159', - '180', '181', '182', '183', '184', '185', '186', '187', '188', '189']) - # 随机生成手机号码的后缀 - suffix = ''.join(random.choice(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) for _ in range(8)) - # 将前缀和后缀组合起来,生成手机号码 - return prefix + suffix - phone_number = generate_phone_number() phone = { 'phone': phone_number diff --git a/app/filter_fun.py b/app/filter_fun.py new file mode 100644 index 0000000000000000000000000000000000000000..3cf71f53b2107a280608c0386bd47f94c063e4b0 --- /dev/null +++ b/app/filter_fun.py @@ -0,0 +1,3 @@ +from jinja2 import Template +def datauri(uri): + return f'data:image/png;base64,{uri}' \ No newline at end of file diff --git a/app/templates/base.html b/app/templates/base.html index 29a7483107188ea5c03f40e491b6a8962efeef91..3c187ac2f31a2a0d65919714624302e35099c9ea 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -4,6 +4,7 @@ {% include 'common/header.html'%} {% block link %}{% endblock link %} + {% block style %}{% endblock style %} {% block script %}{% endblock script %} {% include 'common/tj.html'%} diff --git a/app/templates/hw/rank.html b/app/templates/hw/rank.html index c77462b22b40d06dcac3e7a53bb447fe23466112..16d4364ed083e9a25e1557fb46b87e89432ceb67 100644 --- a/app/templates/hw/rank.html +++ b/app/templates/hw/rank.html @@ -7,6 +7,7 @@ padding:3px;} +
@@ -14,8 +15,8 @@ padding:3px;}

华为云社区月更榜
- 【<2023年1月数据>】 -

+ 【<2023年1月数据>】 +

数据每小时同步一次

diff --git a/app/templates/index.html b/app/templates/index.html index 37d68482c0f75ecc67bb80338b80218cef4a0058..d33e1b3f46f6047e430d0001040d5bbb2244a919 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -24,7 +24,8 @@

@@ -45,7 +46,8 @@

@@ -67,8 +69,9 @@

@@ -89,8 +92,9 @@

@@ -114,8 +118,9 @@

@@ -136,7 +141,8 @@

@@ -165,8 +171,9 @@ @@ -175,9 +182,6 @@

定值 Cookie 反爬

-
最新更新 -

本案例要求爬虫程序在采集时,必须在请求头中携带固定 Cookie 值,如果缺少无法访问。

@@ -199,9 +203,7 @@

简易响应加密

-
最新更新 -
+

本案例请求数据接口之后,会返回加密值,在前台需要对加密串进行解密,然后在渲染数据。

@@ -212,8 +214,9 @@

@@ -234,12 +237,15 @@

-
+
+
+

IP 限制爬虫

@@ -256,7 +262,31 @@

+
+
+
+
+
+

手机号码图片展示

+
最新更新 +
+
+
+

本案例将重要信息手机号码以图片形式展示,爬虫程序无法通过简单提取获取手机号码

+

难度:⭐⭐

+

+ 案例: + 名片 +

+
+
diff --git a/app/templates/timeline.html b/app/templates/timeline.html index e894225ba0bf2e9cbafbd36de70168754898bf4c..f63607ba20eb8b697915646812cd4f24d628ad0d 100644 --- a/app/templates/timeline.html +++ b/app/templates/timeline.html @@ -16,6 +16,47 @@ 正在更新中 + +
+ +
+ +
+
+
+

爬虫训练场 V0.18.0 发布

+
+
+

上线手机号码转图片案例,已上线案例 12 个,同时更新2款API接口,分别如下

+ +
+ +
+
+
+ +
+ +
+
+
+

爬虫训练场 V0.17.0 发布

+
+
+

上线华为云社区月更榜单

+
+ +
+
+ +
diff --git a/app/templates/user/index.html b/app/templates/user/index.html index 540dbaae2a36a8cf09dd7b5e2d6e29144b053220..f27b888730ae6d765e8b672107d6286addc91b93 100644 --- a/app/templates/user/index.html +++ b/app/templates/user/index.html @@ -1,10 +1,41 @@ - - - - - Title - - - - - \ No newline at end of file +{% extends "base.html" %} +{% block style %} + + +{% endblock style %} +{% block content %} + +
+
+ + {% for item in user_data %} + +
+
+
+

+ image +

+
+ {{item.name}}
+

联系方式:phone

+
+
+
+ + + {% endfor %} + +
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/user/index_bak.html b/app/templates/user/index_bak.html new file mode 100644 index 0000000000000000000000000000000000000000..b3b603c5d7aeab4ce69a69240cec873d3f35f68a --- /dev/null +++ b/app/templates/user/index_bak.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} +{% block style %} + + +{% endblock style %} +{% block content %} + +
+
+ + {% for item in user_data %} + +
+
+
+

+ image +

+
+ {{item.name}}
+

联系方式:phone

+
+
+
+ + + {% endfor %} + +
+
+{% endblock %} \ No newline at end of file diff --git a/app/user/__pycache__/index.cpython-36.pyc b/app/user/__pycache__/index.cpython-36.pyc index 318572cc45713d20a63b74b6ad94b8a07d9e58ae..36084369660880076ba9e35ff10688b90a42b4a7 100644 Binary files a/app/user/__pycache__/index.cpython-36.pyc and b/app/user/__pycache__/index.cpython-36.pyc differ diff --git a/app/user/index.py b/app/user/index.py index eb8ca5e78b1d347999f7b7c8521aa316e4f5b34b..a05e7195a52c597f4cd38cdab86a7b534c68f3a0 100644 --- a/app/user/index.py +++ b/app/user/index.py @@ -1,11 +1,43 @@ from flask import Blueprint, jsonify, request from flask import render_template - +from ..apis.index import get_random_common_char, generate_phone_number,static_path +from PIL import Image, ImageDraw, ImageFont +import os +import io +import base64 u = Blueprint('user', __name__, url_prefix='/u') +# 手机号码转换为图片 +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 + @u.route('/i') def index(): - return render_template('user/index.html') + # 随机生成用户姓名 + ret = list() + for i in range(0, 20): + name = "".join([get_random_common_char() for i in range(5)]) + ret.append({ + "name": name, + "phone": phone_to_img(generate_phone_number()) + }) + + return render_template('user/index.html', user_data=ret) diff --git a/playground.py b/playground.py index d10813f0abab68d8e8e7765edc7ff79ebe255fcf..25d9dfd6c2e0a28c8f5aef2417dcc70649ebde31 100644 --- a/playground.py +++ b/playground.py @@ -1,6 +1,6 @@ from app import app -# app.jinja_env.auto_reload = True +app.jinja_env.auto_reload = True app.config['TEMPLATES_AUTO_RELOAD'] = True