var (
//身份证号码
//rePersonCode = `<span>身份号码:[\s]?(([1-6]\d{5})(\d{4})(\d{2})(\d{2})(\d{4}))</span>`
//rePersonCode = `<span>身份号码:[\s]?(([1-6]\d{5})((19\d{2})|(20\d{2}))(\d{2})(\d{2})(\d{4}))</span>`
rePersonCode = `<span>身份号码:[\s]?(([1-6]\d{5})(19\d{2}|20\d{2})(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])(\d{3}[\dxX]))</span>`
//身份证号码: 空格也需要表示出来, 直接打空格是不起作用的 \s表示空字符 [\s]任意空字符 ?出现0次或者次
//([1-6]\d{5})(19\d{2}|20\d{2})(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])(\d{3}[\dxX])
// ([1-6]\d{5}) 为一组 第一位表示地区 例如 华中 华南等 数字为1-6 [1-6]表示任意一个 \d{5} 数字共5位
//(19\d{2}|20\d{2}) 为一组 年的前两位要么为19 要么为20 后两位为\d{2}数字出现两次
//(0[1-9]|1[012]) 为一组 月第一位为0或者为1 为0的时候 后边为[1-9]任意一个数字 为1的时候 后边为[012]任意一个数字
//(0[1-9]|[12]\d|3[01]) 为一组 日第一位要么为0要么为1或者2或者3 为0的时候第2位[1-9]任意一个数字 第1位为1或者2的时候 第2位为\d任意一个数字相当于[0-9]
//第一位为3的时候 第2位为[0-1]任意一个数字 这里不处理2月28天或者29天的情况
)
func HandleErr(err error, when string) {
if err!=nil {
fmt.Println(when, err)
os.Exit(1)
}
}
func main() {
//爬取身份证号码
person_code_num()
}
func person_code_num() {
html := getHtml("https://www.sohu.com/a/252455940_164709")
//fmt.Println(html)
re := regexp.MustCompile(rePersonCode)
codes := re.FindAllStringSubmatch(html, -1)
fmt.Println("总共: ", len(codes))
for _, value := range codes {
fmt.Println(value)
fmt.Println(value[1])
}
}
func getHtml(url string)(html string) {
fmt.Printf("001_正则表达式")
resp, err := http.Get(url)
HandleErr(err,`http.Get(s)`)
bytes, err := ioutil.ReadAll(resp.Body)
if err!=nil {
fmt.Println("ioutil.ReadAll err:",err)
}
html = string(bytes)
return
}
爬取数据如下图: