主要使用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; }
时间: 2024-10-09 05:06:50