還有一年多就要畢業了,不許備考研的我要着手準備找實習及工做了,因此一直沒有更新。html
由於Python是自學不久,發現好久不用的話之前學過的不少方法就忘了,今天打算使用簡單的BeautifulSoup和一點正則表達式的方法來爬一下top100電影,固然,咱們並不只是使用爬蟲爬取數據,這樣的話,數據中存在不少的對人有用的信息則被忽略了。因此,爬取數據只是開頭,對這些數據根據意願進行分析,或許能有額外的收穫。正則表達式
注:本人仍是Python菜鳥,如有錯誤歡迎指正app
轉載請標明出處async
由上圖可知電影信息在 li 節點內,並且發現第一頁與後面網頁地址不一樣,須要進行判斷。svn
第一頁地址爲:http://www.mtime.com/top/movie/top100/函數
第二頁地址爲:http://www.mtime.com/top/movie/top100/index-2.html字體
第三頁及後面地址均與第二頁類似,僅網址的數字相應增長,因此更改數字便可爬取網站
1 import requests 2 from bs4 import BeautifulSoup 3 import re 4 import csv 5 6 #定義爬取函數 7 def get_infos(htmls, csvname): 8 #信息頭 9 headers = { 10 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36' 11 } 12 #flag在寫入文件時判斷是否爲首行 13 flag = True 14 #判斷第一頁網址,第二頁及其後的網址 15 for i in range(10): 16 if i == 0: 17 html = htmls 18 else: 19 html = htmls + 'index-{}.html'.format(str(i+1)) 20 res = requests.get(html, headers=headers) 21 soup = BeautifulSoup(res.text, 'lxml') 22 alls = soup.select('#asyncRatingRegion > li') #選取網頁的li節點的內容 23 #對節點內容進行循環遍歷 24 for one in alls: 25 paiming = one.div.em.string #排名 26 names = str(one.select('div.mov_pic > a')) #電影名稱並將列表字符串化 27 name = re.findall('.*?title="(.*?)">.*?', names, re.S)[0] #使用正則表達式提取內容 28 content = str(one.select('div.mov_con > p.mt3')) #評論 29 realcontent = re.findall('.*?mt3">(.*?)</p>', content, re.S)[0] #同上 30 p1 = one.find(name='span', attrs={'class': 'total'}, text=re.compile('\d')) #評分在兩個節點, 31 p2 = one.find(name='span', attrs={'class': 'total2'}, text=re.compile('.\d')) 32 #判斷評分是否爲空 33 if p1 and p2 != None: 34 p1 = p1.string 35 p2 = p2.string 36 else: 37 p1 = 'no' 38 p2 = ' point' 39 point = p1 + p2 + '分' 40 numbers = one.find(text=re.compile('評分')) #評分數量 41 # 保存爲csv 42 csvnames = 'C:\\Users\lenovo\Desktop\\' + csvname + '.csv' 43 with open(csvnames, 'a+', encoding='utf-8') as f: 44 writer = csv.writer(f) 45 if flag: 46 writer.writerow(('paiming', 'name', 'realcontent', 'point', 'numbers')) 47 writer.writerow((paiming, name, realcontent, point, numbers)) 48 flag = False 49 50 #調用函數 51 Japan_html = 'http://www.mtime.com/top/movie/top100_japan/' 52 csvname1 = 'Japan_top' 53 get_infos(Japan_html, csvname1) 54 55 Korea_html = 'http://www.mtime.com/top/movie/top100_south_korea/' 56 csvname2 = 'Korea_top' 57 get_infos(Korea_html, csvname2)
這裏要注意的是要有些電影沒有評分,爲了預防出現這種狀況,因此要進行判斷spa
注:上述沒有添加華語電影top100及全部電影top100的代碼,可自行添加。code
爬取結果部份內容以下:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
步驟二和三:導入數據並使用matplotlib分析,保存分析圖片
1 import csv 2 from matplotlib import pyplot as plt 3 #中文亂碼處理 4 plt.rcParams['font.sans-serif'] =['Microsoft YaHei'] 5 plt.rcParams['axes.unicode_minus'] = False 6 7 def read_csv(csvname): 8 csvfile_name = 'C:\\Users\lenovo\Desktop\\' + csvname + '.csv' 9 #打開文件並存入列表 10 with open(csvfile_name,encoding='utf-8') as f: 11 reader = csv.reader(f) 12 header_row = next(reader) 13 name = [] 14 for row in reader: 15 name.append(row) 16 #取列表中非空元素 17 real = [] 18 for i in name: 19 if len(i) != 0: 20 real.append(i) 21 #去除中文並將數據轉換爲整形 22 t = 0 23 ss = [] 24 for j in real: 25 ss.append(int(real[t][4][:-5])) 26 t += 1 27 return ss 28 29 #繪製對比圖形 30 All_plt = read_csv('bs1') #調用函數 31 China_plt = read_csv('China_top') 32 Japan_plt = read_csv('Japan_top') 33 Korea_plt = read_csv('Korea_top') 34 shu = list(range(1,101)) 35 fig = plt.figure(dpi=128, figsize=(10, 6)) #設置圖形界面 36 plt.subplot(2,1,1) 37 plt.bar(shu ,All_plt, align='center', color='green', label='World', alpha=0.6) #繪製條圖形,align指定橫座標在中心,顏色,alpha指定透明度 38 plt.bar(shu ,China_plt, color='indigo', label='China', alpha=0.4) #繪製圖形,顏色, label屬性用於後面使用legend方法時顯示圖例標籤 39 plt.bar(shu ,Japan_plt, color='blue', label='Japan',alpha=0.5) #繪製圖形,顏色, 40 plt.bar(shu ,Korea_plt, color='yellow', label='Korea',alpha=0.5) #繪製圖形,顏色, 41 plt.ylabel('評論數', fontsize=10) #縱座標題目,字體大小 42 plt.title('不一樣地區的電影top100對比', fontsize=10) #圖形標題 43 plt.legend(loc='best') 44 45 plt.subplot(2,1,2) 46 plt.plot(shu , All_plt, linewidth=1, c='green', label='World') #繪製圖形,指定線寬,顏色,label屬性用於後面使用legend方法時顯示圖例標籤 47 plt.plot(shu ,China_plt, linewidth=1, c='indigo', label='China', ls='-.') #繪製圖形,指定線寬,顏色, 48 plt.plot(shu ,Japan_plt, linewidth=1, c='green', label='Japan', ls='--') #繪製圖形,指定線寬,顏色, 49 plt.plot(shu ,Korea_plt, linewidth=1, c='red', label='Korea', ls=':') #繪製圖形,指定線寬,顏色, 50 plt.ylabel('comments', fontsize=10) #縱座標題目,字體大小 51 plt.title('The different top 100 movies\'comments comparison', fontsize=10) #圖形標題 52 plt.legend(loc='best') 53 ''' 54 plt.legend()——loc參數選擇 55 'best' : 0, #自動選擇最好位置 56 'upper right' : 1, 57 'upper left' : 2, 58 'lower left' : 3, 59 'lower right' : 4, 60 'right' : 5, 61 'center left' : 6, 62 'center right' : 7, 63 'lower center' : 8, 64 'upper center' : 9, 65 'center' : 10, 66 ''' 67 plt.savefig('C:\\Users\lenovo\Desktop\\bs1.png') #保存圖片 68 plt.show() #顯示圖形
這裏須要注意的是讀取保存的csv文件並將數據傳入列表時,每個電影數據又是一個列表(先稱爲有效列表),每一個有效列表先後都有一個空列表,因此須要將空列表刪除,才能進行下一步
評分數據爲string類型且有中文,因此進行遍歷將中文去除並轉換爲int。
最後保存的對比分析圖片:
本次使用的爬取方法、爬取內容、分析內容都很容易,但我在完成過程當中,發現本身仍是會出現各類各樣的問題,說明還有不少須要改善進步的地方。
同時歡迎你們指正。