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。
微信技术交流群,欢迎交流