您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Python如何爬取地鐵線路圖,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
BeautifulSoup:“美味的湯,綠色的濃湯”,是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python庫(kù)。BeautifulSoup提供一些簡(jiǎn)單的、python式的函數(shù)用來(lái)處理導(dǎo)航、搜索、修改分析樹(shù)等功能。它是一個(gè)工具箱,通過(guò)解析文檔為用戶提供需要抓取的數(shù)據(jù),因?yàn)楹?jiǎn)單,所以不需要多少代碼就可以寫出一個(gè)完整的應(yīng)用程序。
BeautifulSoup自動(dòng)將輸入文檔轉(zhuǎn)換為Unicode編碼,輸出文檔轉(zhuǎn)換為utf-8編碼。你不需要考慮編碼方式,除非文檔沒(méi)有指定一個(gè)編碼方式,這時(shí),BeautifulSoup就不能自動(dòng)識(shí)別編碼方式了。然后,你僅僅需要說(shuō)明一下原始編碼方式就可以了。
可以直接使用pip安裝:
pip install BeautifulSoup
BeautifulSoup支持Python標(biāo)準(zhǔn)庫(kù)中的HTML解析器,還支持一些第三方的解析器,如,lxml,XML,html5lib等,但是需要安裝相應(yīng)的庫(kù):
pip install lxml
如果我們不安裝它,則Python會(huì)使用Python默認(rèn)的解析器,lxml解析器更加強(qiáng)大,速度更快,推薦安裝。
接下來(lái)我們以爬取8684網(wǎng)站上的深圳地鐵線路數(shù)據(jù)為例來(lái)進(jìn)行爬蟲實(shí)戰(zhàn)。
首先導(dǎo)入庫(kù)bs4、lxml、requests:
import requests import json from bs4 import BeautifulSoup import lxml.html
獲取地鐵線路網(wǎng)址
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')# 查找所有有關(guān)的節(jié)點(diǎn) 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')
為創(chuàng)建BeautifulSoup對(duì)象,其意義是將發(fā)送網(wǎng)絡(luò)請(qǐng)求返回的響應(yīng)數(shù)據(jù)創(chuàng)建為soup對(duì)象,數(shù)據(jù)格式為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('內(nèi)圈') == -1 and url['key'].find('外圈') == -1):#地鐵線路名稱既無(wú)內(nèi)環(huán)也無(wú)外環(huán) route_info = {} #定義地鐵內(nèi)環(huán)字典 route_info_wai = {}#定義地鐵外環(huán)字典 stations_nei = [] #定義地鐵內(nèi)環(huán)站臺(tái)列表 route_info['name'] = url['key'] + '內(nèi)環(huán)'#定義內(nèi)環(huán)線路字典name鍵的值 route_info_wai['name'] = url['key'] + '外環(huán)'# 定義外環(huán)線路字典name鍵的值 time_nei_1 = []#定義地鐵內(nèi)環(huán)發(fā)車時(shí)間列表 time_nei_2 = []#定義地鐵內(nèi)環(huán)收班時(shí)間列表 time_wai_1 = [] #定義地鐵外環(huán)發(fā)車時(shí)間列表 time_wai_2 = []# 定義地鐵外環(huán)收班時(shí)間列表 for i in per_info: if (i != []): j = i.findAll('td') if (j != []): for k in j[0]: stations_nei.append(k.text)#內(nèi)外環(huán)站點(diǎn)名 for k in j[3]: time_nei_2.append(k)#內(nèi)環(huán)收車時(shí)間 for k in j[1]: time_nei_1.append(k)#內(nèi)環(huán)發(fā)車時(shí)間 for k in j[4]: time_wai_2.append(k) #外環(huán)收車時(shí)間 for k in j[2]: time_wai_1.append(k)#外環(huán)發(fā)車時(shí)間 try: if (time_nei_1[0] != '--' and time_nei_1[0] != '—'): route_info['startTime'] = startTime = time_nei_1[0]#篩除地鐵內(nèi)環(huán)線路發(fā)車時(shí)間為空的數(shù)值 else: route_info['startTime'] = time_nei_1[1]#定義地鐵內(nèi)環(huán)線路發(fā)車時(shí)間 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]#篩除地鐵內(nèi)環(huán)線路收車時(shí)間為空的數(shù)值 else: route_info['endTime'] = time_nei_2[len(time_nei_2) - 2]# 定義地鐵內(nèi)環(huán)線路收車時(shí)間 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]# 篩除地鐵外環(huán)線路發(fā)車時(shí)間為空的數(shù)值 else: route_info_wai['startTime'] = time_wai_1[len(time_wai_1) - 2]# 定義地鐵外環(huán)線路發(fā)車時(shí)間 if (time_wai_2[0] != '--' and time_wai_2[0] != '—'): route_info_wai['endTime'] = startTime = time_wai_2[0]# 篩除地鐵外環(huán)線路收車時(shí)間為空的數(shù)值 else: route_info_wai['endTime'] = time_wai_2[1]# 定義地鐵外環(huán)線路收車時(shí)間 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'#若無(wú)法找到數(shù)據(jù),則捕捉索引異常錯(cuò)誤,并對(duì)運(yùn)行時(shí)間賦默認(rèn)值 route_info['stations'] = stations_nei #內(nèi)環(huán)線路字典stations值賦為內(nèi)環(huán)站點(diǎn)名 route_info_wai['stations'] = list(reversed(stations_nei))#反轉(zhuǎn)列表值并強(qiáng)制轉(zhuǎn)換數(shù)據(jù)類型為列表,作為外環(huán)站點(diǎn)名 route_list.append(route_info) route_list.append(route_info_wai)#將內(nèi)外環(huán)線路字典插入列表 else: #地鐵線路名稱包含“內(nèi)環(huán)”或“外環(huán)” route_info = {} stations = [] route_info['name'] = url['key']# 定義線路字典name鍵的值 time_1 = [] # 定義地鐵發(fā)車時(shí)間列表 time_2 = []#定義地鐵收車時(shí)間列表 for i in per_info: if (i != []): j = i.findAll('td') if (j != []):# 篩除表頭相關(guān)空數(shù)據(jù) for k in j[0]: stations.append(k.text)#地鐵線路站點(diǎn)名 for k in j[1]: time_1.append(k)#地鐵線路發(fā)車時(shí)間 for k in j[2]: time_2.append(k)#地鐵線路收車時(shí)間 if (time_1[0] != '--' and time_1[0] != '—'): route_info['startTime'] = startTime = time_1[0]# 篩除地鐵線路發(fā)車時(shí)間為空的數(shù)值 else: route_info['startTime'] = time_1[1]#定義地鐵線路發(fā)車時(shí)間 if (time_2[len(time_2) - 1] != '--' and time_2[len(time_2) - 1] != '—'): route_info['endTime'] = time_2[len(time_2) - 1]#篩除地鐵線路收車時(shí)間為空的數(shù)值 else: route_info['endTime'] = time_2[len(time_2) - 2]#定義地鐵線路收車時(shí)間 route_info['stations'] = stations# 線路字典stations值賦為站點(diǎn)名 route_list.append(route_info)#將線路字典插入列表 return route_list
其中,if語(yǔ)句(Part2的大部分代碼)都是用于對(duì)非常規(guī)線路數(shù)據(jù)進(jìn)行特殊處理,這也印證了“80%的代碼處理20%的情況”,常規(guī)線路數(shù)據(jù)只需前六行代碼即可爬取,最終返回線路列表rout_list。
for i in get_urls():#遍歷城市地鐵線路網(wǎng)址 for j in get_schedule(i): json_str = json.dumps(j, ensure_ascii=False) #轉(zhuǎn)換數(shù)據(jù)格式為json格式,忽略格式轉(zhuǎn)換錯(cuò)誤進(jìn)行強(qiáng)制轉(zhuǎn)換 print(json_str)
關(guān)于“Python如何爬取地鐵線路圖”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。