爬蟲入門經典(五) | 簡單一文教你如何爬取高德地圖

2020-10-25 10:00:01

  大家好,我是不溫卜火,是一名計算機學院巨量資料專業大三的學生,暱稱來源於成語—不溫不火,本意是希望自己性情溫和。作為一名網際網路行業的小白,博主寫部落格一方面是為了記錄自己的學習過程,另一方面是總結自己所犯的錯誤希望能夠幫助到很多和自己一樣處於起步階段的萌新。但由於水平有限,部落格中難免會有一些錯誤出現,有紕漏之處懇請各位大佬不吝賜教!暫時只在csdn這一個平臺進行更新,部落格主頁:https://buwenbuhuo.blog.csdn.net/
1

PS:由於現在越來越多的人未經本人同意直接爬取博主本人文章,博主在此特別宣告:未經本人允許,禁止轉載!!!


2


一、 分析網頁結構

以往幾篇都是介紹的傳統的靜態介面的爬取,這次博主介紹一個爬取動態網頁的超簡單的一個小demo
3
說到動態網頁,你對它瞭解多少呢?

如果對動態網頁不認識的童鞋,博主在此給出連結,可以看百度百科的詳細解析動態網頁_百度百科以及小馬伕的靜態頁面和動態頁面的區別

4
不要怪博主沒有進行講解,因為博主本人對與動態網頁的概念也不是太過了解。等到博主整理好思緒的時候,博主會專門寫一篇博文的 -。-

簡單來說,要獲取靜態網頁的網頁資料只需要給伺服器傳送該網頁url地址就行,而動態網頁的資料因為是儲存在後端的資料庫裡。所以要獲取動態網頁的網頁資料,我們需要向伺服器傳送請求檔案的url地址,而不是該網頁的url地址。

🆗,下面開始進入正題。

本篇博文就以高德地圖展開:https://www.amap.com/
5
在開啟後,我們發現有一堆div標籤,但是並沒有我們需要的資料,這個時候就可以判定其為動態網頁,這個時候,我們就需要找介面
8
6
點選網路標籤,我們可以看到網頁向伺服器傳送了很多請求,資料很多,找起來太費時間

我們點選XHR分類,可以減少很多不必要的檔案,省下很多時間。

XHR型別即通過XMLHttpRequest方法傳送的請求,它可以在後臺與伺服器交換資料,這意味著可以在不載入整個網頁的情況下,對網頁某部分的內容進行更新。也就是說,向資料庫請求然後得到響應的資料是XHR型別的

然後我們就可以在XHR型別下開始一個個找,找到了如下的資料
7
通過檢視Headers獲得URL
9
開啟之後,我們發現其為近兩天的天氣情況。
10

開啟後我們可以看到上面的情況,這是個json格式的檔案。然後,它的資料資訊是以字典的形式來儲存的,而資料是都儲存在「data」這個鍵值裡面。

🆗,找到了json資料,我們來對比下看是否是我們找的東西
11
通過對比,資料正好對應,那就說明咱們已經拿到資料了。

二、拿到相關網址

'''
查詢當前地點天氣的url:https://www.amap.com/service/cityList?version=2020101417
各城市對應code的url:https://www.amap.com/service/weather?adcode=410700

備註:這兩個url可以從Network中檢視到
'''

12
🆗,相關網址我們已經拿到了,下面就是具體的程式碼實現了。至於怎麼實現,

我們知道json資料可以使用response.json()轉字典,然後操作字典。
13

三、程式碼實現

知道了資料的位置後,我們開始來寫程式碼。

3.1 查詢所有城市名稱和編號

先抓取網頁,通過新增headers來偽裝成瀏覽器來對資料庫地址進行存取,防止被識別後攔截。

url_city = "https://www.amap.com/service/cityList?version=202092419"

headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}

city = []
response = requests.get(url=url_city, headers=headers)
content = response.json()
print(content)

14
得到我們想要的資料之後,我們通過查詢可以發現cityByLetter裡的編號和名稱是我們需要的,那麼我們就可以盤它了。
15

    if "data" in content:
        cityByLetter = content["data"]["cityByLetter"]
        for k,v in cityByLetter.items():
            city.extend(v)
    return city

15

3.2 根據編號查詢天氣

得到了編號和名稱,下面肯定就是查詢天氣呀!

先來看介面
16
通過上圖,可以確定最高溫度,最低溫度等內容。那麼就以此來進行資料爬取。

url_weather = "https://www.amap.com/service/weather?adcode={}"

response = requests.get(url=url_weather.format(adcode), headers=headers)
content = response.json()
item["weather_name"] = content["data"]["data"][0]["forecast_data"][0]["weather_name"]
item["min_temp"] = content["data"]["data"][0]["forecast_data"][0]["min_temp"]
item["max_temp"] = content["data"]["data"][0]["forecast_data"][0]["max_temp"]
print(item)

17

🆗,我們的設想已經實現了。
20

四、完整程式碼

# encoding: utf-8
'''
  @author 李華鑫
  @create 2020-10-06 19:46
  Mycsdn:https://buwenbuhuo.blog.csdn.net/
  @contact: 459804692@qq.com
  @software: Pycharm
  @file: 高德地圖_每個城市的天氣.py
  @Version:1.0

'''
import requests


url_city = "https://www.amap.com/service/cityList?version=202092419"
url_weather = "https://www.amap.com/service/weather?adcode={}"

headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}


def get_city():
    """查詢所有城市名稱和編號"""
    city = []
    response = requests.get(url=url_city, headers=headers)
    content = response.json()

    if "data" in content:
        cityByLetter = content["data"]["cityByLetter"]
        for k, v in cityByLetter.items():
            city.extend(v)
    return city


def get_weather(adcode, name):
    """根據編號查詢天氣"""
    item = {}
    item["adcode"] = str(adcode)
    item["name"] = name

    response = requests.get(url=url_weather.format(adcode), headers=headers)
    content = response.json()
    item["weather_name"] = content["data"]["data"][0]["forecast_data"][0]["weather_name"]
    item["min_temp"] = content["data"]["data"][0]["forecast_data"][0]["min_temp"]
    item["max_temp"] = content["data"]["data"][0]["forecast_data"][0]["max_temp"]

    return item


def save(item):
    """儲存"""
    print(item)
    with open("./weather.txt","a",encoding="utf-8") as file:
        file.write(",".join(item.values()))
        file.write("\n")


if __name__ == '__main__':
    city_list = get_city()
    for city in city_list:
        item = get_weather(city["adcode"],city["name"])
        save(item)

五、儲存結果

18
19

美好的日子總是短暫的,雖然還想繼續與大家暢談,但是本篇博文到此已經結束了,如果還嫌不夠過癮,不用擔心,我們下篇見!


21

  好書不厭讀百回,熟讀課思子自知。而我想要成為全場最靚的仔,就必須堅持通過學習來獲取更多知識,用知識改變命運,用部落格見證成長,用行動證明我在努力。
  如果我的部落格對你有幫助、如果你喜歡我的部落格內容,請「點贊」 「評論」「收藏」一鍵三連哦!聽說點讚的人運氣不會太差,每一天都會元氣滿滿呦!如果實在要白嫖的話,那祝你開心每一天,歡迎常來我部落格看看。
  碼字不易,大家的支援就是我堅持下去的動力。點贊後不要忘了關注我哦!

22
23