写在前面:

GIS,即地理信息专业,算是近些年来地质方面的热门专业;当进行空间数据采集和建模地图制作和更新空间分析和决策支持地理空间数据管理地理空间数据可视化等任务是,都会涉及点坐标的数据采集,编写一个数据采集器是十分重要的。

本文代码将实现爬去指定关键词下的所有地质云点坐标信息,包含标志位、代号、详细信息、所属、地理位置、钻孔高度、钻孔深度、经纬度、图片地址以及图片保存,实现上述参数导出为excel。

(该程序算是笔者学习爬虫以来接的第一笔单,不过是帮朋友写的没收钱)

完整代码

get_info.py

import requests
import re

session = requests.Session()
kw = input("请输入关键字:")


def classify(ex, page_text_):
    res = re.findall(ex, page_text_, re.S)
    return res
#return type <list?>
#kw_ = kw.encode('utf-8')
#print(kw_)
#https://zk.cgsi.cn/MapQuery/KeySearch?page=1&many=10&keys=%E5%8C%97%E4%BA%AC&method=0
#https://zk.cgsi.cn/MapQuery/KeySearch?page=1&many=10&keys=北京&method=0


#批量爬取时,加个for循环,递增url中page的值,我电脑不行,就不试了
headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 '
                      '(KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
    }


#这边函数写法可以优化,我是最后临时加的,懒得改了
#推荐把正则筛选放外面,再加个测试try except防止程序意外崩溃
def get_infomation(kw, headers):
    url = f"https://zk.cgsi.cn/MapQuery/KeySearch?page=1&many=10&keys={kw}&method=0"
    response = session.get(url=url, headers=headers)
    page_text = response.text
    #page_json = response.json()
    #page_str = json.loads(page_json)
    #print(page_text)
    ex_marker = r'"marker":"(.*?)",'
    markers = re.findall(ex_marker, page_text, re.S)
    ex_code = r'"编号":"(.*?)",'
    codes = re.findall(ex_code, page_text, re.S)
    ex_content = r'"content":"(.*?)",'
    contents = re.findall(ex_content, page_text, re.S)
    ex_jingdu = r'"经度":"(.*?)","纬度":".*?"}'
    jingdu = re.findall(ex_jingdu, page_text, re.S)
    ex_weidu = r'"经度":".*?","纬度":"(.*?)"}'
    weidu = re.findall(ex_weidu, page_text, re.S)
    #   "经度":"91.345269","纬度":"29.585376"}
    #找图片
    #https:(.*?).jpg&
    ex_src = r'path=(.*?).jpg&'
    src_url = re.findall(ex_src, page_text, re.S)

    content_0 = []
    for content in contents:
        if 'http' not in content:
            content_0.append(content)
    kind = []
    content_2 = []
    #这边有一个小问题,如果会用json根本不需要这么麻烦,还用正则匹配
    for t in range(0, int(len(content_0))):
        if 'qq' in content_0[t] or 'com' in content_0[t]:
            kind.append(t+1)
    for t_0 in range(0, int(len(kind))):
        content_1 = []
        if t_0 == 0:
            for t_1 in range(0, int(kind[t_0]) - 1):
                content_1.append(content_0[t_1])
        else:
            for t_1 in range(int(kind[t_0 - 1]), int(kind[t_0])):
                content_1.append(content_0[t_1])
        content_2.append(content_1)
    src_url_ = []
    for src in src_url:
        src_ = src + '.jpg'
        src_url_.append(src_)

    '''
    print(markers)
    print(codes)
    print(content_0)
    print(len(content_0))
    print(kind)
    print(content_2)
    print(len(content_2))
    print(jingdu)
    print(weidu)
    print(src_url)
    print(f"长度:{len(src_url)}")
    '''
    print(f"\n查找到关于{kw}的钻孔信息如下:")
    for x in range(0, 10):
        print(f"\n标志位:{markers[x]}")
        print(f"编号:{codes[x]}")
        print(f"详细信息:")

        print(f"代号:{content_2[x][0]}-{content_2[x][1]}")
        print(f"所属:{content_2[x][3]}")
        print(f"地理位置:{content_2[x][4]}-{content_2[x][5]}")
        print(f"钻孔高度-钻孔深度:{content_2[x][6]} {content_2[x][7]}")
        print(f"经纬度:{jingdu[x]}-{weidu[x]}")
        print(f"图片地址:{src_url_[x]}")

        return src_url_, markers, codes, content_2, jingdu, weidu


