《爬蟲學習》(五)(爬蟲實戰之爬取天氣信息)

1.大致框架列出+爬取網頁:html

#數據可視化
from pyecharts import Bar
#用來url鏈接登錄等功能
import requests
#解析數據
from bs4 import BeautifulSoup

#用來存取爬取到的數據
data = []

def parse_data(url):
    headers = {
        'User-Agent':"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400"
    }
    rest = requests.get(url=url, headers=headers)#使用requests.get方法爬取網頁
    # 通常人可能會用rest.text,可是會顯示亂碼
    text = rest.content.decode('utf-8')#使用utf-8解碼,防止顯示亂碼,接下來沒法解析
    soup = BeautifulSoup(text, 'html5lib')#BeautifulSoup方法須要指定解析文本和解析方式


def main():
    url = "http://www.weather.com.cn/textFC/hb.shtml"
    parse_data(url)

if __name__ == '__main__':
    main()

parse_data函數主要用於爬取以及解析數據html5

headers能夠在網頁之中查找python

易錯點:當使用requests.get獲取到網頁以後,通常可能使用text方法進行數據獲取,可是嘗試以後數據產生了亂碼,由於requests.get方法獲取再用text解碼時候默認ISO-8859-1解碼,web

    所以使用content方法並指定decode('utf-8')進行解碼app

數據解析我使用的是bs4庫,也能夠用lxml庫,可是感受沒有bs4方便,解析方式使用html5lib,對於html數據解析更具備容錯性和開放性echarts

 

2.爬取網頁解析:框架

# 爬取數據
    cons = soup.find('div', attrs={'class':'conMidtab'})
    tables = cons.find_all('table')
    for table in tables:
        trs = table.find_all('tr')[2:]
        for index,tr in enumerate(trs):
            if index == 0:
                tds = tr.find_all('td')[1]
                qiwen = tr.find_all('td')[4]
            else:
                tds = tr.find_all('td')[0]
                qiwen = tr.find_all('td')[3]
            city = list(tds.stripped_strings)[0]
            wendu = list(qiwen.stripped_strings)[0]
            data.append({'城市':city, '最高氣溫':wendu})

bs4庫通常使用方法是find或者find_all方法(詳細內容見上一篇博客)函數

find方法比較使用的是能夠查找指定內容的數據,使用attrs={}來定製條件,代碼中我用了attrs={'class':'conMidtab'}或者使用class_='conMidtab'測試

查看網頁源代碼可知url

 

 

 經過'class':'conMidtab'來定位到所需信息的表

 

 

 再分析:由於有多個conMidtab,因此測試分析得知多個conMidtab對應的是今天,明天,後天......的天氣狀況

咱們分析的是今天的狀況,因此取第一個conMidtab,使用soup.find("div",class_="conMidtab")獲取第一個conMidtab的內容

 

 

 由上知:conMidtab下的多個class="conMidtab2"表明不一樣的省的天氣信息

可是在研究能夠發現,全部天氣信息都是存儲在table裏的,所以獲取全部tables便可——cons.find_all('table')

 

 

 同時對於每個table而言:第三個tr開始纔是對應的城市信息,故對於每個table獲取trs = table.find_all("tr")[2:]

 

 

易錯點:同時發現對於每一個省第一個城市,它隱藏在tr的第二個td裏,而除此以外的該省其餘城市則在tr的第一個td裏,所以使用一個if和else判斷

enumerate方法能夠產生一個index下標,所以在遍歷trs的時候能夠知道當index==0的時候是第一行

 

 

 

以後分析:城市名字:對於每一個省第一個城市,它隱藏在tr的第二個td裏,而除此以外的該省其餘城市則在tr的第一個td裏

     最高氣溫:對於每一個省第一個城市,它隱藏在tr的第五個td裏,而除此以外的該省其餘城市則在tr的第四個td裏

所以使用

       if index == 0:
                tds = tr.find_all('td')[1]
                qiwen = tr.find_all('td')[4]
            else:
                tds = tr.find_all('td')[0]
                qiwen = tr.find_all('td')[3]
