开源小程序: 唯美小姐姐

0x1小程序介绍

这是一款看漂亮小姐姐的小程序,开源地址是: https://github.com/pengwei1024/HiBeauty。话不多说,先上个截图各位小主看看合不合胃口。

怎么抱走小姐姐呢?

可以微信小程序搜索 唯美小姐姐 或者扫码抱走吧

0x2原理分析

各位小主看完了小姐姐,请把口水擦干,我们来看看怎么new一个小姐姐吧。我觉得技术点主要下面两个(当然第一个才是大家最关心的):

  • 小姐姐数据的抓取和处理
  • 小程序从服务器拉取并展示数据

数据抓取

小姐姐的数据主要来自微博美女帅哥大V, 如x粉大魔王等等,在此向各位辛勤付出的大V致谢。抓取用的方案是Headless Chrome + selenium,简而言之就是用的服务器上web自动化方案。

为什么采用这个方案呢,直接抓取网页的方式帐号容易被封,自动登录获取cookie的技术难度都比较大。而web自动化就是模拟网页点击,一切的操作都是so easy。


不了解 Headless Chrome 和 selenium?请看下面的教程:

linux上配置一个定时任务,实现全自动化的抓取,再来个图片分类器把非小姐姐图片去除,自动更新,开开心心欣赏小姐姐真是美滋滋

用selenium抓取的代码不会超过50行,这里就不展开了,各位小主自己尝试下吧~

图片展示

小程序展示列表实在不是什么技术难点,如果说有什么需要注意的话,那就是图片可以持续下拉加载更多,数据量过大导致OOM崩溃的问题, 主要分两步解决吧。

  • 图片不直接加载原图 (微博提供了缩略图和原图两套)
  • 增量刷新列表

重点来看下小程序增量刷新列表吧。(会的大哥大姐可以忽略,毕竟我是一个小菜鸟) 更新的时候加上下标就好了。

this.setData({  
    'array[0].text':'changed data'
})

用了某网友分享的一个类SafeRenderUtil, 自己新增了一个reset方法, 找不到原作者链接了,在此致谢

/**
 * @module SafeRenderUtil
 */

/**
 * 安全渲染的工具类
 * 解决的问题:分页加载时,数组拼接起来在渲染,当数据超过 1M 后,无法再加载
 * @example
 * import SafeRenderUtil from '@xxx/lib/safeRenderUtil';
 * // 初始化
 * this.SafeRenderUtil = new SafeRenderUtil({
 *   arrName: 'arrName',
 *   formatItem: (item) => {
 *     //裁剪每一项的图片...
 *     return item;
 *   },
 *   setData: this.setData.bind(this)
 * });
 * // 将数组传递进来进行渲染
 * this.SafeRenderUtil.addList(res.data.data);
 */
class SafeRenderUtil {  
  /**
   * @param {String} opts.arrName 数组名称
   * @param {Function} opts.formatItem 处理数组的每一个 item ,并将该 item 返回
   * @param {Function} opts.setData 调用页面的渲染方法
   */
  constructor(opts) {
    this.arrName = opts.arrName;
    this.formatItem = opts.formatItem;
    this.setData = opts.setData;
    this.originLen = 0; //原始数组长度
  }
  /**
   * @param {Array} arr 需要渲染的数组
   */
  addList(arr) {
    if (arr && arr.length) {
      let newList = {};
      for (let i = 0; i < arr.length; i++) {
        let item = arr[i];
        if (typeof(this.formatItem) === 'function') {
          item = this.formatItem(item);
        }
        newList[`${this.arrName}[${this.originLen}]`] = item;
        this.originLen += 1;
      };
      this.setData(newList);
    }
  }
  /**
   * 清空数组数据
   */
  clearArr() {
    this.setData({
      [`${this.arrName}`]: []
    });
    this.originLen = 0;
  }

  reset(arr) {
    this.originLen = arr.length;
    if (arr && arr.length) {
      for (let i = 0; i < arr.length; i++) {
        if (typeof(this.formatItem) === 'function') {
          arr[i] = this.formatItem(arr[i]);
        }
      };
      this.setData({
        [`${this.arrName}`]: arr
      });
    }
  }
}
module.exports = SafeRenderUtil;  

0x3 最后

本人代码不精,封装无力,架构松散,欢迎大家提建议、issue、pr。

微信技术交流群,欢迎交流