Nguồn gốc:
Từ việc thiếu thốn dữ liệu của các nhà số học xung quanh mình. Buộc tôi phải tìm cách giúp họ. Nhưng với đôi tay trắng này, giúp sao đây. Tiền đâu mà mua server cắm bot cả ngày, máy mình cũng có trâu chó gì đâu mà cắm cả ngày cào dữ liệu cho nó. Rồi ngồi cào data thế này có ngày result.net block IP thì làm sao mà học toán được nữa.
Tiến hóa:
Chợt nhớ đến Google AppScript có cái Url Fetch, phê rồi đây...IP Bot của Google, các anh mà block có khi các anh lại bị biến mất khỏi Google Search
Ý Tưởng:
Tiến hành thôi, tạo một SpreadSheets ( tương đương Excel của M$) để lưu data, sau đó viết script cào dữ liệu result.net lên đó. Có 2 công việc phải làm, là phải cào dữ liệu từ trước đến thời điểm hiện tại và hiện tại (1.1.2000 đến nay, gần 20 năm )
Thực Nghiệm
1.Khởi tạo:
Tạo 2 sheet: Data, Config
Để map source bên script.google.com với file SpreadSheets, chọn Trình chỉnh sửa tập lệnh
Để bóc tách được dữ liệu html, tôi sử dụng một thư viện giống jquery (cheerio) để xử lý DOM cho ngon nghẻ.
ID thư viện : 1ReeQ6WO8kKNxoaA_O0XEQ589cIrRvEBA9qcWpNqdOP17i47u6N9M5Xh0
Chỉ việc thêm id thư viện này vào Tài nguyên > Thư viện là dùng được.
2.Phương thức:
Input :
- Url: /xo-so-truyen-thong.php?ngay=dd-mm-yyyy
- Date: date
Xây dựng các function format lại dữ liệu truyền vào.
Date.prototype.fTime = function() { // dd-mm-yyyy; return this.getDate() + "-" + (this.getMonth() + 1) + "-" + this.getYear(); }
Xây dựng func crawl: Fetch source về và bóc tách dữ liệu lấy 8 giải chính, sau đó lưu vào SpreadSheets,
có 2 options lưu dữ liệu, bao gồm:
- Lưu các ngày trước ngày hiện tại với job cào ngược
- Lưu các này hiện tại với job cào xuôi
Được phân định bằng biến isBack.
var $; function getGS(pos) { var root = $("#result_tab_mb"); return "'" + root.find("[id*=rs_" + pos + "_]").map(function(i, v) { return $(this).text(); }).get().join(","); } function crawl(date, isBack) { var content = UrlFetchApp.fetch('http://ketqua.net/xo-so-truyen-thong.php?ngay=' + date.fTime()); var html = content.getContentText(); if (html) { $ = Cheerio.load(html); const root = $("#result_tab_mb"); if (root) { var gs = { "g0": getGS(0), "g1": getGS(1), "g2": getGS(2), "g3": getGS(3), "g4": getGS(4), "g5": getGS(5), "g6": getGS(6), "g7": getGS(7) } // save var excel = SpreadsheetApp.getActive(); var sheet = excel.getSheets()[0]; var time = root.find("#result_date").text(); var dayName = time.split("ngày")[0]; var timeStr = time.split("ngày")[1]; var rowContent = [(dayName || "--").toString().trim(), (timeStr || date.fTime()).toString().trim(), gs.g0.toString(), gs.g1, gs.g2, gs.g3, gs.g4, gs.g5, gs.g6, gs.g7]; if (isBack) { sheet.appendRow(rowContent); } else { sheet.insertRowBefore(1).getRange("a1:j1").setValues([rowContent]); // chen len tren } } } }
Tạo các job
function daily() { crawl(new Date(), false); } function jobCrawBack() { var excel = SpreadsheetApp.getActive(); var sheet = excel.getSheets()[0]; var sheetCf = excel.getSheets()[1]; var rowEnd = sheet.getLastRow(); // Lấy dữ liệu ngày của hàng cuối cùng var lastDate = sheet.getRange(rowEnd, 2).getValue(); var now = new Date(); // Tính ngày tiếp theo var _lastDate = new Date(lastDate); _lastDate.setDate(_lastDate.getDate() - 1); crawl(_lastDate, true); // Thống kê số ngày lấy được spaceDay = Math.floor((now.getTime() - _lastDate.getTime()) / 86400000); sheetCf.getRange("b1").setValue(spaceDay); }
3.Triển Khai:
Chọn trigger menu (hình đồng hồ)
Đặt thời gian thực hiện các function để công việc trở thành tự động.
- Set time cho function daily là theo ngày ( đặt tầm 1 giờ sáng hàng ngày )
- Set time cho function jobCrawBack là mỗi phút 1 lần (*), sau khi lấy đủ dữ liệu thì xóa bỏ job này.
4.Kết Quả:
Sau 0.7day bot đã cào xong dữ liệu của 20 năm, hiện tại nó vẫn lấy dữ liệu đều đặn hàng ngày.
Output: Xem Thành Quả Nào!.
(*) Với 1 phút thì 1 lần lấy thì max chậm, tiến hành đệ quy chính nó và đổi thời gian lên thành 5 phút, vì sau 5 phút nếu function vẫn chạy thì Trình kích hoạt sẽ tự động kill job này. Vả từ 1 record / 1 min nó đã tăng lên 39 record / 5 phút.
-----Nguồn Chia Sẻ------
Anh NC _ Anh GQG _ Yukenz
Tôi đã cào dữ liệu 20 năm của ketqua.net bằng Google AppScript như thế nào.