因为去年全国多个城市重新划分行政管理区域,所以以前的行政区域数据要更新一遍,然后就抽空写了一个比较简易的php爬取行政区域编码的方法。
这个方法有很多缺点,耗时,非常的耗时,效率也不高,基本上都是跑到超时了。不过我想着反正也抓取到数据了,就没有继续去优化了。
如果有更好的实现方法,还请多多指教。
- 调用getCityCode()方法
//获取全国最新行政区域编码
public function getCityCode()
{
ini_set('memory_limit', '4096M'); // 临时设置最大内存占用
set_time_limit(0); // 设置脚本最大执行时间 为0 永不过期
//抓取2020年的全国最新行政区域编码
$data = iconv('gbk', 'utf-8//IGNORE', file_get_contents('http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/index.html'));
$html = self::getSubstr($data, '况', '</TD>');
$pat = "/<a(.*?)href='(.*?)'(.*?)>(.*?)<\/a>/i";
preg_match_all($pat, $html, $province);
$province_code = [];
$city_code = [];
$area_code = [];
foreach ($province[4] as $key => $value) {
//补全省的行政编码
$code = explode('.', $province[2][$key])[0] . '0000000000';
$province_code[$code] = [
'id' => (int)$code,
'name' => trim($value, '<br/>'),
'parent_id' => 0, //省级
'level' => 1,
];
}
//市/区/街道
foreach ($province[2] as $key => $value) {
$province_code_num = explode('.', $value)[0] . '0000000000';
$city_data = $this->getMore($value, $province_code_num);
//数组的长度
//组城市
for ($i = 0; $i < count($city_data[4]); $i += 2) {
$city_code_num = $city_data[4][$i];
$city_code[$city_code_num] = [
'id' => (int)($city_code_num),
'name' => $city_data[4][$i + 1],
'parent_id' => (int)$province_code_num,
'level' => 2,
];
//组区数据
$area_data = $this->getMore($city_data[2][$i]);
//数组的长度
for ($j = 0; $j < count($area_data[4]); $j += 2) {
$area_code_num = $area_data[4][$j];
$area_code[$area_code_num] = [
'id' => (int)($area_code_num),
'name' => $area_data[4][$j + 1],
'parent_id' => (int)$city_code_num,
'level' => 3,
];
// //组街道 最后没有抓取街道的了,因为超时了..
//
// $street_data = $this->getMore(explode('.', $value)[0] . '/' . $area_data[2][$j]);
//
//
// //数组的长度
//
// for ($k = 0; $k < count($street_data[4]); $k += 2) {
//
// $street_code_num = $street_data[4][$k];
// $street_code[$street_code_num] = [
// 'id' => (int)($street_code_num),
// 'name' => $street_data[4][$k + 1],
// 'parent_id' => $area_code_num,
// 'level' => 4,
// ];
// }
}
}
}
$all_code = array_merge($province_code, $city_code, $area_code);
//写入文件
file_put_contents('D:/city.php', "<?php \n return " . var_export($all_code, true) . ";");
exit('完毕');
}
public function getMore($url)
{
//解决g_zip引起的乱码,城市的页面需要设置compress.zlib://解决gzip引起的乱码问题
$data = file_get_contents('compress.zlib://http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/' . $url);
$data = iconv('gbk', 'utf-8//IGNORE', $data);
$html = Self::getSubstr($data, '名称', '</TD>');
$pat = "/<a(.*?)href='(.*?)'(.*?)>(.*?)<\/a>/i";
preg_match_all($pat, $html, $html_data);
if (count($html_data[2]) > 0) {
$html_data['is_end'] = 'false';
// $html_data[2] = array_unique($html_data[2]);
} else {
$html_data['is_end'] = 'true';
}
return $html_data;
}
static function getSubstr($str, $leftStr, $rightStr)
{
$llen = strlen($leftStr);
$left = strpos($str, $leftStr);
$right = strpos($str, $rightStr, $left + $llen);
if ($left < 0 || $right < $left)
return "";
return substr($str, $left + $llen, $right - $left - $llen);
}