欢迎光临
我们一直在努力

使用 LINQPad 缓存 2021 年统计用区划代码和城乡划分代码五级库

国家统计局于 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

赞(1) 打赏
未经允许不得转载:码农很忙 » 使用 LINQPad 缓存 2021 年统计用区划代码和城乡划分代码五级库

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

给作者买杯咖啡

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