Twitter List lister
Dec. 13th, 2009 12:34 amThis Perl script outputs a list of users that a Twitter List is following. Use this script to save your Twitter Lists in case you need to recreate those one day.
#!perl -w
#
# twlist.pl - Output members of a Twitter List.
#
# Usage: twlist.pl [-p proxyhost:proxyport] [-P proxyuser:proxypass]
# user:password user list
#
# proxyserver:proxyport - Optional. HTTP proxy server and port.
# proxyuser:proxypass - Optional. HTTP proxy login.
# username:password - Required. Twitter login.
# user - Required. User who owns the List. Need not be the
# same as login user.
# list - Required. The id or slug of the List.
#
# Login information can be specified in Base64 format. If it is, it will be
# placed directly in the HTTP headers.
#
use strict;
use XML::Simple;
use LWP::UserAgent;
use Getopt::Std;
use MIME::Base64;
use Data::Dumper;
my $count = 0;
# Parse XML and output List members.
sub process_xml {
my $xmlstr = shift;
my $xml = XMLin($xmlstr, ForceArray => ['user'], KeyAttr => []);
# print Dumper($xml);
for my $user (@{$xml->{users}{user}}) {
++$count;
print "$count: $user->{id} $user->{name}\n";
}
return $xml->{next_cursor};
}
# Encode in Base64 if login string is in user:pass format. Otherwise,
# assume it is already in Base64.
sub base64login {
my $login = shift;
$login =~ /:/ ? encode_base64($login) : $login;
}
my $MAXRETRY = 5;
# Download Twitter list members through Twitter API.
sub twitter_api {
my $user = shift;
my $list = shift;
my $login = shift;
my $proxy = shift;
my $proxylogin = shift;
my $cursor = shift;
my $retrycount = 0;
while (1) {
my $ua = new LWP::UserAgent;
$proxy ne '' and $ua->proxy('http', "http://$proxy");
$proxylogin ne '' and
$ua->default_header('Proxy-Authorization' =>
"Basic ".base64login($proxylogin));
$login ne '' and
$ua->default_header('Authorization' =>
"Basic ".base64login($login));
my $response = $ua->get("http://api.twitter.com/1/$user/$list/" .
"members.xml?cursor=$cursor");
$response->is_success and return $response->content;
++$retrycount;
$retrycount > $MAXRETRY and die $response->as_string;
warn "Retrying...\n";
sleep 3;
}
}
# Get all pages of Twitter list members.
sub get_pages {
my $user = shift;
my $list = shift;
my $login = shift;
my $proxy = shift;
my $proxylogin = shift;
my $cursor = -1;
my $page = 0;
do {
++$page;
warn "Getting $user/$list list members page $page...\n";
my $xmlstr;
eval {
$xmlstr = twitter_api($user, $list, $login,
$proxy, $proxylogin, $cursor);
};
return if $@;
$cursor = process_xml($xmlstr);
sleep 1;
} until $cursor == 0;
}
sub usage {
die "Usage: $0 [-p proxyhost:proxyport] [-P proxyuser:proxypass] "
."user:password user list\n";
}
sub main {
binmode STDOUT, ":utf8";
my $proxy = '';
my $login = '';
my $proxylogin = '';
my %opts;
getopts('p:P:', \%opts) or usage;
defined $opts{p} and $proxy = $opts{p};
defined $opts{P} and $proxylogin = $opts{P};
@ARGV < 3 and usage;
$login = shift @ARGV;
my $user = shift @ARGV;
my $list = shift @ARGV;
get_pages($user, $list, $login, $proxy, $proxylogin);
}
main;
__END__