主要使用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 = { "xe7x94xb5xe4xbfxa1" => 'telecom', "xe7xa7xbbxe5x8axa8" => 'mobile', "xe8x81x94xe9x80x9a" => 'unicom', "xe6x9cxaaxe7x9fxa5" => '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">[sS]+?</span>S+s+([^<]+)</td/g ) { my $ipHash; my $area = $1; $area =~ s/s+//g; #匹配电信、移动、联通、腾讯集团 #xe7x94xb5xe4xbfxa1 电信 #xe7xa7xbbxe5x8axa8 移动 #xe8x81x94xe9x80x9a 联通 #xe8x85xbexe8xaexafxe9x9bx86xe5x9bxa2 腾讯集团 if ( $area =~ /(xe7x94xb5xe4xbfxa1|xe7xa7xbbxe5x8axa8|xe8x81x94xe9x80x9a)/ ) { #插入运营商字段 $ipHash->{$id} = $ip; update_pt_data( $dbh, $ipHash, 'system_info', $operators->{$1}, 'id' ); $ipArea->{"$ip:$id"} = $operators->{$1}; } elsif ( $area =~ /xe8x85xbexe8xaexafxe9x9bx86xe5x9bxa2/ ) { #对特殊字段 腾讯集团处理 $ipHash->{$id} = $ip; update_pt_data( $dbh, $ipHash, 'system_info', $operators->{"xe7x94xb5xe4xbfxa1"}, 'id' ); $ipArea->{"$ip:$id"} = $operators->{"xe7x94xb5xe4xbfxa1"}; } else { #对未知运营商处理,并且处理 $ipHash->{$id} = $ip; update_pt_data( $dbh, $ipHash, 'system_info', $operators->{"xe6x9cxaaxe7x9fxa5"}, 'id' ); $ipArea->{"$ip:$id"} = $operators->{"xe6x9cxaaxe7x9fxa5"}; } } else { $ipArea->{"$ip:$id"} = $operators->{"xe6x9cxaaxe7x9fxa5"}; } } } keys %$ips; for (@coro) { $_->join; } return $ipArea; }