爬取行政区代码

练习写的,比较烂

PHP

go

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

// v.(map[string]interface{}) v原本为interface 这里意思是转类型为map interface转其他类型v.(type)
// 结构体必须是首字母大写 不然会被忽略
type RequestData struct {
	Total int
	Rows  []map[string]interface{} // []为切片类型,切片可以不写长度的申明  map为map类型[键的类型]值的类型
}

func main() {
	t1 := time.Now()
	//需要post的数据,以key-value形式提交
	data := make(url.Values)
	//data["appId"] = []string{"10001"}
	//data["appKey"] = []string{"test"}
	//data["option"] = []string{"upload"}
	//data["sign"] = []string{"1111"}

	res, err := http.PostForm("http://cnis.7east.com/widget.do?type=service&ajax=yes&action=cnislist", data)
	//设置http中header参数,可以再此添加cookie等值
	//res.Header.Add("User-Agent", "***")
	//res.Header.Add("http.socket.timeou", 5000)

	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	//fmt.Println(string(body))

	//requestData := make(map[string]interface{}) // json字符转map interface{}这个目前不是很懂,反正不确定value值类型的时候这样子写就ok了

	// json转结构
	requestData := RequestData{}
	json.Unmarshal([]byte(string(body)), &requestData)

	arr := requestData.Rows
	var lastSlice []map[string]interface{}
	for _, v := range arr {
		lastMap := make(map[string]interface{}) // 申明初始化一个map map是个引用类型,所以要在循环里面创建,不然就会覆盖之前的值
		lastMap["code"] = v["code"]
		lastMap["name"] = v["local_name"]
		lastMap["region_id"] = v["region_id"]
		children := getChildren(v["region_id"].(float64)) // 这里不能直接转int 报错说这里是float64类型
		if children != nil {
			lastMap["children"] = children
		}
		lastSlice = append(lastSlice, lastMap)
	}

	// 转json
	str, err := json.Marshal(lastSlice)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("map to json", string(str))

	elapsed := time.Since(t1)
	fmt.Println(elapsed)
}

func getChildren(id float64) []map[string]interface{} {
	data := make(url.Values)
	id = math.Floor(id)                              // 下取整 本来以为转整后就是int了,结果是我想多了,这步意义不大,下面是float64toString的方法
	idString := strconv.FormatFloat(id, 'f', -1, 64) // float64toString 如果是float32最后的参数就是32 第二个参数如下
	// 'b' (-ddddp±ddd,二进制指数)
	// 'e' (-d.dddde±dd,十进制指数)
	// 'E' (-d.ddddE±dd,十进制指数)
	// 'f' (-ddd.dddd,没有指数)
	// 'g' ('e':大指数,'f':其它情况)
	// 'G' ('E':大指数,'f':其它情况)
	res, err := http.PostForm("http://cnis.7east.com/widget.do?type=service&action=cnischildlist&a=2&ajax=yes&pid="+idString, data)
	//设置http中header参数,可以再此添加cookie等值
	//res.Header.Add("User-Agent", "***")
	//res.Header.Add("http.socket.timeou", 5000)

	if err != nil {
		fmt.Println(err.Error())
		return nil
	}
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	//fmt.Println(string(body))
	// json转结构
	requestData := RequestData{}
	json.Unmarshal([]byte(string(body)), &requestData)
	arr := requestData.Rows
	if len(arr) == 0 {
		return nil
	}
	var lastSlice []map[string]interface{}
	for _, v := range arr {
		lastMap := make(map[string]interface{}) // 申明初始化一个map map是个引用类型,所以要在循环里面创建,不然就会覆盖之前的值
		lastMap["code"] = v["code"]
		lastMap["name"] = v["local_name"]
		lastMap["region_id"] = v["region_id"]
		if v["layer"].(float64) < 3 {
			fmt.Println(v["local_name"])
			children := getChildren(v["region_id"].(float64)) // 这里不能直接转int 报错说这里是float64类型
			if children != nil {
				lastMap["children"] = children
			}
		}
		lastSlice = append(lastSlice, lastMap)
	}
	return lastSlice
}

 

你可能感兴趣的:(爬取行政区代码)