twitter-scrape-account-stats
Version:
scrape public Twitter data w/out API access
82 lines (73 loc) • 2.27 kB
JavaScript
// Generated by CoffeeScript 1.10.0
(function() {
var STAT_NAME_MAP, STAT_TITLE_RE, cheerio, getAccountStats, getStatInt, request;
request = require('request-promise');
cheerio = require('cheerio');
STAT_NAME_MAP = {
following: 'following_stats',
followers: 'follower_stats',
posts: 'tweet_stats'
};
STAT_TITLE_RE = {
'following_stats': /^[0-9,]+ Following$/,
'follower_stats': /^[0-9,]+ Followers$/,
'tweet_stats': /^[0-9,]+ Tweets$/
};
getStatInt = function($, statName) {
var stat;
stat = $("[data-element-term=\"" + statName + "\"]").attr('title');
if (stat == null) {
throw new Error("couldn't get " + statName);
}
if (!STAT_TITLE_RE[statName].test(stat)) {
throw new Error('unexpected format in title attribute');
}
return parseInt(stat.replace(/[^0-9]/g, ''));
};
getAccountStats = function(arg) {
var data, queryString, userId, username;
username = arg.username, userId = arg.userId;
if ((username == null) && (userId == null)) {
throw new Error('A username or userId needs to be passed');
}
queryString = {
'wants_hovercard': true,
'_': (new Date()).getTime()
};
if (userId != null) {
queryString['user_id'] = userId;
} else {
queryString['screen_name'] = username;
}
data = void 0;
return request.get({
uri: 'https://twitter.com/i/profiles/popup',
qs: queryString
}).then(function(resp) {
data = JSON.parse(resp);
return cheerio.load(data.html);
}).then(function($) {
var e, error, field, res, statName;
res = {
description: $('.bio.profile-field').text(),
isVerified: $('.Icon--verified').length > 0,
name: $('.ProfileCard-avatarLink').attr('title'),
userId: data['user_id'],
username: data['screen_name']
};
for (field in STAT_NAME_MAP) {
statName = STAT_NAME_MAP[field];
try {
res[field] = getStatInt($, statName);
} catch (error) {
e = error;
throw new Error("Couldn't get " + field + " stat for " + res.username);
}
}
return res;
});
};
module.exports = {
getAccountStats: getAccountStats
};
}).call(this);