php mysql最新全国地区sql表下载

首先我得道歉,因为我做了一回标题党。但我想也并没让你失望吧,虽然没有现在成的sql,但亲写的php脚本同样可以生成烫手的sql!

本博客参考中国统计局2017最新数据进行编写的,有必要的话你可以改成对应最新版本即可。

准备:一张表(id,pid,url,level,name)
注意:本脚本默认获取三级,最多可获取到4级,自行调整!由于平台限制,可能得刷新请求大概5次左右才能完全下载完省市区(直接返回空数组,即下载完成)
技术点:运用了递归和正则匹配,特别的名称进行了处理(如:省直辖县级行政区划、市辖区、县),至于数据库看着替换上即可!
以下代码附上:

function curl_get($url){
    //初始化
    $curl = curl_init();
    //设置抓取的url
    curl_setopt($curl, CURLOPT_URL, $url);
    //设置头文件的信息作为数据流输出
    curl_setopt($curl, CURLOPT_HEADER, 1);
    //设置获取的信息以文件流的形式返回,而不是直接输出。
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    //执行命令
    $data = curl_exec($curl);

    if (curl_errno($curl)) {
        $curl_error = curl_error($curl);
        throw new Exception ($curl_error, 0);
    } else {
        $httpStatusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        if (200 !== $httpStatusCode) {
            throw new Exception ($data, $httpStatusCode);
        }
    }
    //关闭URL请求
    curl_close($curl);
    //显示获得的数据
    return $data;
}
function getAddress($url, $pid=0, $level=1, $p_name , $data=array()){
    try{
        // 拼接请求链接
        $html = curl_get($url);

        // 以下为节点要点字眼,选择自己要的地区等级字眼则可
        // provincetr|citytr|countytr|towntr|villagetr
        preg_match_all('/(provincetr|citytr|countytr).*<td(.*)td/i',$html,$res1);

        if($res1){
            $tr = $res1[0][0];
            preg_match_all('/<td.*?>.*?href=[\'|"](.*?)[\'|"]>(.*?)(<\/br>)?<\/a><\/td/',$tr,$res2);

            foreach ($res2[2] as $key => $value) {
                $curll_val = $res2[1][$key];
                $curll_url = substr($url,0, strrpos($url, '/') + 1) . $curll_val;
                $select_sql = "select * from test_region where url='{$curll_val}'";
                $exist = $GLOBALS['db_separate']->getRow($select_sql);

                // 如果已经存在该父级节点,则跳过
                if ($exist){
                    continue;
                }

                $value = trim(strip_tags($value));
                if (!is_numeric($value) && !empty($value)) {
                    // 转换成数据库的编码
                    $encode = mb_detect_encoding($value, array('ASCII','UTF-8','GB2312','GBK','BIG5'));
                    // EUC-CN
                    $value = iconv( $encode, 'utf-8',$value);

                    // 湖北仙桃 河南济源 海南五指山 文昌等
                    if($value == '省直辖县级行政区划'){ // 向上推一级
                        $data += getAddress($curll_url, $pid, $level, $value);  // 可选择性去掉
                    } else {
                        // 每个顶级节点做一次事务,从而保障就算出错也不会出现漏数据
                        $level == 1 && $GLOBALS['db_separate']->beginTransaction();

                        // 如果是市辖区或只有县,则用低级名称
                        //县 重庆城口 丰都等
                        if($value == '市辖区' || $value == '县'){ // 替换成上级的名称
                            $value = $p_name;
                        }

                        // 初始保证变量没被污染
                        $sub_pid = '';
                        if($value == '重庆市'){
                            $sql = "select id from test_region where level='{$level}' and region_name='{$value}'";
                            $sub_pid = $GLOBALS['db_separate']->getOne($sql);
                        }

                        if(empty($sub_pid)){
                            $row = array('region_name'=>trim(strip_tags($value)), 'url'=>$curll_val, 'level'=>$level, 'pid'=>$pid);
                            // 向数据库插入一条数据
                            $GLOBALS['db_separate']->insert('test_region', $row);
                            // 把当前的id作为自己子级的父ID
                            $sub_pid = $GLOBALS['db_separate']->lastInsertId();

                        }

                        // 递归查找自己的子级
                        $row['child'] = getAddress($curll_url, $sub_pid, $level +1, $value);
                        $data[] = $row;

                        // 如果该顶节点回调完才会提交自己的事务
                        $level == 1 && $GLOBALS['db_separate']->commit();
                    }

                }
                // file_put_contents('res.txt', var_export($data,true));
            }
        }
    }catch (Exception $e){
        // 如果帮忙错,则回滚事务再刷新当前页,以此来继续操作插入完成未处理的数据
        echo '出错了哦~' . $e->getMessage();
        $reload_srcipt = "<script>location.reload()</script>";
        try{
            $GLOBALS['db_separate']->rollBack();  // 必须先回滚再刷新
            echo $reload_srcipt;
        }catch (Exception $e_sub){
            echo $reload_srcipt;
        }
    }

    // 返回本次处理过的结果集
    return $data;
}

set_time_limit(0);
$url = 'http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2017/index.html';
$data = getAddress($url);

var_dump($data);

猜你喜欢

转载自blog.csdn.net/qq_27974479/article/details/83304604