{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-04-23-serverless-scf-api","result":{"data":{"currentBlog":{"id":"5e61ae27-a6be-5a1e-a7bd-06ddaaab5c3d","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020523/1590208707614-16201.jpg","authors":["乂乂又又"],"categories":["user-stories"],"date":"2020-04-23T00:00:00.000Z","title":"万物皆可 Serverless 之使用云函数 SCF 快速部署验证码识别接口","description":"验证码识别是搞爬虫实现自动化脚本避不开的一个问题，通常验证码识别程序要么部署在本地，要么部署在服务器端，如果部署在服务器端就需要自己去搭建配置网络环境并编写调用接口，这是一个极其繁琐耗时的过程。但是现在我们通过无服务器云函数 SCF，就可以快速将本地的验证码识别程序发布上线，极大地提高了开发效率。","authorslink":["https://cloud.tencent.com/developer/article/1615839"],"translators":null,"translatorslink":null,"tags":["爬虫","云函数"],"keywords":"Serverless,Serverless SCF,Serverless应用","outdated":null},"wordCount":{"words":131,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-23-serverless-scf-api.md","fields":{"slug":"/blog/2020-04-23-serverless-scf-api/","keywords":["java","python","serverless","无服务器","无服务器云函数","云函数","验证码","putpixel","range","识别"]},"html":"<p>验证码识别是搞爬虫实现自动化脚本避不开的一个问题。通常验证码识别程序要么部署在本地，要么部署在服务器端。如果部署在服务器端就需要自己去搭建配置网络环境并编写调用接口，这是一个极其繁琐耗时的过程。</p>\n<p>但是现在我们通过腾讯云云函数 SCF，就可以快速将本地的验证码识别程序发布上线，极大地提高了开发效率。</p>\n<h2 id=\"效果展示\"><a href=\"#%E6%95%88%E6%9E%9C%E5%B1%95%E7%A4%BA\" aria-label=\"效果展示 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>效果展示</h2>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590208707883-16201.jpg\" alt=\"一种比较简单的验证码\"></p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590208707787-16201.jpg\" alt=\"识别扭曲变形的验证码\"></p>\n<p>可以看到，识别效果还是蛮好的，甚至超过了肉眼识别率。</p>\n<h2 id=\"操作步骤\"><a href=\"#%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4\" aria-label=\"操作步骤 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>操作步骤</h2>\n<p>传统的验证码识别流程是</p>\n<ol>\n<li>图像预处理（灰化，去噪，切割，二值化，去干扰线等）</li>\n<li>验证码字符特征提取（SVM，CNN 等）</li>\n<li>验证码识别</li>\n</ol>\n<p>下面我就带大家一起来创建、编写并发布上线一个验证识别云函数</p>\n<h3 id=\"第一步：新建-python-云函数\"><a href=\"#%E7%AC%AC%E4%B8%80%E6%AD%A5%EF%BC%9A%E6%96%B0%E5%BB%BA-python-%E4%BA%91%E5%87%BD%E6%95%B0\" aria-label=\"第一步：新建 python 云函数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第一步：新建 python 云函数</h3>\n<p>参见系列文章<a href=\"https://serverlesscloud.cn/blog/2020-04-23-serverless-scf-cos/\">《万物皆可Serverless之使用 SCF+COS 快速开发全栈应用》</a></p>\n<h3 id=\"第二步：编写验证识别云函数\"><a href=\"#%E7%AC%AC%E4%BA%8C%E6%AD%A5%EF%BC%9A%E7%BC%96%E5%86%99%E9%AA%8C%E8%AF%81%E8%AF%86%E5%88%AB%E4%BA%91%E5%87%BD%E6%95%B0\" aria-label=\"第二步：编写验证识别云函数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第二步：编写验证识别云函数</h3>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590208707700-16201.jpg\" alt=\"一个简单的验证码\"></p>\n<blockquote>\n<p>Life is short, show me the code.</p>\n</blockquote>\n<p>这里我就以一个最简单的验证码识别程序为例，直接上代码</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"53942454459052060000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import io\nimport os\nimport time\nfrom PIL import Image as image\nimport json\n\n#字符特征\nchars = {\n    '1': [1, 1, 1, 0, 1, ...],\n    '2': [1, 0, 0, 1, 0, ...],\n    '3': [0, 1, 0, 0, 1, ...],\n    # 其他字符特征...\n}\n\n\n# 灰度处理\ndef covergrey(img):\n    return img.convert('L')\n\n# 去除验证码边框\ndef clearedge(img):\n    for y in range(img.size[1]):\n        img.putpixel((0, y), 255)\n        img.putpixel((1, y), 255)\n        img.putpixel((2, y), 255)\n        img.putpixel((img.size[0]-1, y), 255)\n        img.putpixel((img.size[0]-2, y), 255)\n        img.putpixel((img.size[0]-3, y), 255)\n    for x in range(img.size[0]):\n        img.putpixel((x, 0), 255)\n        img.putpixel((x, 1), 255)\n        img.putpixel((x, 2), 255)\n        img.putpixel((x, img.size[1]-1), 255)\n        img.putpixel((x, img.size[1]-2), 255)\n        img.putpixel((x, img.size[1]-3), 255)\n    return img\n\n# 去除干扰线并转换为黑白照片\ndef clearline(img):\n    for y in range(img.size[1]):\n        for x in range(img.size[0]):\n            if int(img.getpixel((x, y))) >= 110:\n                img.putpixel((x, y), 0xff)\n            else:\n                img.putpixel((x, y), 0x0)\n    return img\n\n# 去噪/pnum-去噪效率\ndef del_noise(im, pnum=3):\n    w, h = im.size\n    white = 255\n    black = 0\n    for i in range(0, w):\n        im.putpixel((i, 0), white)\n        im.putpixel((i, h - 1), white)\n    for i in range(0, h):\n        im.putpixel((0, i), white)\n        im.putpixel((w - 1, i), white)\n    for i in range(1, w - 1):\n        for j in range(1, h - 1):\n            val = im.getpixel((i, j))\n            if val == black:\n                cnt = 0\n                for ii in range(-1, 2):\n                    for jj in range(-1, 2):\n                        if im.getpixel((i + ii, j + jj)) == black:\n                            cnt += 1\n                if cnt < pnum:\n                    im.putpixel((i, j), white)\n            else:\n                cnt = 0\n                for ii in range(-1, 2):\n                    for jj in range(-1, 2):\n                        if im.getpixel((i + ii, j + jj)) == black:\n                            cnt += 1\n                if cnt >= 7:\n                    im.putpixel((i, j), black)\n    return im\n\n# 图片数据二值化\ndef two_value(code_data):\n    table = [serverless]\n    for i in code_data:\n        if i < 140:  # 二值化分界线140\n            table.append(0)\n        else:\n            table.append(1)\n    return table\n\n# 图片预处理\ndef pre_img(img):\n    img = covergrey(img)  # 去色\n    img = clearedge(img)  # 去边\n    img = clearline(img)  # 去线\n    img = del_noise(img)  # 去噪\n    return img\n\n# 处理图片数据\ndef data_img(img):\n    code_data = [serverless]  # 验证码数据列表\n    for i in range(4):  # 切割验证码\n        x = 5 + i * 18  # 可用PS确定图片切割位置\n        code_data.append(img.crop((x, 9, x + 18, 33)).getdata())\n        code_data[i] = two_value(code_data[i])  # 二值化数据\n    return code_data\n\n# 验证码识别\ndef identify(data):\n    code = ['']*4  # 验证码字符列表\n    diff_min = [432]*4  # 初始化最小距离--不符合的数据点个数（共120数据点）\n    for char in chars:  # 遍历验证码字符（每个字符比较一次4个验证码）\n        diff = [0]*4  # 各验证码差距值(每个字符判断前重置此距离)\n        for i in range(4):  # 计算四个验证码\n            for j in range(432):  # 逐个像素比较验证码特征\n                if data[i][j] != chars[char][j]:\n                    diff[i] += 1  # 距离+1\n        for i in range(4):\n            if diff[i] < diff_min[i]:  # 比已有距离还要小（更加符合）\n                diff_min[i] = diff[i]  # 刷新最小距离\n                code[i] = char  # 刷新最佳验证码\n    return ''.join(code)  # 输出结果\n\n\ndef predict(imgs):\n    code = ''\n    img = imgs.read()\n    img = image.open(io.BytesIO(img))\n    img = pre_img(img)  # 预处理图片\n    data = data_img(img)  # 获取图片数据\n    code = identify(data)  # 识别验证码\n    return code\n\n\ndef apiReply(reply, code=200):\n    return {\n        &quot;isBase64Encoded&quot;: False,\n        &quot;statusCode&quot;: code,\n        &quot;headers&quot;: {'Content-Type': 'application/json', &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;},\n        &quot;body&quot;: json.dumps(reply, ensure_ascii=False)\n    }\n\n\ndef main_handler(event, context):\n    main_start = time.time()\n    flag = True if 'image' in event['queryString'] else False\n    code = predict(event['queryString']['image']) if 'image' in event['queryString'] else '无效的请求'\n    return apiReply({\n        'ok': flag,\n        'code': code,\n        'spendTime': str(time.time()-main_start)\n    })`, `53942454459052060000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> io\n<span class=\"token keyword\">import</span> os\n<span class=\"token keyword\">import</span> time\n<span class=\"token keyword\">from</span> <span class=\"token constant\">PIL</span> <span class=\"token keyword\">import</span> Image <span class=\"token keyword\">as</span> image\n<span class=\"token keyword\">import</span> json\n\n#字符特征\nchars <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token string\">'1'</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">'2'</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">'3'</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    # 其他字符特征<span class=\"token operator\">...</span>\n<span class=\"token punctuation\">}</span>\n\n\n# 灰度处理\ndef <span class=\"token function\">covergrey</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> img<span class=\"token punctuation\">.</span><span class=\"token function\">convert</span><span class=\"token punctuation\">(</span><span class=\"token string\">'L'</span><span class=\"token punctuation\">)</span>\n\n# 去除验证码边框\ndef <span class=\"token function\">clearedge</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">for</span> y <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token operator\">-</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token operator\">-</span><span class=\"token number\">3</span><span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">for</span> x <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token operator\">-</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n        img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token operator\">-</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">255</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> img\n\n# 去除干扰线并转换为黑白照片\ndef <span class=\"token function\">clearline</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">for</span> y <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">for</span> x <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">if</span> <span class=\"token function\">int</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span><span class=\"token function\">getpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> <span class=\"token number\">110</span><span class=\"token punctuation\">:</span>\n                img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0xff</span><span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n                img<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0x0</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> img\n\n# 去噪<span class=\"token operator\">/</span>pnum<span class=\"token operator\">-</span>去噪效率\ndef <span class=\"token function\">del_noise</span><span class=\"token punctuation\">(</span>im<span class=\"token punctuation\">,</span> pnum<span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    w<span class=\"token punctuation\">,</span> h <span class=\"token operator\">=</span> im<span class=\"token punctuation\">.</span>size\n    white <span class=\"token operator\">=</span> <span class=\"token number\">255</span>\n    black <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> w<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        im<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> white<span class=\"token punctuation\">)</span>\n        im<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">,</span> h <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> white<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> h<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        im<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> white<span class=\"token punctuation\">)</span>\n        im<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>w <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> white<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> w <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">for</span> j <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> h <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            val <span class=\"token operator\">=</span> im<span class=\"token punctuation\">.</span><span class=\"token function\">getpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">,</span> j<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">if</span> val <span class=\"token operator\">==</span> black<span class=\"token punctuation\">:</span>\n                cnt <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n                <span class=\"token keyword\">for</span> ii <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n                    <span class=\"token keyword\">for</span> jj <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n                        <span class=\"token keyword\">if</span> im<span class=\"token punctuation\">.</span><span class=\"token function\">getpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i <span class=\"token operator\">+</span> ii<span class=\"token punctuation\">,</span> j <span class=\"token operator\">+</span> jj<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> black<span class=\"token punctuation\">:</span>\n                            cnt <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>\n                <span class=\"token keyword\">if</span> cnt <span class=\"token operator\">&lt;</span> pnum<span class=\"token punctuation\">:</span>\n                    im<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">,</span> j<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> white<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n                cnt <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n                <span class=\"token keyword\">for</span> ii <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n                    <span class=\"token keyword\">for</span> jj <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n                        <span class=\"token keyword\">if</span> im<span class=\"token punctuation\">.</span><span class=\"token function\">getpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i <span class=\"token operator\">+</span> ii<span class=\"token punctuation\">,</span> j <span class=\"token operator\">+</span> jj<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> black<span class=\"token punctuation\">:</span>\n                            cnt <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>\n                <span class=\"token keyword\">if</span> cnt <span class=\"token operator\">>=</span> <span class=\"token number\">7</span><span class=\"token punctuation\">:</span>\n                    im<span class=\"token punctuation\">.</span><span class=\"token function\">putpixel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">,</span> j<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> black<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> im\n\n# 图片数据二值化\ndef <span class=\"token function\">two_value</span><span class=\"token punctuation\">(</span>code_data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    table <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>serverless<span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> code_data<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">140</span><span class=\"token punctuation\">:</span>  # 二值化分界线<span class=\"token number\">140</span>\n            table<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n            table<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> table\n\n# 图片预处理\ndef <span class=\"token function\">pre_img</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    img <span class=\"token operator\">=</span> <span class=\"token function\">covergrey</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 去色\n    img <span class=\"token operator\">=</span> <span class=\"token function\">clearedge</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 去边\n    img <span class=\"token operator\">=</span> <span class=\"token function\">clearline</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 去线\n    img <span class=\"token operator\">=</span> <span class=\"token function\">del_noise</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 去噪\n    <span class=\"token keyword\">return</span> img\n\n# 处理图片数据\ndef <span class=\"token function\">data_img</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    code_data <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>serverless<span class=\"token punctuation\">]</span>  # 验证码数据列表\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 切割验证码\n        x <span class=\"token operator\">=</span> <span class=\"token number\">5</span> <span class=\"token operator\">+</span> i <span class=\"token operator\">*</span> <span class=\"token number\">18</span>  # 可用<span class=\"token constant\">PS</span>确定图片切割位置\n        code_data<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">.</span><span class=\"token function\">crop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> <span class=\"token number\">9</span><span class=\"token punctuation\">,</span> x <span class=\"token operator\">+</span> <span class=\"token number\">18</span><span class=\"token punctuation\">,</span> <span class=\"token number\">33</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getdata</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        code_data<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">two_value</span><span class=\"token punctuation\">(</span>code_data<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>  # 二值化数据\n    <span class=\"token keyword\">return</span> code_data\n\n# 验证码识别\ndef <span class=\"token function\">identify</span><span class=\"token punctuation\">(</span>data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    code <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token string\">''</span><span class=\"token punctuation\">]</span><span class=\"token operator\">*</span><span class=\"token number\">4</span>  # 验证码字符列表\n    diff_min <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token number\">432</span><span class=\"token punctuation\">]</span><span class=\"token operator\">*</span><span class=\"token number\">4</span>  # 初始化最小距离<span class=\"token operator\">--</span>不符合的数据点个数（共<span class=\"token number\">120</span>数据点）\n    <span class=\"token keyword\">for</span> char <span class=\"token keyword\">in</span> chars<span class=\"token punctuation\">:</span>  # 遍历验证码字符（每个字符比较一次<span class=\"token number\">4</span>个验证码）\n        diff <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token operator\">*</span><span class=\"token number\">4</span>  # <span class=\"token function\">各验证码差距值</span><span class=\"token punctuation\">(</span>每个字符判断前重置此距离<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 计算四个验证码\n            <span class=\"token keyword\">for</span> j <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">432</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 逐个像素比较验证码特征\n                <span class=\"token keyword\">if</span> data<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span> <span class=\"token operator\">!=</span> chars<span class=\"token punctuation\">[</span>char<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>\n                    diff<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>  # 距离<span class=\"token operator\">+</span><span class=\"token number\">1</span>\n        <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">if</span> diff<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> diff_min<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>  # 比已有距离还要小（更加符合）\n                diff_min<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> diff<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span>  # 刷新最小距离\n                code<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> char  # 刷新最佳验证码\n    <span class=\"token keyword\">return</span> <span class=\"token string\">''</span><span class=\"token punctuation\">.</span><span class=\"token function\">join</span><span class=\"token punctuation\">(</span>code<span class=\"token punctuation\">)</span>  # 输出结果\n\n\ndef <span class=\"token function\">predict</span><span class=\"token punctuation\">(</span>imgs<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    code <span class=\"token operator\">=</span> <span class=\"token string\">''</span>\n    img <span class=\"token operator\">=</span> imgs<span class=\"token punctuation\">.</span><span class=\"token function\">read</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    img <span class=\"token operator\">=</span> image<span class=\"token punctuation\">.</span><span class=\"token function\">open</span><span class=\"token punctuation\">(</span>io<span class=\"token punctuation\">.</span><span class=\"token function\">BytesIO</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    img <span class=\"token operator\">=</span> <span class=\"token function\">pre_img</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 预处理图片\n    data <span class=\"token operator\">=</span> <span class=\"token function\">data_img</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 获取图片数据\n    code <span class=\"token operator\">=</span> <span class=\"token function\">identify</span><span class=\"token punctuation\">(</span>data<span class=\"token punctuation\">)</span>  # 识别验证码\n    <span class=\"token keyword\">return</span> code\n\n\ndef <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span>reply<span class=\"token punctuation\">,</span> code<span class=\"token operator\">=</span><span class=\"token number\">200</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token string\">\"isBase64Encoded\"</span><span class=\"token punctuation\">:</span> False<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"statusCode\"</span><span class=\"token punctuation\">:</span> code<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"headers\"</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span><span class=\"token string\">'Content-Type'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'application/json'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Access-Control-Allow-Origin\"</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"*\"</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"body\"</span><span class=\"token punctuation\">:</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">dumps</span><span class=\"token punctuation\">(</span>reply<span class=\"token punctuation\">,</span> ensure_ascii<span class=\"token operator\">=</span>False<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n\ndef <span class=\"token function\">main_handler</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    main_start <span class=\"token operator\">=</span> time<span class=\"token punctuation\">.</span><span class=\"token function\">time</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    flag <span class=\"token operator\">=</span> True <span class=\"token keyword\">if</span> <span class=\"token string\">'image'</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'queryString'</span><span class=\"token punctuation\">]</span> <span class=\"token keyword\">else</span> False\n    code <span class=\"token operator\">=</span> <span class=\"token function\">predict</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">[</span><span class=\"token string\">'queryString'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'image'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">if</span> <span class=\"token string\">'image'</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'queryString'</span><span class=\"token punctuation\">]</span> <span class=\"token keyword\">else</span> <span class=\"token string\">'无效的请求'</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        <span class=\"token string\">'ok'</span><span class=\"token punctuation\">:</span> flag<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">'code'</span><span class=\"token punctuation\">:</span> code<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">'spendTime'</span><span class=\"token punctuation\">:</span> <span class=\"token function\">str</span><span class=\"token punctuation\">(</span>time<span class=\"token punctuation\">.</span><span class=\"token function\">time</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-</span>main_start<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>老规矩，先捋一下整个云函数的流程。</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"8090201388850104000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`def main_handler(event, context):\n    main_start = time.time()\n    flag = True if 'image' in event['queryString'] else False\n    code = predict(event['queryString']['image']) if 'image' in event['queryString'] else '无效的请求'\n    return apiReply({\n        'ok': flag,\n        'code': code,\n        'spendTime': str(time.time()-main_start)\n    })`, `8090201388850104000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">def <span class=\"token function\">main_handler</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    main_start <span class=\"token operator\">=</span> time<span class=\"token punctuation\">.</span><span class=\"token function\">time</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    flag <span class=\"token operator\">=</span> True <span class=\"token keyword\">if</span> <span class=\"token string\">'image'</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'queryString'</span><span class=\"token punctuation\">]</span> <span class=\"token keyword\">else</span> False\n    code <span class=\"token operator\">=</span> <span class=\"token function\">predict</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">[</span><span class=\"token string\">'queryString'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token string\">'image'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">if</span> <span class=\"token string\">'image'</span> <span class=\"token keyword\">in</span> event<span class=\"token punctuation\">[</span><span class=\"token string\">'queryString'</span><span class=\"token punctuation\">]</span> <span class=\"token keyword\">else</span> <span class=\"token string\">'无效的请求'</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        <span class=\"token string\">'ok'</span><span class=\"token punctuation\">:</span> flag<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">'code'</span><span class=\"token punctuation\">:</span> code<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">'spendTime'</span><span class=\"token punctuation\">:</span> <span class=\"token function\">str</span><span class=\"token punctuation\">(</span>time<span class=\"token punctuation\">.</span><span class=\"token function\">time</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-</span>main_start<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>首先，我们通过 event 事件拿到 api 请求的验证码 image 数据，然后判断一下 image 参数是否存在，若不存在就返回请求无效的提示</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"76458946538216300000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`def predict(imgs):\n    code = ''\n    img = imgs.read()\n    img = image.open(io.BytesIO(img))\n    img = pre_img(img)  # 预处理图片\n    data = data_img(img)  # 获取图片数据\n    code = identify(data)  # 识别验证码\n    return code`, `76458946538216300000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">def <span class=\"token function\">predict</span><span class=\"token punctuation\">(</span>imgs<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    code <span class=\"token operator\">=</span> <span class=\"token string\">''</span>\n    img <span class=\"token operator\">=</span> imgs<span class=\"token punctuation\">.</span><span class=\"token function\">read</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    img <span class=\"token operator\">=</span> image<span class=\"token punctuation\">.</span><span class=\"token function\">open</span><span class=\"token punctuation\">(</span>io<span class=\"token punctuation\">.</span><span class=\"token function\">BytesIO</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    img <span class=\"token operator\">=</span> <span class=\"token function\">pre_img</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 预处理图片\n    data <span class=\"token operator\">=</span> <span class=\"token function\">data_img</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 获取图片数据\n    code <span class=\"token operator\">=</span> <span class=\"token function\">identify</span><span class=\"token punctuation\">(</span>data<span class=\"token punctuation\">)</span>  # 识别验证码\n    <span class=\"token keyword\">return</span> code</code></pre></div>\n<p>如果 image 请求参数存在就调用 predict 函数解析识别验证码，流程如下：</p>\n<ol>\n<li>读取验证码图像</li>\n<li>验证码图像预处理</li>\n<li>识别处理后的验证码</li>\n</ol>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"18947083037190240000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`# 图片预处理\ndef pre_img(img):\n    img = covergrey(img)  # 去色\n    img = clearedge(img)  # 去边\n    img = clearline(img)  # 去线\n    img = del_noise(img)  # 去噪\n    return img`, `18947083037190240000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"># 图片预处理\ndef <span class=\"token function\">pre_img</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    img <span class=\"token operator\">=</span> <span class=\"token function\">covergrey</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 去色\n    img <span class=\"token operator\">=</span> <span class=\"token function\">clearedge</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 去边\n    img <span class=\"token operator\">=</span> <span class=\"token function\">clearline</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 去线\n    img <span class=\"token operator\">=</span> <span class=\"token function\">del_noise</span><span class=\"token punctuation\">(</span>img<span class=\"token punctuation\">)</span>  # 去噪\n    <span class=\"token keyword\">return</span> img</code></pre></div>\n<p>我们来看一下图像预处理过程</p>\n<ol>\n<li>将验证码去色，转为灰度图</li>\n<li>去除验证码黑色边框</li>\n<li>去除验证码干扰线</li>\n<li>去除验证码噪点</li>\n</ol>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"25608072528580640000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`#字符特征\nchars = {\n    '1': [1, 1, 1, 0, 1, ...],\n    '2': [1, 0, 0, 1, 0, ...],\n    '3': [0, 1, 0, 0, 1, ...],\n    # 其他字符特征...\n}\n\n# 验证码识别\ndef identify(data):\n    code = ['']*4  # 验证码字符列表\n    diff_min = [432]*4  # 初始化最小距离--不符合的数据点个数（共120数据点）\n    for char in chars:  # 遍历验证码字符（每个字符比较一次4个验证码）\n        diff = [0]*4  # 各验证码差距值(每个字符判断前重置此距离)\n        for i in range(4):  # 计算四个验证码\n            for j in range(432):  # 逐个像素比较验证码特征\n                if data[i][j] != chars[char][j]:\n                    diff[i] += 1  # 距离+1\n        for i in range(4):\n            if diff[i] < diff_min[i]:  # 比已有距离还要小（更加符合）\n                diff_min[i] = diff[i]  # 刷新最小距离\n                code[i] = char  # 刷新最佳验证码\n    return ''.join(code)  # 输出结果`, `25608072528580640000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">#字符特征\nchars <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token string\">'1'</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">'2'</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">'3'</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    # 其他字符特征<span class=\"token operator\">...</span>\n<span class=\"token punctuation\">}</span>\n\n# 验证码识别\ndef <span class=\"token function\">identify</span><span class=\"token punctuation\">(</span>data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    code <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token string\">''</span><span class=\"token punctuation\">]</span><span class=\"token operator\">*</span><span class=\"token number\">4</span>  # 验证码字符列表\n    diff_min <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token number\">432</span><span class=\"token punctuation\">]</span><span class=\"token operator\">*</span><span class=\"token number\">4</span>  # 初始化最小距离<span class=\"token operator\">--</span>不符合的数据点个数（共<span class=\"token number\">120</span>数据点）\n    <span class=\"token keyword\">for</span> char <span class=\"token keyword\">in</span> chars<span class=\"token punctuation\">:</span>  # 遍历验证码字符（每个字符比较一次<span class=\"token number\">4</span>个验证码）\n        diff <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token operator\">*</span><span class=\"token number\">4</span>  # <span class=\"token function\">各验证码差距值</span><span class=\"token punctuation\">(</span>每个字符判断前重置此距离<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 计算四个验证码\n            <span class=\"token keyword\">for</span> j <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">432</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  # 逐个像素比较验证码特征\n                <span class=\"token keyword\">if</span> data<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span> <span class=\"token operator\">!=</span> chars<span class=\"token punctuation\">[</span>char<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>\n                    diff<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>  # 距离<span class=\"token operator\">+</span><span class=\"token number\">1</span>\n        <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token function\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">if</span> diff<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> diff_min<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>  # 比已有距离还要小（更加符合）\n                diff_min<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> diff<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span>  # 刷新最小距离\n                code<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> char  # 刷新最佳验证码\n    <span class=\"token keyword\">return</span> <span class=\"token string\">''</span><span class=\"token punctuation\">.</span><span class=\"token function\">join</span><span class=\"token punctuation\">(</span>code<span class=\"token punctuation\">)</span>  # 输出结果</code></pre></div>\n<p>PS：文章中的字符特征 chars 并不完整，你可能需要自行提取所有特征。</p>\n<p>最后来看一下验证码的识别过程：这里我们直接简单粗暴地取处理后图像数据的所有像素点作为字符的特征（所谓大道至简），然后将每个待识别字符处理后图像的数据与所有字符的特征逐个比较，取最相似的那个字符作为识别结果。</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590208707602-16201.jpg\" alt=\"正确的识别结果\"></p>\n<p>嗯，没什么问题的话，你就可以得到正确的识别结果了。</p>\n<h3 id=\"第三步：上线发布云函数、添加-api-网关触发器、启用响应集成\"><a href=\"#%E7%AC%AC%E4%B8%89%E6%AD%A5%EF%BC%9A%E4%B8%8A%E7%BA%BF%E5%8F%91%E5%B8%83%E4%BA%91%E5%87%BD%E6%95%B0%E3%80%81%E6%B7%BB%E5%8A%A0-api-%E7%BD%91%E5%85%B3%E8%A7%A6%E5%8F%91%E5%99%A8%E3%80%81%E5%90%AF%E7%94%A8%E5%93%8D%E5%BA%94%E9%9B%86%E6%88%90\" aria-label=\"第三步：上线发布云函数、添加 api 网关触发器、启用响应集成 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第三步：上线发布云函数、添加 API 网关触发器、启用响应集成</h3>\n<p>参见系列文章<a href=\"https://serverlesscloud.cn/blog/2020-04-23-serverless-scf-cos/\">《万物皆可 Serverless 之使用 SCF+COS 快速开发全栈应用》</a></p>\n<h2 id=\"写在最后\"><a href=\"#%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E\" aria-label=\"写在最后 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>写在最后</h2>\n<p>当然，以上只是以一个简单的验证码识别为例，对于一些比较复杂的验证码，你也可以使用 Tensorflow，Pytorch 等深度学习计算框架搭建、训练模型，然后将训练好的模型借助无服务器云函数快速上线发布使用。</p>\n<hr>\n<div id='scf-deploy-iframe-or-md'></div>\n<hr>\n<blockquote>\n<p><strong>传送门：</strong></p>\n<ul>\n<li>GitHub: <a href=\"https://github.com/serverless/serverless/blob/master/README_CN.md\">github.com/serverless</a></li>\n<li>官网：<a href=\"https://serverless.com/\">serverless.com</a></li>\n</ul>\n</blockquote>\n<p>欢迎访问：<a href=\"https://serverlesscloud.cn/\">Serverless 中文网</a>，您可以在 <a href=\"https://serverlesscloud.cn/best-practice\">最佳实践</a> 里体验更多关于 Serverless 应用的开发！</p>","tableOfContents":"<ul>\n<li><a href=\"/blog/2020-04-23-serverless-scf-api/#%E6%95%88%E6%9E%9C%E5%B1%95%E7%A4%BA\">效果展示</a></li>\n<li>\n<p><a href=\"/blog/2020-04-23-serverless-scf-api/#%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4\">操作步骤</a></p>\n<ul>\n<li><a href=\"/blog/2020-04-23-serverless-scf-api/#%E7%AC%AC%E4%B8%80%E6%AD%A5%EF%BC%9A%E6%96%B0%E5%BB%BA-python-%E4%BA%91%E5%87%BD%E6%95%B0\">第一步：新建 python 云函数</a></li>\n<li><a href=\"/blog/2020-04-23-serverless-scf-api/#%E7%AC%AC%E4%BA%8C%E6%AD%A5%EF%BC%9A%E7%BC%96%E5%86%99%E9%AA%8C%E8%AF%81%E8%AF%86%E5%88%AB%E4%BA%91%E5%87%BD%E6%95%B0\">第二步：编写验证识别云函数</a></li>\n<li><a href=\"/blog/2020-04-23-serverless-scf-api/#%E7%AC%AC%E4%B8%89%E6%AD%A5%EF%BC%9A%E4%B8%8A%E7%BA%BF%E5%8F%91%E5%B8%83%E4%BA%91%E5%87%BD%E6%95%B0%E3%80%81%E6%B7%BB%E5%8A%A0-api-%E7%BD%91%E5%85%B3%E8%A7%A6%E5%8F%91%E5%99%A8%E3%80%81%E5%90%AF%E7%94%A8%E5%93%8D%E5%BA%94%E9%9B%86%E6%88%90\">第三步：上线发布云函数、添加 API 网关触发器、启用响应集成</a></li>\n</ul>\n</li>\n<li><a href=\"/blog/2020-04-23-serverless-scf-api/#%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E\">写在最后</a></li>\n</ul>"},"previousBlog":{"id":"4c7906fb-df88-5132-96f0-3613754d9e05","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/202068/1591592316812-13ui2js5xx.png","authors":["乂乂又又"],"categories":["user-stories"],"date":"2020-04-23T00:00:00.000Z","title":"万物皆可 Serverless 之使用云函数 Timer 触发器实现每天自动定时打卡","description":"本文并不探讨如何编写自动化的操作脚本，而是和大家介绍一下如何使用腾讯云函数的 Timer 触发器实现定时任务，来快速、稳定、低成本地实现一些 fancy 的操作。","authorslink":["https://cloud.tencent.com/developer/article/1612169"],"translators":null,"translatorslink":null,"tags":["Serverless","云函数"],"keywords":"Serverless,云函数触发器,Serverless应用","outdated":null},"wordCount":{"words":196,"sentences":60,"paragraphs":60},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-23-serverless-timer-scf.md","fields":{"slug":"/blog/2020-04-23-serverless-timer-scf/","keywords":["java","python","serverless","spa","云函数","message","errorinfo","函数","mail","requests","toAddr","email"]}},"nextBlog":{"id":"e0959654-d44e-59c0-8201-19822e61b38d","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020523/1590204021386-16200.jpg","authors":["乂乂又又"],"categories":["user-stories"],"date":"2020-04-23T00:00:00.000Z","title":"万物皆可 Serverless 之使用云函数 SCF+COS 免费运营微信公众号","description":"是的，你没听错，这一次我来带大家直接上手运营微信公众号","authorslink":["https://cloud.tencent.com/developer/article/1612816"],"translators":null,"translatorslink":null,"tags":["云函数","对象存储"],"keywords":"Serverless,Serverless微信,Serverless应用","outdated":null},"wordCount":{"words":271,"sentences":67,"paragraphs":67},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-23-serverless-wechat-cos.md","fields":{"slug":"/blog/2020-04-23-serverless-wechat-cos/","keywords":["java","python","serverless","腾讯云无服务器云函数","无服务器","无服务器云函数","云函数","reply","requestParameters","微信","timestamp","nonce","signature"]}},"recommendBlogs":{"edges":[{"node":{"id":"4300b21c-7209-5256-86ff-0d38e3daec9b","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/14f1c8eed372e76c1b139703b2f6d0fa.jpg","authors":["KieranMcCarthy"],"categories":["user-stories","engineering-culture"],"date":"2018-01-09T00:00:00.000Z","title":"我是如何在四年时间里，从厨师转行为 Serverless 应用开发者","description":"我是厨师出身，现在成为了一名 Serverless 应用开发者。","authorslink":["https://serverless.com/author/kieranmccarthy/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["应用开发","Serverless"],"keywords":"Serverless 应用开发,Serverless 管理,厨师转行为 Serverless 应用开发者","outdated":null},"wordCount":{"words":285,"sentences":38,"paragraphs":36},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years.md","fields":{"slug":"/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years/","keywords":["无服务器","无服务器开发","云函数","学习","Serverless","构建","Framework","开发者","服务器","应用","学位","简历"]}}},{"node":{"id":"713a0563-4bf9-5721-bacb-3b4ef609fe4a","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/camp-fire/camp-fire-housing-thumb.jpg","authors":["EricWyne"],"categories":["guides-and-tutorials","user-stories"],"date":"2018-12-05T00:00:00.000Z","title":"Serverless Twitter 机器人帮助为坎普山火受灾者安置住房","description":"加利福尼亚州的坎普山火致使数千人流离失所，为此，我构建了一个简单的 Serverless Twitter 机器人来帮助将受灾者安置在临时住房！","authorslink":["https://serverless.com/author/ericwyne/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":157,"sentences":26,"paragraphs":26},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-05-serverless-twitter-camp-fire.md","fields":{"slug":"/blog/2018-12-05-serverless-twitter-camp-fire/","keywords":["serverless","无服务器","云函数","Serverless","org","住房","Twitter","函数","受灾","机器人","山火"]}}},{"node":{"id":"98602143-b837-5f50-a24f-3b1ec76044d7","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/sqquid/sqquid-serverless-thumb.jpg","authors":["RonPeled"],"categories":["user-stories"],"date":"2018-12-17T00:00:00.000Z","title":"SQQUID：100% 无服务器初创公司","description":"SQQUID 将 AWS Lambda 和无服务器框架用于其核心产品和营销网站。我们来看看一个完全无服务器的初创公司是怎样的。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":266,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-17-sqquid-one-hundred-percent-serverless.md","fields":{"slug":"/blog/2018-12-17-sqquid-one-hundred-percent-serverless/","keywords":["go","serverless","无服务器","无服务器架构","服务器","架构","Lambda","集成","FaaS","串行","系统"]}}},{"node":{"id":"29dc2e58-d2ba-56f9-aee1-d21b0bc62e0e","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/ao-com-story/ao-serverless-thumbnail.png","authors":["NickGottlieb"],"categories":["user-stories"],"date":"2019-04-24T00:00:00.000Z","title":"AO.com：逐渐转向无服务器优先","description":"AO.com 的 SCV 团队率先尝试无服务器服务。折服于无服务器框架的快速周转时间和低维护成本，整个团队逐渐转向无服务器优先。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":236,"sentences":42,"paragraphs":35},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-04-24-ao-serverless-first.md","fields":{"slug":"/blog/2019-04-24-ao-serverless-first/","keywords":["serverless","无服务器","服务器","团队","Lambda","功能","构建"]}}},{"node":{"id":"752d08d1-387a-5bde-acf3-98141baab294","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020414/1586871710979-%E5%85%AC%E5%85%B1%E7%94%A8.png","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-06-20T00:00:00.000Z","title":"如何用 Serverless 为 Python 云函数打包依赖","description":"在使用无服务器云函数SCF时通常会遇到导入第三方库的问题，很多小伙伴比较头疼是：应该如何打包进去？这里，推荐几个不错的方法。","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["云函数","Serverless"],"keywords":"Serverless,Serverless应用,无服务器云函数","outdated":null},"wordCount":{"words":81,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-06-20-for-python-cloud-functions.md","fields":{"slug":"/blog/2019-06-20-for-python-cloud-functions/","keywords":["java","serverless","无服务器","无服务器云函数","云函数","serverlesscloud","安装","serverless","pillowtest"]}}},{"node":{"id":"2dc78814-9d77-555b-a1bb-ad202c8ec2d1","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/cloudforecast/thumbnail.png","authors":["FrancoisLagier"],"categories":["user-stories"],"date":"2019-08-07T00:00:00.000Z","title":"Serverless：初创企业的理想选择？（CloudForecast 案例分析）","description":"CloudForecast 是 2018 年成立的一家独立初创企业，本文将介绍他们决定选择 Serverless 的原因。","authorslink":["https://serverless.com/author/francoislagier/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":211,"sentences":29,"paragraphs":29},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-08-07-serverless-for-startups.md","fields":{"slug":"/blog/2019-08-07-serverless-for-startups/","keywords":["serverless","云函数","serverless","函数","Serverless","utm","Framework","blog","CloudForecast","cloudforecast"]}}},{"node":{"id":"97450b07-658b-5207-8216-1c7b9b51b115","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578988490344-v2-8b2cd2c5275aa2c5a3c5083a148a7a9f_1200x500.jpg","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-09-01T00:00:00.000Z","title":"如何通过 Serverless 与自然语言处理，让搜索引擎「看」到你的博客","description":"Serverless 与自然语言处理结合的一个小应用","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["个人博客","serverless"],"keywords":"Serverless 自然语言处理","outdated":null},"wordCount":{"words":106,"sentences":34,"paragraphs":34},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-01-search-engine-blog.md","fields":{"slug":"/blog/2019-09-01-search-engine-blog/","keywords":["serverless","云函数","keywords","serverlesscloud","summary"]}}},{"node":{"id":"ae4fd2f8-515c-5aec-b584-38427ef33f7e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578989800047-part-00492-780.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials","user-stories"],"date":"2019-09-16T00:00:00.000Z","title":"突破传统 OJ 瓶颈，「判题姬」接入云函数","description":"通过 Serverless 实现在线编程","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["在线编程","云函数"],"keywords":"Serverless 在线编程,Serverless OJ","outdated":null},"wordCount":{"words":169,"sentences":30,"paragraphs":30},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-16-online-Judge.md","fields":{"slug":"/blog/2019-09-16-online-Judge/","keywords":["python","serverless","云函数","代码","函数","serverless"]}}}],"totalCount":64}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"5e61ae27-a6be-5a1e-a7bd-06ddaaab5c3d","previousBlogId":"4c7906fb-df88-5132-96f0-3613754d9e05","nextBlogId":"e0959654-d44e-59c0-8201-19822e61b38d","categories":["user-stories"]}}}