1.大體框架列出+爬取網頁:
#數據可視化 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函數主要用於爬取以及解析數據
headers可以在網頁之中查找
易錯點:當使用requests.get獲取到網頁之后,一般可能使用text方法進行數據獲取,但是嘗試之后數據產生了亂碼,因為requests.get方法獲取再用text解碼時候默認ISO-8859-1解碼,
因此使用content方法並指定decode('utf-8')進行解碼
數據解析我使用的是bs4庫,也可以用lxml庫,但是感覺沒有bs4方便,解析方式使用html5lib,對於html數據解析更具有容錯性和開放性
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'
查看網頁源代碼可知
通過'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()