这篇文章将为大家详细讲解有关Python如何爬取地铁线路图,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
BeautifulSoup:“美味的汤,绿色的浓汤”,是一个可以从HTML或XML文件中提取数据的Python库。BeautifulSoup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
BeautifulSoup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,BeautifulSoup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
可以直接使用pip安装:
pip install BeautifulSoup
BeautifulSoup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如,lxml,XML,html5lib等,但是需要安装相应的库:
pip install lxml
如果我们不安装它,则Python会使用Python默认的解析器,lxml解析器更加强大,速度更快,推荐安装。
接下来我们以爬取8684网站上的深圳地铁线路数据为例来进行爬虫实战。
首先导入库bs4、lxml、requests:
import requests import json from bs4 import BeautifulSoup import lxml.html
获取地铁线路网址
etree = lxml.html.etree def get_urls(): url = 'https://dt.8684.cn/so.php?k=pp&dtcity=sz&q=wedwed' response = requests.get(url=url) soup = BeautifulSoup(response.content, 'lxml').find(attrs={'class': 'fs-fdLink'}) routes = soup.find('tr').find('td').findAll('a')# 查找所有有关的节点 route_list = [] for i in routes: per = {} per['key'] = i.string per['value'] = 'https://dt.8684.cn' + i.get('href') route_list.append(per) return route_list
其中,
soup = BeautifulSoup(response.content, 'lxml')
为创建BeautifulSoup对象,其意义是将发送网络请求返回的响应数据创建为soup对象,数据格式为lxml。
def get_schedule(url): response = requests.get(url['value']) soup = BeautifulSoup(response.content, 'lxml').find(attrs={'class': 'ib-mn'}) table_head = soup.find(attrs={'class': 'pi-table tl-table'}) per_info = table_head.findAll('tr') route_list = [] if (url['key'].find('内圈') == -1 and url['key'].find('外圈') == -1):#地铁线路名称既无内环也无外环 route_info = {} #定义地铁内环字典 route_info_wai = {}#定义地铁外环字典 stations_nei = [] #定义地铁内环站台列表 route_info['name'] = url['key'] + '内环'#定义内环线路字典name键的值 route_info_wai['name'] = url['key'] + '外环'# 定义外环线路字典name键的值 time_nei_1 = []#定义地铁内环发车时间列表 time_nei_2 = []#定义地铁内环收班时间列表 time_wai_1 = [] #定义地铁外环发车时间列表 time_wai_2 = []# 定义地铁外环收班时间列表 for i in per_info: if (i != []): j = i.findAll('td') if (j != []): for k in j[0]: stations_nei.append(k.text)#内外环站点名 for k in j[3]: time_nei_2.append(k)#内环收车时间 for k in j[1]: time_nei_1.append(k)#内环发车时间 for k in j[4]: time_wai_2.append(k) #外环收车时间 for k in j[2]: time_wai_1.append(k)#外环发车时间 try: if (time_nei_1[0] != '--' and time_nei_1[0] != '—'): route_info['startTime'] = startTime = time_nei_1[0]#筛除地铁内环线路发车时间为空的数值 else: route_info['startTime'] = time_nei_1[1]#定义地铁内环线路发车时间 if (time_nei_2[len(time_nei_2) - 1] != '--' and time_nei_2[len(time_nei_2) - 1] != '—'): route_info['endTime'] = time_nei_2[len(time_nei_2) - 1]#筛除地铁内环线路收车时间为空的数值 else: route_info['endTime'] = time_nei_2[len(time_nei_2) - 2]# 定义地铁内环线路收车时间 if (time_wai_1[len(time_wai_1) - 1] != '--' and time_wai_1[len(time_wai_1) - 1] != '—'): route_info_wai['startTime'] = time_wai_1[len(time_wai_1) - 1]# 筛除地铁外环线路发车时间为空的数值 else: route_info_wai['startTime'] = time_wai_1[len(time_wai_1) - 2]# 定义地铁外环线路发车时间 if (time_wai_2[0] != '--' and time_wai_2[0] != '—'): route_info_wai['endTime'] = startTime = time_wai_2[0]# 筛除地铁外环线路收车时间为空的数值 else: route_info_wai['endTime'] = time_wai_2[1]# 定义地铁外环线路收车时间 except IndexError as e: route_info_wai['startTime'] = '06:00' route_info_wai['endTime'] = '23:00' route_info['startTime'] = '06:00' route_info['endTime'] = '23:00'#若无法找到数据,则捕捉索引异常错误,并对运行时间赋默认值 route_info['stations'] = stations_nei #内环线路字典stations值赋为内环站点名 route_info_wai['stations'] = list(reversed(stations_nei))#反转列表值并强制转换数据类型为列表,作为外环站点名 route_list.append(route_info) route_list.append(route_info_wai)#将内外环线路字典插入列表 else: #地铁线路名称包含“内环”或“外环” route_info = {} stations = [] route_info['name'] = url['key']# 定义线路字典name键的值 time_1 = [] # 定义地铁发车时间列表 time_2 = []#定义地铁收车时间列表 for i in per_info: if (i != []): j = i.findAll('td') if (j != []):# 筛除表头相关空数据 for k in j[0]: stations.append(k.text)#地铁线路站点名 for k in j[1]: time_1.append(k)#地铁线路发车时间 for k in j[2]: time_2.append(k)#地铁线路收车时间 if (time_1[0] != '--' and time_1[0] != '—'): route_info['startTime'] = startTime = time_1[0]# 筛除地铁线路发车时间为空的数值 else: route_info['startTime'] = time_1[1]#定义地铁线路发车时间 if (time_2[len(time_2) - 1] != '--' and time_2[len(time_2) - 1] != '—'): route_info['endTime'] = time_2[len(time_2) - 1]#筛除地铁线路收车时间为空的数值 else: route_info['endTime'] = time_2[len(time_2) - 2]#定义地铁线路收车时间 route_info['stations'] = stations# 线路字典stations值赋为站点名 route_list.append(route_info)#将线路字典插入列表 return route_list
其中,if语句(Part2的大部分代码)都是用于对非常规线路数据进行特殊处理,这也印证了“80%的代码处理20%的情况”,常规线路数据只需前六行代码即可爬取,最终返回线路列表rout_list。
for i in get_urls():#遍历城市地铁线路网址 for j in get_schedule(i): json_str = json.dumps(j, ensure_ascii=False) #转换数据格式为json格式,忽略格式转换错误进行强制转换 print(json_str)
关于“Python如何爬取地铁线路图”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。