举个栗子

马辰龙De技术分享
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用coro+anyevent 异步协程获取IP运营商

Posted on 2016-07-09 14:12  ChenlongMa  阅读(469)  评论(0编辑  收藏  举报

主要使用coro协程+AnyEvent::HTTP::LWP::UserAgent 异步http请求,查询数据库中IP字段,返回运营商。如需要获取其他类型的字段,修改正则即可,

此方法的好处是,不需要获取本地IP库,提高IP精准度。缺点,需要很好的网络质量。CODE如下:

#查询IP的网络提供商
sub search_ip_area {
    my $self = shift;
    my ( $dsn, $dbuser, $dbpass, $ips ) = @_;
    my $ua = AnyEvent::HTTP::LWP::UserAgent->new;
    my $dbh = AnyEvent::DBI::MySQL->connect( $dsn, $dbuser, $dbpass );
    my $ipArea;
 
    
#定义运营商字段
    my $operators = {
        "\xe7\x94\xb5\xe4\xbf\xa1" => 'telecom',
        "\xe7\xa7\xbb\xe5\x8a\xa8" => 'mobile',
        "\xe8\x81\x94\xe9\x80\x9a" => 'unicom',
        "\xe6\x9c\xaa\xe7\x9f\xa5" => 'unknowPublic'
    };
    my @coro = map {
        my ( $ip, $id ) = split /:/, $_;
        my $url = "http://www.baidu.com/s?wd=$ip";
 
        async {
            my $r       = $ua->get($url);
            my $content = $r->content;
            
#正则提取运营商
            if ( $content
                =~ /<div[^\"]+\".*?op-ip-detail\">[\s\S]+?<\/span>\S+\s+([^<]+)<\/td/g
                )
            {
                my $ipHash;
                my $area = $1;
                $area =~ s/\s+//g;
 
                
#匹配电信、移动、联通、腾讯集团
                
#\xe7\x94\xb5\xe4\xbf\xa1 电信
                
#\xe7\xa7\xbb\xe5\x8a\xa8 移动
                
#\xe8\x81\x94\xe9\x80\x9a 联通
                
#\xe8\x85\xbe\xe8\xae\xaf\xe9\x9b\x86\xe5\x9b\xa2 腾讯集团
                if ( $area
                    =~ /(\xe7\x94\xb5\xe4\xbf\xa1|\xe7\xa7\xbb\xe5\x8a\xa8|\xe8\x81\x94\xe9\x80\x9a)/
                    )
                {
                    
#插入运营商字段
                    $ipHash->{$id} = $ip;
 
                    update_pt_data( $dbh, $ipHash,
                        'system_info', $operators->{$1}, 'id' );
                    $ipArea->{"$ip:$id"} = $operators->{$1};
                }
                elsif ( $area
                    =~ /\xe8\x85\xbe\xe8\xae\xaf\xe9\x9b\x86\xe5\x9b\xa2/ )
                {    
#对特殊字段 腾讯集团处理
                    $ipHash->{$id} = $ip;
 
                    update_pt_data( $dbh, $ipHash, 'system_info',
                        $operators->{"\xe7\x94\xb5\xe4\xbf\xa1"}, 'id' );
                    $ipArea->{"$ip:$id"}
                        = $operators->{"\xe7\x94\xb5\xe4\xbf\xa1"};
                }
                else {    
#对未知运营商处理,并且处理
                    $ipHash->{$id} = $ip;
 
                    update_pt_data( $dbh, $ipHash, 'system_info',
                        $operators->{"\xe6\x9c\xaa\xe7\x9f\xa5"}, 'id' );
                    $ipArea->{"$ip:$id"}
                        = $operators->{"\xe6\x9c\xaa\xe7\x9f\xa5"};
                }
 
            }
            else {
                $ipArea->{"$ip:$id"}
                    = $operators->{"\xe6\x9c\xaa\xe7\x9f\xa5"};
            }
        }
    } keys %$ips;
    for (@coro) {
        $_->join;
    }
    return $ipArea;
 
}