zoukankan      html  css  js  c++  java
  • 抓取epsg.io的内容

    简述

    epsg.io是一个查询EPSG坐标系相关信息的好网站,内容很全。有各种格式的定义可以直接下载,也有坐标系的范围名称等相关信息,所以想抓取这些信息下来,方便对接各个系统。
    epsg.io本身是开源的,代码在https://github.com/klokantech/epsg.io上,但是这个我分析出数据来源,应该是在epsg.io/gml/gml.sqlite文件中,但是我打开这个文件发现没有相关的记录。

    抓取说明

    抓取的时候使用的是proj4项目里的nad/epsg文件中的记录作为索引,找到对应的epsg代码去拼成对应url去下载。
    下面是代码,用的是libcurl进行的相关操作。日志记录简单的用了一下glog,可以去掉,去掉之后就是纯C的代码了。
    抓取的结果直接写在程序目录下的epsg.io目录下,请先创建好这个目录。
    保存的html文件的解析,可以参考HTML解析库Gumbo简单使用记录

    抓取好的文件可以在这里epsg.io.7z下载,解压压缩之后会有三百多兆,共5754个文件。
    分析后提取的内容,生成了一个超大的JSON文件,可以再这里epsg.io.json.7z下载。


    我把抓取的内容处理成json后,又将其导入了MongoDB数据库。
    这里将数据备份后上传在这里https://files.cnblogs.com/files/oloroso/epsg.io.mongodb.7z,这个数据可以直接使用mongorestore工具恢复到数据库。
    导入MongoDB的数据中,wgs84_bound字段名改为84boxproj_bound字段改为projbox,中心点坐标经过处理,不会有null出现。

    代码

    // g++ epsg.spider.cpp -o epsg.spider -lcurl  -lglog -lpthread
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <curl/curl.h>
    #include <glog/logging.h>
    
    
    int downpage(int epsgcode)
    {
    	int ret = 0;
    	char url[1024];
    	sprintf(url,"./epsg.io/%d.html",epsgcode);
    	FILE* fp = fopen(url,"wb");
    	if(fp == NULL){
    		fprintf(stderr,"
    创建输出文件失败i
    ");
    		ret = -1;
    		return ret;
    	}
    
    	sprintf(url,"http://epsg.io/%d",epsgcode);
    	CURL *hnd = curl_easy_init();
    	curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET");
    	curl_easy_setopt(hnd, CURLOPT_URL, url);
    	curl_easy_setopt(hnd, CURLOPT_COOKIEFILE, "./epsg.spider.cookie");
    	//curl_easy_setopt(hnd, CURLOPT_COOKIE, cookie_buffer);
    
    	curl_easy_setopt(hnd, CURLOPT_WRITEDATA, fp);
    
    	CURLcode res = (CURLcode)curl_easy_perform(hnd);
    	if(res != CURLE_OK) {
    		fprintf(stderr,"
    %s curl_easy_perform failed:%s
    ",url,curl_easy_strerror(res));
    		ret = -2;
    	}
    	fclose(fp);
    	curl_easy_cleanup(hnd);
    	return ret;
    }
    
    int main(int c,char** v)
    {
           // 打开epsg文件
    	FILE* fp = fopen("epsg","r");
    	if(fp == NULL){ 
    		puts("open epsg fiaild");
    		return 0;
    	}
    	google::InitGoogleLogging(v[0]);
    	FLAGS_log_dir = ".";
     
    	  /*
    	   * 这个函数只能用一次,如果这个函数在curl_easy_init函数调用时还没调用,
    	   * 它讲由libcurl库自动调用,所以多线程下最好在主线程中调用一次该函数以防止在线程
    	   * 中curl_easy_init时多次调用
    	   */
    	  curl_global_init(CURL_GLOBAL_ALL);
    
    	char s[4096];
    
    	puts("开始下载:");
    	while(!feof(fp) && limit > 0){
    		int epsgcode = 0;
    		static char name[1024];
    		static char proj[1024];
    		fgets(s,sizeof s,fp);
    		if(s[0] == '#' ){
    			sscanf(s,"# %[^
    ]s",name);
    		}
    		sscanf(s,"<%d> %[^
    <]s",&epsgcode,proj);
    		if(epsgcode == 0){
    			continue;
    		}
    		char path[128];
    		sprintf(path,"./epsg.io/%d.html",epsgcode);
    		struct stat st;
    		if(stat(path,&st) == 0) {
    			if(st.st_size > 1024){
    				// printf("%5d   %s exsits
    ",epsgcode,path);
    				continue;
    			}
    		}
    
    		printf("
    正在下载:http://epsg.io/%d ",epsgcode);
    		LOG(INFO) << "begin download http://epsg.io/"<<epsgcode;
    		if( downpage(epsgcode) != 0){
    			break;
    		}
    		LOG(INFO) << "finish download http://epsg.io/"<<epsgcode;
    	}
    
    	//在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数
    	curl_global_cleanup();
    
    	fclose(fp);
    	return 0;
    }
    
  • 相关阅读:
    LeetCode Merge Two Sorted Lists 归并排序
    LeetCode Add Binary 两个二进制数相加
    LeetCode Climbing Stairs 爬楼梯
    034 Search for a Range 搜索范围
    033 Search in Rotated Sorted Array 搜索旋转排序数组
    032 Longest Valid Parentheses 最长有效括号
    031 Next Permutation 下一个排列
    030 Substring with Concatenation of All Words 与所有单词相关联的字串
    029 Divide Two Integers 两数相除
    028 Implement strStr() 实现 strStr()
  • 原文地址:https://www.cnblogs.com/oloroso/p/9674716.html
Copyright © 2011-2022 走看看