前言:vscode作为一款轻量级的编辑器,界面整洁,操作方便,虽然比不上pycharm的功能齐全,但对新手来说已经足够了。具体的python开发环境配置可以参考以下链接。VSCode配置Python开发环境
目录
一. 爬取思路
二. 页面分析
三. 代码实现
四. 成果展示
Reference:
一. 爬取思路
1.首先从高德地图找到地铁线路以及站点页面。http://map.amap.com/subway/index.html
图一
2.在此页面按F12,点击Network,得到图二所示的地址。右键该地址选择Open in new tab转到图三,可以看到我们需要的站点以及路线信息就在此位置下。我们要做的就是构造这个url。
图二
图三
二. 页面分析
1. 打开多个城市的页面尝试以上步骤可以看出我们需要访问的所以url中只有城市编码和城市的名称不同。那么这个一一对应的城市编码我们应该去哪里找呢?这时候就需要一点点的html知识,在层层嵌套的页面中找到所需要的信息。
图四
最终我们在图四所示的div中找到了所需要的信息,接下来就可以开始写代码了。
三. 代码实现
1.引入需要的包,构建请求头
import requests
import json
import csv
from lxml import etree
PAGE_URL = 'http://map.amap.com/subway/index.html?&1100'
DATA_URL = 'http://map.amap.com/service/subway?srhdata='
HEADER = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
}
2.主要代码
def fetchAllCity(url, header):
r = requests.get(url, header)
html = r.content
element = etree.HTML(html)
#使用xpath函数结合xpath表达式进行标签定位和指定数据提取
options = element.xpath("//a[contains(@class, 'city')]")
#存入cities
cities = []
for option in options:
city = {
'id': option.get('id'),
'name': option.get('cityname'),
'text': option.text
}
cities.append(city)
return cities
def parseCityData(citys):
lw = open('./ditie_line.txt', 'a')
lw.write('\n')
pw = open('./ditie_point.txt', 'a')
pw.write('\n')
for city in citys:
parseCityPointFromApi(city, lw, pw)
def parseCityPointFromApi(city, lw,pw):
#构建url并输出检查
url = DATA_URL + "{}_drw_{}.json".format(city['id'], city['name'])
print(url)
#发出请求并解析json
json_str = requests.get(url).text
lines_list = json.loads(json_str).get('l')
# 地铁线路信息表
lw = open("ditie_line.txt",'a',encoding="utf-8")
pw = open("ditie_point.txt",'a',encoding="utf-8")
lineInfo_list = []
for line in lines_list:
#每条线的信息集合,可根据个人需要在这一步选择需要的字段
lineInfo = {}
lineInfo['ln'] = line.get('ln')
lineInfo['cl'] = line.get('cl')
print(lineInfo['ln'],lineInfo['cl'],city['name'],city['text'],file=lw)
#线路站点列表
station_list = []
st_list = line.get('st')
for st in st_list:
station_dict = {}
station_dict['name'] = st.get('n')
coord = st.get('sl')
station_dict['lat'] = coord.split(',')[0]
station_dict['lon'] = coord.split(',')[-1]
print(station_dict['name'],station_dict['lat'],station_dict['lon'],city['name'],city['text'],lineInfo['ln'],file=pw)
station_list.append(station_dict)
def csvMaker():
#txt储存为csv
with open('./ditie_point.csv','w',newline='') as f:
f_csv=csv.writer(f)
for line in open('E:\python\spider\ditie_point.txt', 'r',encoding='utf-8'):
new_line = line.strip().split()
f_csv.writerow(new_line)
with open('./ditie_line.csv','w',newline='') as f:
f_csv=csv.writer(f)
for line in open('E:\python\spider\ditie_line.txt', 'r',encoding='utf-8'):
new_line = line.strip().split()
f_csv.writerow(new_line)
def main():
cities = fetchAllCity(PAGE_URL, HEADER)
print(cities)
parseCityData(cities)
if __name__ == '__main__':
main()
csvMaker()
四. 成果展示
这里我选择了csv格式的结果,有需要的话可以通过arcpy直接转为空间数据。
图五 成果展示
图六 地铁站点信息
图七 地铁路线信息