爬取公共交通的线路和站点

基于python和某公共交通网站实现爬取城市公交和地铁的线路和站点的功能

一、爬取公共交通线路和站点

#导入python库
import json
import requests
from lxml import etree
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point

import transbigdata as tbd
from tqdm import tqdm

#获得所有的网页url
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'}
url = 'http://shanghai.8684.cn' ##开始的URL地址

def request_html(url):
	sort = requests.get(url = url,headers = headers)
	tree = etree.HTML(sort.text)
	#提取线路分类信息
	route_list = tree.xpath("//div[@class='pl10'][3]/div/a/@href")
	#print(sort)
	route_url1 = []
	for route in route_list:
		r = url + route
		route_url1.append(r)
	return route_url1

#获取上海市所有公共交通线路名称
names = [
'轨道交通',
'常规线路',
'高峰线路',
'夜宵线路',
'轮渡线路',
'穿梭巴士',
'旅游线路',
'机场线路',
'虹桥枢纽线路',
'国际旅游度假区线路',
'中运量线路',
'申崇专线',
'跨省线路',
'BRT快速公交',
'扫墓专线',
'进博会专线',
'定制公交',
'区域公交-普陀',
'区域公交-长宁',
'区域公交-嘉定',
'区域公交-宝山',
'区域公交-青浦',
'区域公交-金山',
'区域公交-闵行',
'区域公交-奉贤',
'区域公交-浦东',
'区域公交-崇明',
'区域公交-松江',
'文字线路-市枢往返郊区',
'文字线路-郊区往返郊区']
count = 0
for i in request_html(url)[0:1]:
    print(i)
    #得到每一页的公共交通线路名称
    PUT = []
    soup = BeautifulSoup(requests.get(i).text, 'lxml')
    soup_div = soup.find_all('div',attrs = {'class':'list clearfix'})[0]
    soup_div_a = BeautifulSoup(str(soup_div),'lxml')
    for j in soup_div_a.div.find_all('a'):
        PUT.append(str(j).split('">')[1][:-4])

    #线路名称数据清洗,去除停运的
    PUT = [i.split('(')[0] for i in PUT ] 
    PUT = pd.Series(PUT)
    PUT = PUT[-(PUT.str.contains('停运'))]
    PUT = PUT.str.replace('轨道交通','地铁')
    
    #调用tbd获取线路和站点数据
    line,stop = tbd.getbusdata('上海',list(PUT)) #坐标系为84
    line.crs = 4326
    stop.crs = 4326
    line.to_file('站点_地铁+公交\\lines\\'+names[count] +'.shp',encoding = 'utf-8')
    stop.to_file('\站点_地铁+公交\\stops\\'+names[count] +'.shp',encoding = 'utf-8')
    count = count +1

二、清洗数据

代码如下(示例):

#重新导入,并去重
gdf_stops = gpd.GeoDataFrame(columns = ['stationnam', 'linename', 'lon', 'lat', 'line', 'id', 'geometry'])
gdf_stops = gdf_stops.set_geometry('geometry')
for i in names:
    stop = gpd.read_file('\\站点_地铁+公交\\stops\\'+i+'.shp')
    gdf_stops = pd.concat([gdf_stops,stop])

#去重
gdf_stops = gdf_stops.drop_duplicates()
gdf_stops.crs = 4326
gdf_stops.to_file(r'\站点_地铁+公交\sh_stops.shp',encoding = 'utf-8')

思路总结

①基于在线公交网站爬取其静态页面,得到该城市的所有公交线路名称。(存在少部分线路名称更新不及时而导致后面爬取失败)
②利用tbd的getbusdata函数爬取线路及站点数据。(存在爬取重复线路情况,比如13号线和13号线西延伸就可能导致重复爬取13号线)
③对爬取的数据进行去重等处理,提高数据质量。

你可能感兴趣的:(python,爬虫)