(python)如何利用python深入爬取自己想要的資料資訊
一、問題說明
由於老師佈置了一個任務,需要對一個網站的城市做一些統計,並提取出這個網站上的城市的經緯度資訊然後繪製在百度地圖上。如果是一些數量不多的城市那也到好辦,但是如果對於這種存在幾百上千的城市,而且這些城市的經緯度資訊在第三級網站上才能找到,這樣一來,如果人工去完成會非常枯燥而且耗時長。
這個網站是維基百科關於自行車公共站點的統計介紹
這裡可以看到城市這一列是有超連結的,通過點選這個城市的超連結,進入到第二級網站上:
比如上面是我點選第一個城市的跳轉,我們需要的資訊在右上角,但是真正的經緯度的座標其實在這個右上角的超連結裡。繼續點選:
進入到第三極網站,這裡是我們需要的資料,經度和緯度。
我們需要對近400個站點做三個點選,然後複製這些資料,最後把這經度和緯度資料儲存在json格式的資料裡面,我們才能在前端的Js中進行讀取,並使用百度地圖顯示。
二、解決辦法
對於這種重複性的勞動,當然是想到利用之前自己研究了一陣子的爬蟲進行解決。
可以參照之前的對於電影影評的提取和分析。
第一步
我們的工作,首先最初的母網站是https://en.wikipedia.org/wiki/List_of_bicycle-sharing_systems#Cities,
# -*-coding:utf-8 -*-
from urllib2 import urlopen #引入urllib2下的urlopen類,這個類可以對url進行操作,開啟一個url連結
resp=urlopen('https://en.wikipedia.org/wiki/List_of_bicycle-sharing_systems#Cities' )
html_data=resp.read().decode('utf-8')
print (html_data)
#接上面程式碼
from bs4 import BeautifulSoup as bs
soup=bs(html_data,'html.parser')#將讀取到的網頁程式碼用指定解析器html.parser進行解析
第二步
在這個網站上找到這個城市表,在此基礎上進行超連結的兩次點選進入。
首先是找到這個網站的 原始碼,找到我們要的城市表
data_tables=soup.find_all('table')#通過soup對解析後的網頁進行特定標籤的讀取,讀取所有table
print data_tables[1]#這裡找到了第一個table是我們想要的資料
這裡的程式碼輸出是:
剛好就是我們找到的原始碼。完全符合
第三步
我們要的是a標籤下的連結,才能二次進入網站
#除去第一行的表頭,第一行有效資料裡面選取第一個td裡面的a標籤下的連結
td_lists=sortable_list[1].find_all('td')
print td_lists[0]
a_lists=td_lists[0].find_all('a')
print a_lists[0]['href'],a_lists[0]['title']
第四步
#上面只是我們需要的資料的測試,下面開始寫迴圈,提取上面的所有有用的資料_city
city_data_table=data_tables[1]#選取下標為1的table
citys_url_data=[]
#除去第一行表頭,從i=1開始提取資料
for i in range(1,len(sortable_list)-1):
if i==229:
continue
if i==369:
continue
all_tr_data=sortable_list[i]
# print all_tr_data
# break
td_lists=all_tr_data.find_all('td')
a_lists=td_lists[0].find_all('a')#選取第一個td
one={}
print i,a_lists[0]['href'],a_lists[0]['title']
one['href']=a_lists[0]['href']
one['city']=a_lists[0]['title']
citys_url_data.append(one)
print citys_url_data
輸出:
第五步
第一個方法,目的在於根據城市連結,進入到第二級網站,找到a標籤,如圖所示:
from bs4 import BeautifulSoup as bs
# 方法,目的在於根據城市的連結,進入到下一級的網站,並尋找到我們要的第二級的連結a標籤
def get_url_data(url):
resp=urlopen(url)
html_data=resp.read().decode('utf-8')
# print (html_data)
soup=bs(html_data,'html.parser')#將讀取到的網頁程式碼用指定解析器html.parser進行解析
tr_datas=soup.find_all('span',id='coordinates')#通過soup對解析後的網頁進行特定標籤的讀取,讀取所有tr
if tr_datas==None:
return
# print tr_datas[0]#這裡找到了第一個table是我們想要的資料
a_find=tr_datas[0].find_all('a',class_='external text')
print a_find[0]['href']
innter_url='https:'+a_find[0]['href']
# 呼叫第二個方法,目的在於通過第二級連結在此尋找我們要的經緯度資料
point= get_innter_data(innter_url)#將資料返回為一個point
return point
第二個方法:找到經緯度
def get_innter_data(url):
resp=urlopen(url)
html_data=resp.read().decode('utf-8')
# print (html_data)
soup=bs(html_data,'html.parser')#將讀取到的網頁程式碼用指定解析器html.parser進行解析
geo=soup.find_all('span',class_='geo')#通過soup對解析後的網頁進行特定標籤的讀取,讀取所有tr
lat=geo[0].find_all('span',class_='latitude')
print lat[0].string
lng=geo[0].find_all('span',class_='longitude')
print lng[0].string
lat_=lat[0].string
lng_=lng[0].string
point=[lat_,lng_]
return point
注:
這裡有個小技巧對於處理找到網頁原始碼中,我們所需要的資訊資料所在的位置,和所在的標籤種類以及id等資訊,可以採用滑鼠右鍵的檢查,找到原始碼
第六步
已經實現三層的網站資料鏈接爬取後,將所有城市的url迴圈遍歷就好了
for i in range(350,len(citys_url_data)):
print i
if i == 71:
continue
url='https://en.wikipedia.org'+citys_url_data[i]['href']
point =get_url_data(url)
if point==None:
continue
citys_url_data[i]['lat']=point[0]
citys_url_data[i]['lng']=point[1]
然後就可以看到資料全部存在citys_url_data的json列表裡面,最後如果有需要將這個citys_url_data寫入到json檔案中。
import json
json.dump(citys_url_data, open('city_url.json', 'w'))
大功告成!