0x1小程式介紹
這是一款看漂亮小姐姐的小程式,開源地址是: github.com/pengwei1024…。話不多說,先上個截圖各位小主看看合不合胃口。
怎麼抱走小姐姐呢?
可以微信小程式搜尋 唯美小姐姐 或者掃碼抱走吧
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。
微信技術交流群,歡迎交流