关于简易爬虫和地图调用

syan 发布于 2020-08-13 1271 次阅读


这是一次很简单的关于爬虫的尝试,毕竟在大多数需要使用爬虫的情况下,网页并不会以api的形式返回给你如此工整的数据。稍微记录一下吧,以备后续使用

虽然我觉得我不会再用百度地图了就是

百度地图很麻烦就在,想进行路径规划只能使用地点的经纬度,据同学说高德地图的api就不存在这个坑爹问题,虽然也可以称之为严谨啦,但是还是令人相当不爽

import requests
import json

obj = "疾控中心"
city = "杭州"
ak = "******"

req_url = "http://api.map.baidu.com/place/v2/search?query={obj}&region={city}&output=json&ak={ak}".format(obj=obj, city=city, ak=ak)

response = requests.get(req_url)
ans = response.json()
with open(r"5 - I'M VIRU\Codes\loc.json", 'w', encoding='utf-8') as file:
    file.write(json.dumps(ans, indent=2, ensure_ascii=False))

这是一个相当简易的访问请求并获取json文件的构造,通过向百度api访问杭州市疾控中心的信息,获取相关的所有资料,并储存在json文件中。其格式大概是这样的

{
  "status": 0,
  "message": "ok",
  "results": [
    {
      "name": "杭州市疾病预防控制中心",
      "location": {
        "lat": 30.313231,
        "lng": 120.234488
      },
      "address": "笕桥镇明石路568号杭州市公共卫生中心内",
      "province": "浙江省",
      "city": "杭州市",
      "area": "江干区",
      "street_id": "a5fad7a038e5e19a714b871d",
      "detail": 1,
      "uid": "a5fad7a038e5e19a714b871d"
    }
  ]
}

还算不错,第一个目标就是我们需要的。

然后使用了比较拉胯的手段把一串json文件通过网页转化成了csv文件,然后整理获得了疾控中心与地理坐标location的对应关系。使用的网页是这一家JSON To CSV Converter,还算很舒服了,非常值得推介,整理得表格

lid    lat lng
卫生健康委员会    30.253522   120.216045
杭州市疾控中心    30.313231   120.234488
​``````
余杭区疾控中心    30.402791   120.290841
西湖区疾控中心    30.288965   120.070272

接下来,使用代码构造地点间的路由矩阵,并配置信息

import pandas as pd
import csv
import re
import time
import json
from urllib.request import urlopen
import urllib

pathlist = r"5 - I'M VIRU\Codes\list.csv"
resultlist = r"5 - I'M VIRU\Codes\result.csv"

# 选取坐标格式,bd09ll(百度经纬度坐标)
cod = r"&coord_type=bd09ll"

# 你的AK
AK = '******'

# 读取初始矩阵
init_list = pd.read_csv(pathlist, sep='\s', encoding='utf-8')
init_list.head()

target_list = []

# 遍历行,构建路由矩阵
for _, row1 in init_list.iterrows():
    lid1 = row1["lid"][0]
    lat1 = row1["lat"]
    lng1 = row1["lng"]
    for _, row2 in init_list.iterrows():
        lid2 = row2["lid"][0]
        lat2 = row2["lat"]
        lng2 = row2["lng"]
        target_list.append([str(lid1)+'2'+str(lid2), lat1, lng1, lat2, lng2])

target_df = pd.DataFrame.from_records(
    target_list, columns=['id', 'olat', 'olng', 'dlat', 'dlng'])
print(target_df)

result_list = []

for i in range(len(target_df)):
    olat = target_df.at[i, 'olat']
    olng = target_df.at[i, 'olng']
    dlat = target_df.at[i, 'dlat']
    dlng = target_df.at[i, 'dlng']

    # 编撰req申请网址
    req_url = r"http://api.map.baidu.com/routematrix/v2/driving?output=json&origins={0},{1}&destinations={2},{3}&{4}&tactics=11&ak={4}".format(
        olat, olng, dlat, dlng, AK)

    result_drive = json.loads(urlopen(req_url).read())  # json转dict

    # 距离/耗时
    distance = result_drive['result'][0]['distance']['value']
    times = result_drive['result'][0]['duration']['value']

    result_list.append([target_df.at[i, 'id'], distance, times])

# 写文件
result_pd = pd.DataFrame.from_records(
    result_list, columns=['id', 'dis', 'time'])

result_pd.to_csv(resultlist)

然后就能获得一个路由矩阵的列啦,接下来还可以再对行列进行处理以方便调用,但是那是明天求解时的事情了(x

话说我不是退数模了吗,为啥还要搞这幺蛾子