| 1 | package Net::Twitter::FriendFinder::From::Google; |
|---|
| 2 | |
|---|
| 3 | use strict; |
|---|
| 4 | use warnings; |
|---|
| 5 | use base qw/Net::Twitter::FriendFinder::From/; |
|---|
| 6 | use Web::Scraper; |
|---|
| 7 | use URI; |
|---|
| 8 | use URI::Escape; |
|---|
| 9 | __PACKAGE__->mk_accessors(qw/lang/); |
|---|
| 10 | |
|---|
| 11 | my $url = "http://www.google.com/search?q=%s+site:.twitter.com&num=%d&start=%d&hl=%s"; |
|---|
| 12 | our $ORDER_SCORE = 30; |
|---|
| 13 | |
|---|
| 14 | sub search { |
|---|
| 15 | my $self = shift; |
|---|
| 16 | my $keyword = shift; |
|---|
| 17 | |
|---|
| 18 | my $coverage = $self->{coverage}; |
|---|
| 19 | my $handicap = $self->{handicap}; |
|---|
| 20 | my $lang = $self->{lang} || ''; |
|---|
| 21 | |
|---|
| 22 | $keyword = URI::Escape::uri_escape( $keyword ); |
|---|
| 23 | $keyword =~ s/%20/+/g; |
|---|
| 24 | my $google_url = scraper { |
|---|
| 25 | process "table> tr > td.j > font > span.a", |
|---|
| 26 | description => 'TEXT', |
|---|
| 27 | }; |
|---|
| 28 | |
|---|
| 29 | my $google = scraper { |
|---|
| 30 | process "div.g", |
|---|
| 31 | "urls[]" => $google_url; |
|---|
| 32 | }; |
|---|
| 33 | |
|---|
| 34 | my $data = {}; |
|---|
| 35 | my $order_point = $ORDER_SCORE; |
|---|
| 36 | for( my $page = 1 ; $page <= $coverage ; $page++ ) { |
|---|
| 37 | my $target_uri = sprintf( $url , $keyword , 20 , ( $page-1 ) * 20 , $lang ) ; |
|---|
| 38 | my $res = $google->scrape( URI->new( $target_uri ) ); |
|---|
| 39 | |
|---|
| 40 | for my $item ( @{ $res->{urls} } ) { |
|---|
| 41 | my ( $name ) = $item->{description} =~ m|twitter.com/(\w+)/|; |
|---|
| 42 | next unless defined $name; |
|---|
| 43 | # order point + prev point |
|---|
| 44 | my $score = $order_point ; |
|---|
| 45 | $score += $data->{ $name } ? $data->{ $name }+1 : 1 ; |
|---|
| 46 | $score = $score * $handicap ; |
|---|
| 47 | $data->{ $name } = $score; |
|---|
| 48 | $order_point-- if $order_point > 0 ; |
|---|
| 49 | } |
|---|
| 50 | } |
|---|
| 51 | return $data; |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | 1; |
|---|
| 55 | |
|---|
| 56 | =head1 NAME |
|---|
| 57 | |
|---|
| 58 | Net::Twitter::FriendFinder::From::Google - Search from google. |
|---|
| 59 | |
|---|
| 60 | =head1 SYNOPSYS |
|---|
| 61 | |
|---|
| 62 | use strict; |
|---|
| 63 | use warnings; |
|---|
| 64 | use FindBin::libs; |
|---|
| 65 | use Net::Twitter::FriendFinder; |
|---|
| 66 | |
|---|
| 67 | |
|---|
| 68 | my $tf |
|---|
| 69 | = Net::Twitter::FriendFinder->new({ |
|---|
| 70 | from => { |
|---|
| 71 | Google => { coverage => 5 , lang => 'ja' }, |
|---|
| 72 | } |
|---|
| 73 | }); |
|---|
| 74 | |
|---|
| 75 | $tf->search('perl'); |
|---|
| 76 | $tf->show(); |
|---|
| 77 | |
|---|
| 78 | =head1 DESCRIPTION |
|---|
| 79 | |
|---|
| 80 | Find twitter friends from google search. |
|---|
| 81 | |
|---|
| 82 | Internally run google search like below. |
|---|
| 83 | |
|---|
| 84 | site:.twitter.com [your keyword] |
|---|
| 85 | |
|---|
| 86 | =head1 coverage |
|---|
| 87 | |
|---|
| 88 | coverage = 20 entry. |
|---|
| 89 | |
|---|
| 90 | So if you set |
|---|
| 91 | |
|---|
| 92 | coverage => 5, |
|---|
| 93 | |
|---|
| 94 | then 20 * 5 = 100. means try to find twitter friend from 100 entry. |
|---|
| 95 | |
|---|
| 96 | =head1 MODULE |
|---|
| 97 | |
|---|
| 98 | =head2 search |
|---|
| 99 | |
|---|
| 100 | =head1 AUTHOR |
|---|
| 101 | |
|---|
| 102 | Tomohiro Teranishi<tomohiro.teranishi@gmail.com> |
|---|
| 103 | |
|---|
| 104 | =cut |
|---|