src_url_0, markers, codes, content_2, jingdu, weidu = get_infomation(kw, headers)

output_excel.py

import pandas
import get_info
kw = get_info.kw
headers = get_info.headers
src_url_, markers, codes, content_2, jingdu, weidu = get_info.get_infomation(kw, headers)
daihao = []
suoshu = []
weizhi = []
chicun = []
#指定文件名和绝对路径(如果存在就写入,不存在就自动创建并写入),如果要批量爬取就设定一个文件名统一格式,get_info主程序加个循环,我怕占内存,就没尝试了
file_name = 'info.csv'
for t in range(0, 10):
    daihao_ = f"{content_2[t][0]}-{content_2[t][1]}"
    suoshu_ = content_2[t][3]
    weizhi_ = f"{content_2[t][4]}-{content_2[t][5]}"
    chicun_ = f"钻孔高度-钻孔深度:{content_2[t][6]} {content_2[t][7]}"
    daihao.append(daihao_)
    suoshu.append(suoshu_)
    weizhi.append(weizhi_)
    chicun.append(chicun_)

fp = pandas.DataFrame({'标志位': markers[:10], '编号': codes[:10], '代号': daihao, '所属':suoshu, '地理位置': weizhi, '钻孔高度-钻孔深度': chicun, '经度': jingdu, '纬度': weidu})
#以excel保存
'''
print(fp)
fp.to_excel('info.csv', index=False, sep=',')
print("Done!")
'''
#以txt保存
'''
with open('info.txt', 'a+') as f:
    f.write(str(fp))
'''

to_excel.py(数据清洗)

import re
import pandas
with open('statics', 'r', encoding='utf-8') as fp:
    statics = fp.readlines()
#print(statics)

data = statics
'''
data = re.findall("(?<=JSON\.parse\(')[A-Za-z0-9'.?!/+=;:,()\\\ \"\-{_àâçéèêëíìîôùûæœÁÀÂÃÇÉÈÊËÍÌÎÔÙÛ©´<>]*", str(data))
'''
data = data[0].encode('utf-8').decode('unicode-escape').encode('iso-8859-1').decode('utf-8')
print(data)
'''
with open('1.vhdl', 'w') as fp_:
    fp_.write(data)
'''
ex_yuanshizhi = r'data-placement=.*?title=.*?>(.*?)</span>"'
#data-placement=.*?title=.*?>(.*?)</span>"
yuanshizhi = re.findall(ex_yuanshizhi, data, re.S)
print(yuanshizhi)
print(len(yuanshizhi))
print(yuanshizhi[400])

frame = pandas.DataFrame({"省份": 1, "流域": 1, "断面名称": 1, "监测时间": 1, "水质类别": 1, '溶解氧(mg/L)': 1, '电导率(μS/cm)': 1, '浊度': 1, '高锰酸盐指数': 1, '氨氮': 1, '总磷': 1, '总氮': 1, '叶绿素': 1, '藻密度': 1})

save_src.py

import requests
import get_info
session = requests.Session()
kw = get_info.kw
headers = get_info.headers
src_url_, markers, codes, content_2, jingdu, weidu = get_info.get_infomation(kw, headers)
s = 1

#下列代码为保存图片,去掉注释符号即可,我怕占内存,不敢运行

for url in src_url_:
    response = session.get(url=url, headers=headers).content
    with open(f"详细信息{s}.jpg", 'wb') as fp:
        fp.write(response)
    
    s += 1

写在最后:

GIS专业需要对大量的地理空间数据进行管理和维护,获取点坐标是地理空间数据管理的重要步骤之一,可以确保数据的准确性和一致性;通过获取点坐标,可以将地理空间数据可视化,以更直观和有效的方式展示地理信息。地理空间数据可视化对于理解和分析地理现象具有重要意义,可以帮助用户更好地认识地理空间关系。

点坐标的获取对于GIS专业非常重要,是进行地理空间数据采集、建模、分析和决策支持的基础工作,简直就是GIS的福音。