有了上次利用python爬蟲抓取糗事百科的經驗,此次本身動手寫了個爬蟲抓取豆瓣電影Top250的簡要信息。html
1.觀察urlpython
首先觀察一下網址的結構 http://movie.douban.com/top250?start=0&filter=&type= :正則表達式
能夠看到,問號?後有三個參數 start、filter、type,其中start表明頁碼,每頁展現25部電影,0表明第一頁,以此類推25表明第二頁,50表明第三頁...設計模式
filter顧名思義,是過濾已經看過的電影,filter和type在這裏不重要,能夠無論。app
2.查看網頁源代碼python爬蟲
打開上面的網址,查看源代碼,能夠看到信息的展現結構以下:ide
1 <ol class="grid_view"> 2 <li> 3 <div class="item"> 4 <div class="pic"> 5 <em class="">1</em> 6 <a href="http://movie.douban.com/subject/1292052/"> 7 <img alt="肖申克的救贖" src="http://img3.douban.com/view/movie_poster_cover/ipst/public/p480747492.jpg" class=""> 8 </a> 9 </div> 10 <div class="info"> 11 <div class="hd"> 12 <a href="http://movie.douban.com/subject/1292052/" class=""> 13 <span class="title">肖申克的救贖</span> 14 <span class="title"> / The Shawshank Redemption</span> 15 <span class="other"> / 月黑高飛(港) / 刺激1995(臺)</span> 16 </a> 17 18 19 <span class="playable">[可播放]</span> 20 </div> 21 <div class="bd"> 22 <p class=""> 23 導演: 弗蘭克·德拉邦特 Frank Darabont 主演: 蒂姆·羅賓斯 Tim Robbins /...<br> 24 1994 / 美國 / 犯罪 劇情 25 </p> 26 27 28 <div class="star"> 29 <span class="rating5-t"><em>9.6</em></span> 30 <span>646374人評價</span> 31 </div> 32 33 <p class="quote"> 34 <span class="inq">但願讓人自由。</span> 35 </p> 36 </div> 37 </div> 38 </div> 39 </li>
其中<em class="">1</em>表明排名,<span class="title">肖申克的救贖</span>表明電影名,其餘信息的含義也很容易能看出來。post
因而接下來能夠寫正則表達式:編碼
1 pattern = re.compile(u'<div.*?class="item">.*?<div.*?class="pic">.*?' 2 + u'<em.*?class="">(.*?)</em>.*?' 3 + u'<div.*?class="info">.*?<span.*?class="title">(.*?)' 4 + u'</span>.*?<span.*?class="title">(.*?)</span>.*?' 5 + u'<span.*?class="other">(.*?)</span>.*?</a>.*?' 6 + u'<div.*?class="bd">.*?<p.*?class="">.*?' 7 + u'導演: (.*?) ' 8 + u'主演: (.*?)<br>' 9 + u'(.*?) / (.*?) / ' 10 + u'(.*?)</p>' 11 + u'.*?<div.*?class="star">.*?<em>(.*?)</em>' 12 + u'.*?<span>(.*?)人評價</span>.*?<p.*?class="quote">.*?' 13 + u'<span.*?class="inq">(.*?)</span>.*?</p>', re.S)
在此處flag參數re.S表明多行匹配。url
3.使用面向對象的設計模式編碼
代碼以下:
1 # -*- coding:utf-8 -*- 2 __author__ = 'Jz' 3 import urllib2 4 import re 5 import sys 6 7 class MovieTop250: 8 def __init__(self): 9 #設置默認編碼格式爲utf-8 10 reload(sys) 11 sys.setdefaultencoding('utf-8') 12 self.start = 0 13 self.param = '&filter=&type=' 14 self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64)'} 15 self.movieList = [] 16 self.filePath = 'D:/coding_file/python_file/File/DoubanTop250.txt' 17 18 def getPage(self): 19 try: 20 URL = 'http://movie.douban.com/top250?start=' + str(self.start) 21 request = urllib2.Request(url = URL, headers = self.headers) 22 response = urllib2.urlopen(request) 23 page = response.read().decode('utf-8') 24 pageNum = (self.start + 25)/25 25 print '正在抓取第' + str(pageNum) + '頁數據...' 26 self.start += 25 27 return page 28 except urllib2.URLError, e: 29 if hasattr(e, 'reason'): 30 print '抓取失敗,具體緣由:', e.reason 31 32 def getMovie(self): 33 pattern = re.compile(u'<div.*?class="item">.*?<div.*?class="pic">.*?' 34 + u'<em.*?class="">(.*?)</em>.*?' 35 + u'<div.*?class="info">.*?<span.*?class="title">(.*?)' 36 + u'</span>.*?<span.*?class="title">(.*?)</span>.*?' 37 + u'<span.*?class="other">(.*?)</span>.*?</a>.*?' 38 + u'<div.*?class="bd">.*?<p.*?class="">.*?' 39 + u'導演: (.*?) ' 40 + u'主演: (.*?)<br>' 41 + u'(.*?) / (.*?) / ' 42 + u'(.*?)</p>' 43 + u'.*?<div.*?class="star">.*?<em>(.*?)</em>' 44 + u'.*?<span>(.*?)人評價</span>.*?<p.*?class="quote">.*?' 45 + u'<span.*?class="inq">(.*?)</span>.*?</p>', re.S) 46 while self.start <= 225: 47 page = self.getPage() 48 movies = re.findall(pattern, page) 49 for movie in movies: 50 self.movieList.append([movie[0], movie[1], movie[2].lstrip(' / '), 51 movie[3].lstrip(' / '), movie[4], 52 movie[5], movie[6].lstrip(), movie[7], movie[8].rstrip(), 53 movie[9], movie[10], movie[11]]) 54 55 def writeTxt(self): 56 fileTop250 = open(self.filePath, 'w') 57 try: 58 for movie in self.movieList: 59 fileTop250.write('電影排名:' + movie[0] + '\r\n') 60 fileTop250.write('電影名稱:' + movie[1] + '\r\n') 61 fileTop250.write('外文名稱:' + movie[2] + '\r\n') 62 fileTop250.write('電影別名:' + movie[3] + '\r\n') 63 fileTop250.write('導演姓名:' + movie[4] + '\r\n') 64 fileTop250.write('參與主演:' + movie[5] + '\r\n') 65 fileTop250.write('上映年份:' + movie[6] + '\r\n') 66 fileTop250.write('製做國家/地區:' + movie[7] + '\r\n') 67 fileTop250.write('電影類別:' + movie[8] + '\r\n') 68 fileTop250.write('電影評分:' + movie[9] + '\r\n') 69 fileTop250.write('參評人數:' + movie[10] + '\r\n') 70 fileTop250.write('簡短影評:' + movie[11] + '\r\n\r\n') 71 print '文件寫入成功...' 72 finally: 73 fileTop250.close() 74 75 def main(self): 76 print '正在從豆瓣電影Top250抓取數據...' 77 self.getMovie() 78 self.writeTxt() 79 print '抓取完畢...' 80 81 DouBanSpider = MovieTop250() 82 DouBanSpider.main()
代碼比較簡單,最後將信息寫入一個文件,沒有什麼須要解釋的地方。
4.運行截圖
5.問題說明
打開文件瀏覽時發現有個別電影沒有抓取下來或者信息中出現html代碼,後來排查發現是由於豆瓣有部分電影的信息不全,缺乏主演等致使html代碼出現差別而致使正則表達式沒有匹配到或者匹配出錯。