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;
    }
    
  • 相关阅读:
    jsp和servlet的联系与区别
    tomcat会如何处理请求
    java中synchronized的关键字
    mybatis的动态sql
    spring自带的json转换工具,支持@ResponseBody注解
    layer一个web弹窗/层解决方案
    spring mvc出现乱码的问题
    hdu1010 Tempter of the Bone
    hdu 3342 Legal or Not
    ThreadPoolExecutor线程池执行器源码解析
  • 原文地址:https://www.cnblogs.com/oloroso/p/9674716.html
Copyright © 2011-2022 走看看