1. 程式人生 > >(python)如何利用python深入爬取自己想要的資料資訊

(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'))

大功告成!