欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

利用python爬取城市公交站点

程序员文章站 2022-06-18 08:09:10
目录页面分析爬虫数据清洗excel pq 数据清洗python数据清洗qgis坐标纠偏导入csv文件坐标纠偏总结利用python爬取城市公交站点页面分析https://guiyang.8684.cn/...

利用python爬取城市公交站点

页面分析

https://guiyang.8684.cn/line1

利用python爬取城市公交站点

利用python爬取城市公交站点

爬虫

我们利用requests请求,利用beautifulsoup来解析,获取我们的站点数据。得到我们的公交站点以后,我们利用高德api来获取站点的经纬度坐标,利用pandas解析json文件。接下来开干,我推荐使用面向对象的方法来写代码。

import requests
import json
from bs4 import beautifulsoup
import pandas as pd
​
​
class bus_stop:
 ## 定义一个类,用来获取每趟公交的站点名称和经纬度
 def __init__(self):
 self.url = 'https://guiyang.8684.cn/line{}'
 self.starnum = []
 for start_num in range(1, 17):
 self.starnum.append(start_num)
 self.payload = {}
 self.headers = {
 'cookie': 'jsessionid=48304f9e8d55a9f2f8acc14b7ec5a02d'}
 ## 调用高德api获取公交线路的经纬度
 ### 这个key大家可以自己去申请
 def get_location(self, line):
 url_api = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=559bdffe35eec8c8f4dae959451d705c&output=json&city=贵阳&offset=2&keywords={}&platform=js'.format(
 line)
 res = requests.get(url_api).text
 # print(res) 可以用于检验传回的信息里面是否有自己需要的数据
 rt = json.loads(res)
 dicts = rt['buslines'][0]
 # 返回df对象
 df = pd.dataframe.from_dict([dicts])
 return df
 ## 获取每趟公交的站点名称
 def get_line(self):
 for start in self.starnum:
 start = str(start)
 # 构造url
 url = self.url.format(start)
 res = requests.request(
 "get", url, headers=self.headers, data=self.payload)
 soup = beautifulsoup(res.text, "lxml")
 div = soup.find('div', class_='list clearfix')
 lists = div.find_all('a')
 for item in lists:
 line = item.text  # 获取a标签下的公交线路 
 lines.append(line)
 return lines
​
​
if __name__ == '__main__':
 bus_stop = bus_stop()
 stop_df = pd.dataframe([])
 lines = []
 bus_stop.get_line()
 # 输出路线
 print('一共有{}条公交路线'.format(len(lines)))
 print(lines)
 # 异常处理
 error_lines = []
 for line in lines:
 try:
 df = bus_stop.get_location(line)
 stop_df = pd.concat([stop_df, df], axis=0)
 except:
 error_lines.append(line)

 # 输出异常的路线 
 print('异常路线有{}条公交路线'.format(len(error_lines))) 
 print(error_lines)

 # 输出文件大小 
 print(stop_df.shape)
 stop_df.to_csv('bus_stop.csv', encoding='gbk', index=false)

利用python爬取城市公交站点

数据清洗

我们先来看效果,我需要对busstops列进行清洗。我们的总体思路,分列->逆透视->分列。我会接受两种方法,一是excel pq,二是python。

利用python爬取城市公交站点

利用python爬取城市公交站点

excel pq 数据清洗

这一方法完全利用pq,纯界面操作,问题不大,所以我们看看流程就可以了,核心步骤就是和上面一样的。

利用python爬取城市公交站点

python数据清洗

## 我们需要处理的busstops列和id列
data = stop_df[['id','busstops']]
data.head()

利用python爬取城市公交站点

## 字典或者列表分列
df_pol = data.copy()
### 设置索引列
df_pol.set_index('id',inplace=true)
df_pol.head()

利用python爬取城市公交站点

## 逆透视
### 释放索引
df_pol.reset_index(inplace=true)
### 逆透视操作
df_pol_ps = df_pol.melt(id_vars=['id'], value_name='busstops')
df_pol_ps.head()

利用python爬取城市公交站点

## 删除空行
df_pol_ps.dropna(inplace=true,axis=0)
df_pol_ps.shape 

利用python爬取城市公交站点

## 分列
### 设置line_id
df_parse['line_id'] = df_pol_ps['id']
df_parse = df_pol_ps['busstops'].apply(pd.series)
df_parse

利用python爬取城市公交站点

我这里补充一下,我们一般还要对location列进行分列,把long,lat分列出来,但是我们这里就不做了,都是重复劳动,而且我用的pq清洗,快很多。

## 写入文件
df_parse.to_excel('贵阳市公交站点分布.xlsx', index=false)</pre> 

qgis坐标纠偏

qgis基础操作,我就不说了,顺便说一下qgis对csv格式支持较好,我推荐我们导入qgis的文件为csv格式的文件。

导入csv文件

利用python爬取城市公交站点

坐标纠偏

以前说了很多,我们高德地图上的坐标是gcj02坐标,我们需要转成wgs 1984坐标,我们在qgis里面需要借助geohey插件。

利用python爬取城市公交站点

利用python爬取城市公交站点

看一下这个坐标纠偏,区别还是很大。

总结

总的来说,我们还是推荐使用使用面向对象的方法来写代码,还有就是异常处理必不可少。我这次面对的问题是某些公交路线,高德api里面没有,这样就会异常,所以这次的异常处理不可缺少。从数据处理的角度来看,这次从速度和方便来说,pq完胜python,我推荐大家数据清洗就用pq,有些时候,我都会给出多种处理方法,pq看起来复杂,但是其实pq是最简单的,总之,我高度推荐pq进行数据清洗。还有一点,python里面的索引比较麻烦,这次我要保证和bus_stop_id和line_id,这样公交站点表和公交路线表才可以连接,其实这就是sql里面的外键连接,所以我在python数据清洗的时候,涉及到大量的索引操作,在pq里面没有这么复杂。说到这个索引,感谢我的sql老师,当年她讲解sql里面的索引,约束,仿佛就在昨天。高德的这个key大家可以自己去申请,这个key可能有数量的限制。我接下来会把代码上传到gitee,这个代码的管理还是很重要的,自己也学习一下代码的管理。接下来,感谢小学妹给的这个小项目,也感谢崔工对我的鼓励,其实,我最近很忙,不太想写文章的。最后,感谢认识的一个小学妹,她真的蛮优秀的,最后希望大家2021年最后这一个月万事如意,开开心心,也希望我们都有一个光明的未来。还有一个坑,我建议大家在简书上写文章,真的本地的话,图片上传有问题。

以上就是利用python爬取城市公交站点的详细内容,更多关于python爬取城市公交站点的资料请关注其它相关文章!