有个小需求, 需要从数据库中查出一批手机号, 然后判断筛查出浙江手机号。在公司尝试了集中方案, 没搞出来, 今天整理一番。

其实思路很简单,就是调用第三方接口,判断手机号归属地咯。根据手机号码的规则判断。这里就介绍第一种思路吧!

使用 PHP 实现

1
2
3
4
5
6
7
8
9
10
11
12
$phoneList = [
18767169866,
13407642222,
];
foreach($phoneList as $phone) {
$apiURL = sprintf("http://shouji.xpcha.com/%s.html", $phone);
$contents = file_get_contents($apiURL);
$count = preg_match("/浙江/", $contents);
if ($count > 0) {
echo $phone . PHP_EOL;
}
}

使用 BASH 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
# @author: luowen<bigpao.luo@gmail.com>
# @time: 2018-03-17
# @desc: 获取数据库中的手机号, 并判断手机号归属地方
# for phone in $(mysql -uroot -p111111 -h127.0.0.1 -s -e 'use actives; select phone from tbl_order')
phones=(18767169858 15179013298 15152088029)
for phone in ${phones[*]}
do
url="http://shouji.xpcha.com/${phone}.html"
loc=`curl -s $url | grep 浙江`
len=`echo $loc | wc -w`
if [ $len -gt 0 ]
then
echo $phone
fi
done

使用 GoLang 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* @website: https://vvotm.github.io
* @author luowen<bigpao.luo@gmail.com>
* @date 2018/3/17 14:08
* @description: 获取手机归属地信息
*/

package main

import (
"sync"
"fmt"
"net/http"
"log"
"regexp"
"io/ioutil"
)

type PhoneLocate struct {
lock *sync.RWMutex
wg *sync.WaitGroup
inputChan chan string
outputChan chan string
}

// main application entrance
func main() {
plt := NewPhoneLocate()
plt.InitWorkman(10)
go plt.AddDataSource(GetPhoneList())
result := plt.GetResult()
log.Printf("符合条件手机号码: %+v", result)
}

// GetPhoneList data source method
func GetPhoneList() []string {
return []string{"18767169856", "15179013264", "13738058509"}
}

// NewPhoneLocate create phone location query instance
func NewPhoneLocate() *PhoneLocate {
return &PhoneLocate{
lock: &sync.RWMutex{},
wg: &sync.WaitGroup{},
inputChan: make(chan string, 100),
outputChan: make(chan string, 100),
}
}

// InitWorkman initialize num workman
// workman is the core method that create http request and match the result
func (pl *PhoneLocate) InitWorkman(num int) {
pl.wg.Add(num)
for i := 0; i < num ; i++ {
go func(pl *PhoneLocate) {
for phone := range pl.inputChan {
apiURL := fmt.Sprintf("http://shouji.xpcha.com/%s.html", phone)
request, err := http.NewRequest("GET", apiURL, nil)
if err != nil {
log.Fatalf("创建请求异常: %#v", err)
continue
}
resp, err := http.DefaultClient.Do(request)
if err != nil {
log.Fatalf("请求异常: %#v", err)
continue
}
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalf("获取接口数据异常: %v", err)
continue
}
resp.Body.Close()
rp := regexp.MustCompile("浙江")
if rp.MatchString(string(content)) {
pl.outputChan <- phone
}
}
pl.wg.Done()
}(pl)
}
}

// AddDataSource add phone list data source
func (pl *PhoneLocate) AddDataSource(phoneList []string) {
for _, phone := range phoneList {
pl.inputChan <- phone
}
pl.CloseInputChan()
}

// GetResult Get result method
func (pl *PhoneLocate) GetResult() []string {
result := new([]string)
go func() {
pl.wg.Wait()
pl.CloseOutputChan()
}()
for {
select {
case phone, ok := <- pl.outputChan:
if !ok {
return *result
}
*result = append(*result, phone)
break
default:
break
}
}
}

// CloseInputChan close input chan method
func (pl *PhoneLocate) CloseInputChan() {
close(pl.inputChan)
}

// CloseOutputChan close output chan method
func (pl *PhoneLocate) CloseOutputChan() {
close(pl.outputChan)
}

GoLang的版本最复杂了, 效率也是最高的