水文:记录我爬取 校验真实姓名枚举数据 的那点鸡毛蒜皮

228 阅读4分钟

菜鸡笔录水文!!!!!!

事情是这样的:下班后突然来了一位神秘人加我QQ,附加信息尽然是主动让我接web开发单,这让我的好奇心一下子拉满,同意好友后,他告诉我他们公司经营了一个专供程序员接单的平台,只需要注册即可接到不同类型的web单,于是我打开了这个神奇的网站发现,注册之后层层校验

填写完个人介绍后突然跳到了个人实名

7A35A9BD491A9AA044DDCD2BD01480AD.png

经过询问客服后发现它可能并不是 一个正规的个人实名认证,客户信息 仅存在于他们公司内部数据库,于是我的好奇心又开始促使我对它进行各种调戏 发现

ED0C784D2BBBA8C6CB9B0109DF27129B.png

发现前端只是简单的校验,于是我突发奇想:决定爬取并收集全 百家姓枚举,这样的话,前端校验是否会更加真实,也会省去后台审核人员的工作力度!

说干就干!!!

首先我打开我的导师:www.百度.COM,寻找百家姓枚举

找到了一个看似很容易加工的一批数据 : www.unjs.com/fanwenwang/…

结果 我cv复制发现,似乎复制不了,需要缴费,我想了想,这是个html

我可以对页面发起请求后 拿到html结构 使用cheerio对结构进行加工截取 就能拿到完美的数据

于是我开始了我的行动

image.png

首选当然是我使用熟练的axios

发现爬取的出来的html中文乱码

审核元素目标站点却发现:原来人家的是GBK页面,不是utf-8的,而axios默认是utf-8。

image.png

于是我询问了我的老师: Baidu

最后我得到了一个答案

image.png

axios使用说明中有:responseType 表示服务器响应的数据类型

大概是这样的一个思路:在使用axios发起请求时,因目标网页是gbk编码格式,而axios默认是utf-8,所以需要使用 responseType属性 将 响应数据 进行编码,再利用其他插件进行转义回来,得到一个正确的中文格式,我理解为: 中间件的意思

于是cv大法 走一波

image.png

查询得知: FileReader这个构造函数是es6新增用来读取文件的,我尝试在 node中使用node全局对象global对象.属性访问此构造函数

image.png

发现并没有访问到 (盼望来位大佬解答)

我尝试换一种思路: 已知只需在响应数据时 对数据进行一种编码处理 再使用转义的方式 再恢复原样, 就额可以得到完整的html结构

继续询问 我的 “老师”

发现一个包:可以对数据各种编码类型的转义编码

image.png

这不就来了吗? cv大法

发现果然管用 !

image.png

于是我开始继续满足我奇怪的好奇心!

使用类似jq的cheerio包,对响应的html结构进行加载

观察网页静态结构发现,开头俩个p标签不需要,于是对数据结构进行了遍历截取拼接

image.png

最后对数据进行粗略的加工

得到三百个 姓

image.png

image.png

最后简单使用express 部署一下 枚举接口

image.png

最后贴一下 完整 代码

mapName.js

const cheerio = require('cheerio');
const http = require('https');
const iconv = require('iconv-lite');
const fs = require('fs');

getNameHtmlApi();

async function getNameHtmlApi() {
  let url = 'https://www.unjs.com/fanwenwang/ziliao/648724.html';
  let html = await new Promise(function (resolve) {
    http.get(url, (res) => {
      let data = [];
      res.on('data', (chunk) => {
        data.push(chunk);
      });
      res.on('end', () => {
        let html = iconv.decode(Buffer.concat(data), 'gbk');
        resolve(html);
      });
    });
  });
  mapNameEnum(html);
}

function mapNameEnum(html) {
  //cheerio就如同jq
  let $ = cheerio.load(html); //加载解析 html结构
  let nameData = '';
  // 观察网页结构发现 开头多余俩个P标签 于是我对p标签进行遍历排除 拼接
  $('.content p').each(function (i, elem) {
    if (i > 2) {
      if ($(this).text().indexOf('第') === -1) {
        nameData += $(this).text();
      }
    }
  });

  let gapreg = new RegExp(/(\s)/g); // 空格
  let numreg = new RegExp(/(\d{1,3})/g); // 数字

  nameData = nameData
    .replace(gapreg, '') //首先对空格进行一层过滤
    .replace(numreg, ',') //  接着对数字进行替换成 统一符号方便 写成数组格式
    .split(',') //再进行截取
    .slice(1); // 发现一个空标签 故截取掉首位

  fs.writeFileSync('./data/surname.json', JSON.stringify(nameData));
}

app.js

const express = require('express');
const app = express();
app.use(express.static('data'));

const port = 6969;
app.listen(port, () => {
  console.log('服务器已经启动!http://127.0.0.1:' + port);
});

结尾:记录一些自己对一些基层知识的温顾,希望大佬亲点喷

后续可能会更进关于 身份证更加严谨的校验枚举数据获取水文!