HOME ABOUT CONTACT SITEMAP
Category
This site uses cookies for analytics, personalized content and ads. By continuing to browse this site, you agree to this use.
Author Image Thursday, 30 August 2018

Blogger JSON Feed API - Limited Feeds


Nói về Blogger JSON Feed API chắc chẳng có site nào xào kĩ như trang của tôi 😁, trong bài viết này tôi sẽ tiếp tục hướng dẫn bạn cách xử lý khi dữ liệu tải feeds bị giới hạn

Bài viết này tôi sẽ demo cho bạn với feed post có dạng /feeds/posts/summary hoặc /feeds/posts/default. Các feed khác cũng hoàn toàn tương tự.

Tại sao lại có bài viết này ? Nếu bạn đọc hết chuyên mục json feed api của tôi chắc cũng đã gặp trường hợp này rồi. Khi bạn build các tiện ích quy mô nhỏ ví dụ như bình luận gần đây, bài viết gần đây, bài viết theo nhãn,... các feed entry của nó (chính là giá trị max-results) không quá lớn. Nhưng khi cần đến dữ liệu dạng tổng hợp, thống kê thì bài toán trở nên phức tạp hơn do bị blogger hạn chế giá trị max-results

Đơn giản như feed post, mỗi lần tải blogger chỉ trả về 150 kết quả, khi blog của bạn có tầm 1000 bài và muốn làm 1 trang thống kê kiểu như sitemap thì bạn phải gửi rất nhiều request mới có thể lấy đủ dữ liệu

Xem demo: trong demo này tôi sẽ tiến hành lấy tất cả tiêu đề các bài đăng trên blog sử dụng 2 cách đó là js callback và ajax get (bạn nhập domain của mình vào để kiểm tra quá trình lấy dữ liệu)

demo

Sử dụng JavaScript callback

Tôi tạo 1 div để append dữ liệu

<div id="demo"></div>

Code JS được trình bày như sau

<script type='text/javascript'>//<![CDATA[
var totalEntires = 0,
    totalPosts = 0;

function myCallBack(json) {
    if ("entry" in json.feed) {
        totalPosts = json.feed.openSearch$totalResults.$t; // biến này sẽ lưu tổng số bài đăng của blog
        totalEntires += json.feed.entry.length; // biến này tăng dần theo mỗi lần tải feed cho tới khi nó bằng tổng số bài đăng của blog ví dụ có 469 bài thì các giá trị lần lượt của nó là 0,150,300,450,469 
        if (totalPosts > totalEntires) { // nếu tổng số bài đăng còn lớn hơn tổng số mục thì tiếp tục gửi request tải feed
            var s = document.createElement("script");
            s.type = "text/javascript";
            startindex = totalEntires + 1; // đây là giá trị quan trọng nhất để feed không bị trùng lặp ví dụ 1,151,301,451,...
            s.setAttribute("src", "/feeds/posts/summary?start-index=" + startindex + "&max-results=150&alt=json-in-script&callback=myCallBack"); // callback lại nó cho tới khi tải đủ dữ liệu
            document.getElementById("demo").appendChild(s);
        }
        for (var i = 0; i < json.feed.entry.length; i++) {
            // lấy những gì bạn muốn và viết những gì bạn thích
        }
    }
}
//]]></script>
<script src='/feeds/posts/summary?max-results=150&alt=json-in-script&callback=myCallBack' type='text/javascript'></script>

Sử dụng jQuery Ajax

Nếu như js callback sử dụng biến "tổng số mục" tăng dần tới "tổng số bài đăng" để gửi request, thì trong ajax get tôi lại làm ngược lại. Chia nhỏ tổng bài đăng cho con số tối đa của feed post là 150 rồi lần lượt gửi request theo giá trị start-index để lấy dữ liệu

Thuật toán đã được trình bày ở bài thống kê bình luận rồi nên tôi sẽ không comment lại nữa, chỉ lưu ý là khi gửi ajax request trong vòng lặp có thể nó sẽ không get dữ liệu tuần tự, nên bạn cần thêm 1 plugin nhỏ kiểu như ajax queue để tải feed theo thứ tự

Tôi tạo 1 div để append dữ liệu

<div id="demo"></div>

Code JS được trình bày như sau

<script type='text/javascript'>//<![CDATA[
$.ajax({
    url: '/feeds/posts/summary',
    type: 'GET',
    dataType: 'jsonp',
    data: {
        alt: 'json',
        'max-results': 0
    },
}).done(function(json) {
    totalPosts = json.feed.openSearch$totalResults.$t;
    if (totalPosts % 150 == 0) {
        num = (totalPosts / 150) - 1
    } else {
        num = Math.floor(totalPosts / 150);
    }
    /*! jQuery Ajax Queue 
     * https://github.com/gnarf37/jquery-ajaxQueue
     */
    (function(e) {
        var r = e({});
        e.ajaxQueue = function(n) {
            function t(r) {
                u = e.ajax(n).done(a.resolve).fail(a.reject).then(r, r)
            }
            var u, a = e.Deferred(),
                i = a.promise();
            return r.queue(t), i.abort = function(o) {
                if (u) return u.abort(o);
                var c = r.queue(),
                    f = e.inArray(t, c);
                return f > -1 && c.splice(f, 1), a.rejectWith(n.context || n, [i, o, ""]), i
            }, i
        }
    })(jQuery);
    for (var k = 0; k <= num; k++) {
        $.ajaxQueue({
            url: '/feeds/posts/summary',
            type: 'GET',
            dataType: 'jsonp',
            data: {
                alt: 'json',
                'max-results': 150,
                'start-index': (150 * k) + 1
            },
        }).done(function(e) {
            if ("entry" in e.feed) {
                for (var i = 0; i < e.feed.entry.length; i++) {
                    // lấy những gì bạn muốn và viết những gì bạn thích
                }
            }
        })
    }
})
//]]></script>

Như vậy sau khi đọc xong bài viết này, khi gặp bài toán cần lấy toàn bộ dữ liệu của blog chắc không làm khó được bạn nữa nhỉ.

Để lại bình luận nếu bạn gặp khó khăn và chúc thành công !
Comments:
Bạn được tự do bày tỏ quan điểm nhưng nghiêm cấm spam
  • Chèn ảnh theo mẫu [img]link[/img]
  • Chèn video Youtube theo mẫu [youtube]link[/youtube]
  • Chèn code theo mẫu [pre]code[/pre]. Lưu ý: mã hóa code trước khi bình luận

  • Please wait while i am loading Facebook SDK js