最後使用stripped_strings獲取字符串而且添加到data列表裏

3.進行全部城市的數據獲取:
def main():
    urls = [
        "http://www.weather.com.cn/textFC/hb.shtml",
        "http://www.weather.com.cn/textFC/db.shtml",
        "http://www.weather.com.cn/textFC/hd.shtml",
        "http://www.weather.com.cn/textFC/hz.shtml",
        "http://www.weather.com.cn/textFC/hn.shtml",
        "http://www.weather.com.cn/textFC/xb.shtml",
        "http://www.weather.com.cn/textFC/xn.shtml",
        "http://www.weather.com.cn/textFC/gat.shtml"
    ]
    for url in urls:
        parse_data(url)  

 

 

 修改了一下main方法:獲取全國數據

 

4.數據排序找出全國氣溫最高十大城市:

# 排序找出十大溫度最高的城市
# 按照溫度排序
data.sort(key=lambda x:int(x['最高氣溫']))
#十大溫度最高的城市
data_2 = data[-10:]

其中在排序的時候注意:要轉化爲int型才能夠進行排序,不然是按照string進行排序的。

 

5.數據可視化:

citys = list(map(lambda x:x['城市'], data_2))#橫座標
wendu = list(map(lambda x:x['最高氣溫'], data_2))#縱座標
charts = Bar('中國十大最高溫度城市')
charts.add('', citys, wendu)
charts.render('天氣網.html')  

使用Bar模塊:

  Bar方法主要能夠給該圖標命名

  add方法主要是添加(圖顏色的名稱,橫座標名, 縱座標名)

  render主要是存儲在本地之中

結果展現:

 

 

完整代碼:

#數據可視化
from pyecharts import Bar
#用來url鏈接登錄等功能
import requests
#解析數據
from bs4 import BeautifulSoup

#用來存取爬取到的數據
data = []


def parse_data(url):
    headers = {
        'User-Agent':"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400"
    }
    rest = requests.get(url=url, headers=headers)#使用requests.get方法爬取網頁
    # 通常人可能會用rest.text,可是會顯示亂碼
    text = rest.content.decode('utf-8')#使用utf-8解碼,防止顯示亂碼,接下來沒法解析
    soup = BeautifulSoup(text, 'html5lib')#BeautifulSoup方法須要指定解析文本和解析方式

    # 爬取數據
    cons = soup.find('div', attrs={'class':'conMidtab'})
    tables = cons.find_all('table')
    for table in tables:
        trs = table.find_all('tr')[2:]
        for index,tr in enumerate(trs):
            if index == 0:
                tds = tr.find_all('td')[1]
                qiwen = tr.find_all('td')[4]
            else:
                tds = tr.find_all('td')[0]
                qiwen = tr.find_all('td')[3]
            city = list(tds.stripped_strings)[0]
            wendu = list(qiwen.stripped_strings)[0]
            data.append({'城市':city, '最高氣溫':wendu})

def main():
    urls = [
        "http://www.weather.com.cn/textFC/hb.shtml",
        "http://www.weather.com.cn/textFC/db.shtml",
        "http://www.weather.com.cn/textFC/hd.shtml",
        "http://www.weather.com.cn/textFC/hz.shtml",
        "http://www.weather.com.cn/textFC/hn.shtml",
        "http://www.weather.com.cn/textFC/xb.shtml",
        "http://www.weather.com.cn/textFC/xn.shtml",
        "http://www.weather.com.cn/textFC/gat.shtml"
    ]
    for url in urls:
        parse_data(url)

    # 排序找出十大溫度最高的城市
    # 按照溫度排序
    data.sort(key=lambda x:int(x['最高氣溫']))
    #十大溫度最高的城市
    data_2 = data[-10:]

    # 數據可視化
    citys = list(map(lambda x:x['城市'], data_2))#橫座標
    wendu = list(map(lambda x:x['最高氣溫'], data_2))#縱座標
    charts = Bar('中國十大最高溫度城市')
    charts.add('', citys, wendu)
    charts.render('天氣網.html')

if __name__ == '__main__':
    main()
相關文章
相關標籤/搜索