Skip to content

Instantly share code, notes, and snippets.

@dotSlashLu
Last active January 3, 2016 13:49
Show Gist options
  • Save dotSlashLu/8471804 to your computer and use it in GitHub Desktop.
Save dotSlashLu/8471804 to your computer and use it in GitHub Desktop.
Format Twitter feed pages(home, search result) into API format JSON
/**
* Copyright Dotslash.Lu <dotslash.lu@gmail.com>
*
* This script runs on Twitter feed pages(home, search results)
* and automatically get data including both the feed and the user
* then output them in the format of standard API request result
* thus bypassing the limit of the Twitter API
*/
function O(){}
O.prototype = {
jqTweets : $(".tweet"),
currentIndex : 0,
maxTry : 3,
currentTry : 0,
results : [],
start : function(){
this.next()
},
stop : function(){
this.currentTry = this.maxTry
this.currentIndex = this.jqTweets.length
console.error(JSON.stringify(this.results));
},
next : function(){
// we'll use console.error hereafter, because twitter has somewhy reset console.{log, info}
console.error("Processing #" + this.currentIndex);
this.jqTweets = $(".tweet");
if (this.currentIndex < this.jqTweets.length) {
this.scroll();
get_tweet(this, this.jqTweets.eq(this.currentIndex++));
}
else if (this.currentTry++ < this.maxTry) {
console.error("Seems we are out of tweets, retry after 3 seconds");
setTimeout(function(){this.next()}, 3000); // wait for more tweets to load over ajax
}
else {
this.stop();
alert("All Done!");
}
},
scroll : function(){
$(document).scrollTop(this.jqTweets.eq(this.currentIndex).offset().top - 40)
}
}
function get_tweet(o, $_t){
var _t = {}; // result
// user info
_t.user = {};
_t.user.id = new Number($_t.data("user-id")).valueOf();
_t.user.id_str = $_t.data("user-id");
_t.user.profile_image_url = $_t.find(".avatar").attr("src");
_t.user.name = $_t.data("name");
_t.user.screen_name = $_t.data("screen-name");
// tweet info
_t.id = $_t.data("item-id");
_t.id_str = new String(_t.id).valueOf();
_t.created_at = $_t.find("small.time a").attr("title") || $_t.find("small.time a").data("original-title");
_t.text = $_t.find(".tweet-text").html();
// get rt & fav count
var expand_url = "https://twitter.com/i/expanded/batch/" + _t.id_str + "?facepile_max=7&include%5B%5D=social_proof";
$.getJSON(expand_url, null, function(data){
data = data.social_proof;
var rt_count_match = data.match(/<strong>(\d+)<\/strong> Retweet/); // \u003cstrong\u003e1\u003c\/strong\u003e Retweet
rt_count_match? _t.retweet_count = rt_count_match[1]: _t.retweet_count = 0
var fv_count_match = data.match(/<strong>(\d+)<\/strong> Favorite/); // \u003cstrong\u003e1\u003c\/strong\u003e Favorite
fv_count_match? _t.favorite_count = fv_count_match[1]: _t.favorite_count = 0;
})
// get user detail
var user_url = "https://twitter.com/" + _t.user.screen_name;
$.ajax({
retryCount: 0,
retryLimit: 3,
url: user_url,
dataType: "text",
success: function(data) {
var pattern = {
profile : /<p class="bio profile\-field">([\s\S]+?)<\/p>/,
location: /<span class="location profile\-field">([\s\S]+?)<\/span>/,
stats : /<ul class="stats js\-mini\-profile\-stats " data\-user\-id="\d+">([\s\S]+?)<\/ul>/,
stat_fig: /<strong>[,\d]+<\/strong>/g,
stat : />(.*)</
},
profile_match = data.match(pattern.profile),
location_match = data.match(pattern.location);
profile_match? _t.user.description = profile_match[1]: "";
location_match? _t.user.location = location_match[1].trim(): "";
// stats
var stats = data.match(pattern.stats)[1].match(pattern.stat_fig);
stats.forEach(function(v, i){
v = v.match(pattern.stat)[1].replace(/,/, "");
switch(i) {
case 0:
_t.user.statuses_count = v;
break;
case 1:
_t.user.friends_count = v;
break;
case 2:
_t.user.followers_count= v;
break;
}
})
o.results.push(_t);
setTimeout("o.next()", 0);
},
error : function(xhr, textStatus, errorThrown ) {
if (this.retryCount++ <= this.retryLimit) {
console.error(
"Requesting " + user_url + "failed with status " + xhr.status
+ "; Trying for " + this.retryCount + " times..."
);
$.ajax(this);
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment