ShareTôi đã cào dữ liệu 20 năm của ketqua.net bằng Google AppScript như thế nào

02.07.2021 / 09:45
hoangchan
Bài đăng: 108
Member
Samsung j2

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 :D

[IMAGE]

Ý 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

[IMAGE]

Để 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

[IMAGE]

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.

PHP
  1. Date.prototype.fTime = function() {
  2. // dd-mm-yyyy;
  3. return this.getDate() + "-" + (this.getMonth() + 1) + "-" + this.getYear();
  4. }

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.

PHP
  1. var $;
  2.  
  3. function getGS(pos) {
  4. var root = $("#result_tab_mb");
  5. return "'" + root.find("[id*=rs_" + pos + "_]").map(function(i, v) {
  6. return $(this).text();
  7. }).get().join(",");
  8. }
  9.  
  10. function crawl(date, isBack) {
  11. var content = UrlFetchApp.fetch('http://ketqua.net/xo-so-truyen-thong.php?ngay=' + date.fTime());
  12. var html = content.getContentText();
  13. if (html) {
  14.  
  15. $ = Cheerio.load(html);
  16.  
  17. const root = $("#result_tab_mb");
  18.  
  19. if (root) {
  20.  
  21. var gs = {
  22. "g0": getGS(0),
  23. "g1": getGS(1),
  24. "g2": getGS(2),
  25. "g3": getGS(3),
  26. "g4": getGS(4),
  27. "g5": getGS(5),
  28. "g6": getGS(6),
  29. "g7": getGS(7)
  30. }
  31.  
  32. // save
  33. var excel = SpreadsheetApp.getActive();
  34. var sheet = excel.getSheets()[0];
  35.  
  36. var time = root.find("#result_date").text();
  37. var dayName = time.split("ngày")[0];
  38. var timeStr = time.split("ngày")[1];
  39.  
  40. 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];
  41.  
  42. if (isBack) {
  43. sheet.appendRow(rowContent);
  44. } else {
  45. sheet.insertRowBefore(1).getRange("a1:j1").setValues([rowContent]); // chen len tren
  46. }
  47.  
  48. }
  49. }
  50. }

Tạo các job

PHP
  1. function daily() {
  2. crawl(new Date(), false);
  3. }
  4.  
  5. function jobCrawBack() {
  6. var excel = SpreadsheetApp.getActive();
  7. var sheet = excel.getSheets()[0];
  8. var sheetCf = excel.getSheets()[1];
  9.  
  10. var rowEnd = sheet.getLastRow();
  11.  
  12. // Lấy dữ liệu ngày của hàng cuối cùng
  13. var lastDate = sheet.getRange(rowEnd, 2).getValue();
  14.  
  15. var now = new Date();
  16.  
  17. // Tính ngày tiếp theo
  18. var _lastDate = new Date(lastDate);
  19. _lastDate.setDate(_lastDate.getDate() - 1);
  20.  
  21. crawl(_lastDate, true);
  22.  
  23. // Thống kê số ngày lấy được
  24. spaceDay = Math.floor((now.getTime() - _lastDate.getTime()) / 86400000);
  25. sheetCf.getRange("b1").setValue(spaceDay);
  26. }

3.Triển Khai:

Chọn trigger menu (hình đồng hồ)

[IMAGE]

Đặ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.

[IMAGE]

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.

25.07.2021 / 12:28
hoangchan
Bài đăng: 108
Member
Samsung j2

Đây là 1 bản mix

02.07.2024 / 22:46
hoangchan
Bài đăng: 108
Member
Samsung j2

02/07/2024 Buồn của tôi....

Edited hoangchan (02.07.2024 / 22:48)