国家统计局于 2021 年 12 月 30 日发布了《2021年统计用区划代码和城乡划分代码》,详细链接在这里:
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/index.html
2021年度全国统计用区划代码和城乡划分代码更新维护的标准时点为2021年10月31日。目前,已完成更新维护工作,现予公布。
2021年统计用区划代码和城乡划分代码依据国务院批复同意的《关于统计上划分城乡的规定》(国函〔2008〕60号)及国家统计局印发的《统计用区划代码和城乡划分代码编制规则》(国统字〔2009〕91号)编制。
此次发布内容为2021年全国统计用区划代码(12位)和城乡分类代码(3位),地域范围为国家统计局开展统计调查的全国31个省(自治区、直辖市),未包括我国台湾省、香港特别行政区和澳门特别行政区。
《关于统计上划分城乡的规定》指出:“本规定作为统计上划分城乡的依据,不改变现有的行政区划、隶属关系、管理权限和机构编制,以及土地规划、城乡规划等有关规定”。统计用区划代码和城乡划分代码用于统计工作,需要在其他工作中使用时,请务必结合有关实际情况。
目标分析
本次的目标是使用 LINQPad 编辑运行 C# 脚本将整个内容全部离线到本地。
目标网页的结构很简单,各个网页之间都使用相对路径进行链接且都包含了文件名,这让我们可以很容易将内容离线到本地。
此外,通过观察地址栏,目标内容的 URL 地址全部都是以固定内容开头的,即:
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021
一个简单的实现就是:创建一个队列,并将首页地址入队。接着,不停的从队列中获取任务。如果任务没有缓存在本地,则发起一个 HTTP 请求进行缓存。如果已经缓存那么就使用 HtmlAgilityPack 分析网页,获得所有 a 标签后,拼接出跳转 URL 并判断是否需要进行缓存。如果需要缓存,则将 URL 入队,否则跳过。
HTTP 请求失败是很常见的事情,所以需要在遇到异常时进行重试。也不能请求过快,为目标服务器造成压力。
LINQPad 代码
var dir = @"D:\data\www.stats.gov.cn";//文件缓存目录 var basic = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/";//起始网页地址 var handler = new HttpClientHandler() { UseCookies = true };//配置使用 Cookie var http = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(5)};//配置 5 秒超时 var queue = new Queue<string>(); queue.Enqueue("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/index.html"); var lastTask = Task.CompletedTask; Util.AutoScrollResults = true;//自动滚动结果 var st = new Stopwatch(); var times = 0; while (queue.TryDequeue(out var url)) { times++; if (times % 100 == 0) { Util.ClearResults(); } Console.WriteLine(DateTime.Now); Console.WriteLine("处理:{0}",url); var uri = new Uri(url); var path = uri.LocalPath.TrimStart('/'); var target = Path.Combine(dir, Path.GetDirectoryName(path)); if (!Directory.Exists(target)) { Console.WriteLine("创建目录:{0}",target); Directory.CreateDirectory(target); } target = Path.Combine(target,Path.GetFileName(path)); if (!File.Exists(target)) { Console.WriteLine("下载文件:{0}", url); await lastTask; try { st.Restart(); var html = await http.GetStringAsync(url); st.Stop(); Console.WriteLine("耗时: {0}毫秒",st.ElapsedMilliseconds); await File.WriteAllTextAsync(target, html, Encoding.UTF8); lastTask = Task.Delay(TimeSpan.FromSeconds(1)); } catch (Exception e) { e.Message.Dump("出现异常,休眠 10 秒钟。"); lastTask = Task.Delay(TimeSpan.FromSeconds(10)); queue.Enqueue(url); continue; } } //分析内容 var doc = new HtmlDocument(); doc.Load(target,Encoding.UTF8); var links = doc.DocumentNode.SelectNodes("//a"); if (links != null && links.Count > 0) { var add = 0; foreach (var link in links) { var href = link.GetAttributeValue("href", string.Empty); if (string.IsNullOrWhiteSpace(href)) continue; var next = new Uri(new Uri(url), href); var str = next.ToString(); ; if (str.StartsWith(basic)) { add++; queue.Enqueue(str); } } if (add > 0) { Console.WriteLine("Add: {0}", add); } } }
数据下载
经过漫长的等待,终于将全部网页都进行了离线。
链接: https://pan.baidu.com/s/17nbDeQD68QvVzqtqby6_ZQ?pwd=habc
提取码: habc