From c738b98b44ae8e28d0b6c1361b020748f87e5c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=A6=E6=83=B3=E6=A9=A1=E7=9A=AE=E6=93=A6?= Date: Tue, 10 Jan 2023 17:04:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=8D=E7=88=AC=E6=A1=88=E4=BE=8B=EF=BC=8C?= =?UTF-8?q?=E6=89=8B=E6=9C=BA=E8=BD=AC=E6=8D=A2=E4=B8=BA=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++ app/__init__.py | 4 + .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 137 bytes .../__pycache__/index.cpython-36.pyc | Bin 0 -> 1137 bytes app/apis/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 131 bytes app/apis/__pycache__/index.cpython-36.pyc | Bin 0 -> 2722 bytes app/apis/index.py | 74 ++++++++++-------- app/filter_fun.py | 3 + app/templates/base.html | 1 + app/templates/hw/rank.html | 5 +- app/templates/index.html | 74 ++++++++++++------ app/templates/timeline.html | 41 ++++++++++ app/templates/user/index.html | 51 +++++++++--- app/templates/user/index_bak.html | 40 ++++++++++ app/user/__pycache__/index.cpython-36.pyc | Bin 434 -> 1511 bytes app/user/index.py | 36 ++++++++- playground.py | 2 +- 17 files changed, 267 insertions(+), 69 deletions(-) create mode 100644 app/antispider/__pycache__/__init__.cpython-36.pyc create mode 100644 app/antispider/__pycache__/index.cpython-36.pyc create mode 100644 app/apis/__pycache__/__init__.cpython-36.pyc create mode 100644 app/apis/__pycache__/index.cpython-36.pyc create mode 100644 app/filter_fun.py create mode 100644 app/templates/user/index_bak.html diff --git a/README.md b/README.md index 8648f8e..1059a3e 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 a6a24f7..7cd4779 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 GIT binary patch literal 137 zcmXr!<>g{ATa(NH1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFEe+mn1afZjQqU# z;)2YS)S~!;oW#oXqWsdll$gYVf|$g-l1zw9OniK1US>&ryk0@&Ee@O9{FKt1R6CG) I#X!se06&`{%K!iX literal 0 HcmV?d00001 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 GIT binary patch literal 1137 zcmZ`&y>HV%6u&#iiQ{~<4Ic&Cfe{ZhNM%9@@i8!wrDCxnStfUBocfD9M>JMpXkcJK zfM|zGFfg*vLI)(oU*Z)tG&^0Gcz11RR256_=kvRF@BQBIo);?>bMyCZE7cJCi6$N$ z*0;gLGXRPx_ECUs91xoXnym#nI~VA-j^!SKy}X^rh+(R+0?kqVm1Y~v=oV?77M`O4 zwu|s(Qe%K=k($a=Ql1ic%Cw?9W#y@YXNpcMPle7bA*(h54#?88;$6STV(x`WR_KZ- z^xFNbz}e#-6G>)pMm^42u-D_h(~h`>vnkF(%D9uTAoksaWu_Y@o`^kgrdr(<5M#>l zn6tLG+LDFjgTV;cJuqx=g13mVadDIJO(~aZiaj#7eWLRB@`&so7 z18JCZBwGOz3CRJGGB&V5a)j65E7j|w6FvDSh>8GEf*7z!U?v6_8YYc&_P9{J=Q{G> zLMI7)3v-!Yv7LY!@MXGUBufb?G$Q;AU|Os*&Le*P+T!V@r9@PNvbn~AJpAj&_r0CB zdoOlJ8=v=HuManO#=@S3U4Bl26ze1?4#v3FEJTcHoQHK@P^p7Xd8oXedEEL&SkVpo*9l4x&d<>E-zY* pL#D%2B~0BBmkOzjr;Bg9Z-jU1z1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnF9Ub0n1afZjQqU# z;)2YS)S~!;oW#oXqWsdll$gYV0wB&Tj){-Y%*!l^kJl@xyv1RYo1apelWGStsThbE E0DNd4b^rhX literal 0 HcmV?d00001 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 GIT binary patch literal 2722 zcmZuz-ESPX5npom_Vzw>lJ#xNcGEU!dqE@lBbS^5)m7b~f!jh!6QBteE)J_B@3iaN z4|933B&>iIr#=dO=wFe4q40mvH@+4{q1Qh8rTq=hmIWt!;BYt`k~5qiXYT&OLi6mO zFNVKsInKYFD_;%#9$NVVL^y&?oRozu>S`X`K5C&G}P8wkY zbMB-WHf`SuTefe9ZOMcu7er0?=Wf`MtzJRvv(8N3(<{uJ#0*alwTvymR+&AD=pvlhkI;DXUoG z)8)*#LwM?Ng?m1lG)8ufVwq7HgNr zf9KCUoWl+Kd>^;knr1Qfl_JuS35JoD<6Iq^Cayy1@_DQejhib0eZGCiu;I6k+Q2C< z-~aUEC&jTo%(FpR#6qe;F^P`HDxYTJNmLYQarq?9ggn|Vj$bx+MLg8QJS`q>k)>p| z@0`3hmU^I~OyubRlPPu^9!6?=cajgIN%?U5&9ZLGczGc+!}HR3MFhjVB#$%Gnn!Ig z7bzJD!UC)rN>eMfiVM@wIHR1vIpfbyGyd=}kB1UBz(!&F%GqVue65`;!%FM!oNU5q zv;O@iUn8$NAdY*31-#7yx8tsI^;1YL0YzTlMzeqtU?@m}&4EO)A*hH3y%Eu-mmwDE zHHc-gB38wkSQi^&Q(PA}#Fn@zZjEmNMvl0R5dT2DbLMDQ{BUMr205z$xeef=`=kBP zy?g%-k-J3h5xGy~10p>l9}@Y9NT0|9kRGk*(TX0e=+TNEDfdXZN6I}??vZkzl>4OI zC*?jV_i6h+t?1K=KCS4}iv9z&NY`=|!)*vkYCi`7g5RAZ7-{D_*E4R;*dHC{JmaDX z_gaPln0F1kXV`tiJ}|6j*oTIFWLV#@2m4*FevCcUyCC4#&>1#(E37XYyJMNjqe4A= z4+<8ao^$du5-Q+kPyp$2kWJGAc@>_o7hMFjyZ7cKb&Jla0c~T6$Kzk7nCS?q=B?As z+V`GA7MGNO9KOkx*$uwQRUf01U?=(p?^TtT$XbH9j%JbdUoeC$-~yM2RD@hkco6(4 zS9i3Fq{Jje=Y z0XDF=FPf)yv_P~@8&yMiTh3{-s#ncT=d@J?wr|rI=Pb||eW$7=ovKx}tA(mF@_^~i zIcE-}i{g64Djx{Hc8&_Amy&C+cCqr3TxUs#-7(6ck{7oR@5*aLU*Kai7!5sJZ1S{@&6YdyNS3E3D8-`?IU=CeIT z2)+0V2okV|dNaA8ns7m2MNmE3L+xP@xTj|ZYG~ALPO|L^;3k+ zFwkmhtx%MJ6*+7%swg3abvc>DMJbJ^B?=FZb5nnGtY!K5Gvk%fH<&1;e5zb1cbC)y zS`!>b^K>0HUUPTfu=h;OUP9;zvVnkU*pXq!#-GS+tPd64qVXnjq>Zcd0*@sgA8O+t zIV7ISiIGROEu&O2_f5^NL}ch0D#AjShwZDmL48d#R3hhu zYKE1Oyrl3r+=t0l*4;9-(IhILDmvd@uHDqeHgrFK{CgWv8%rC-d48cd%JV?wxqcJ>Ie5q^L?NGQX>aOnU#wT; ikO_9vTudkOAwjkz(I#Jgb=?8)@SD8j1uH>ox%+=y-;b*R literal 0 HcmV?d00001 diff --git a/app/apis/index.py b/app/apis/index.py index e70e0a5..182f17a 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 0000000..3cf71f5 --- /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 29a7483..3c187ac 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 c77462b..16d4364 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 37d6848..d33e1b3 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 e894225..f63607b 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 540dbaa..f27b888 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 0000000..b3b603c --- /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 GIT binary patch literal 1511 zcmYjROK;>v5blRx<9X$^(SnfRfCMA434&#XP!z2~#3~XBh($uOva+1%o{7DFrQP1m zM9#@MlEYpRe}EssAL%Qn`3rl2DjRLqqb}Ec)m2@Oul@CS?7!Lld;W(-$Uo%0#|Hf= ztm=0Vf(V+Dj0QAg0n2#6DPjyTE3iQ4!bE6>|DyeYghVaDTjt85<7sFc;Y{|`JTZ~#N#$s|yS{m#K=Q){8*N_pJ zaWgndYgwu|*Tzk%B99j<<0^Ss%Sz9vnJSqJsX{HYGL5ucv)*lYDRro#TohS2FS4x2 z!}&#|%!8%OrGkxNc~Rst%A-SCDbzL+$m;bJPhJLtR~CZm?zSPf0ajU@)czhjg%Rx%N8OTj)(HsIf8 z3;j#B#1LZJjSXGgI5qs2XGiNCl34Gc_!q?WcmZ|nXVvOrPwT~c12Bcj&zP~$1Ts$3 zfS36aN^};5$|8Mj*Lv~j+Zj{c{!QG^)fW1`6JW$ReK3Bn_rSLD!Dx6cU#lT#frYJA zBUC-DYN=PHG_0tMg>x`gQpC9$ppT{Hl{PFcjC-`wvO4+6SXJ~&f|T;5an7SkK6z{g z=T9EXd|n7?JRrcU2)JV$ArYB5#_ncr>=>sTSOQPSt{8q^F9LK9JJVl8eFpH`N6)@H zD_0tb5>{o5Gy{&Uma3?8aTb;384}?v1_EB~l`AvqDWwaDvc#$?Yz$!&>eF4m#XO4I zj-_UR0)OH;n(^VV@Gf?Y`4tpRVBX~FsYc$gmK~E9U)@l_6DBNS-x9!`mL9{rkw*;y zMgg0&jSLX(pA1=Xx%C^-j_?`+H;w@t{L_9SI66b#(G_nDCh#0qm+_J`xju}rpR02mGynkj9mU%T^wKilH#BL#{vQ`*V;M^C+zj_wIMC zv1H_29%WLY&-D~Ly5D&{nK6Yug`5g(tIn420Oe~Yp77Hd&{X-O(r8`NNsI