2-6-1 應用案例:爬取豆瓣 TOP250 電影資訊並存儲(版本:py3)——學習筆記
阿新 • • 發佈:2019-02-13
爬取電影名稱、連結並寫入檔案
import urllib.request as urlrequest from bs4 import BeautifulSoup import time #休息時間 import random #為了時間隨機 top250_url="https://movie.douban.com/top250?start={}&filter=" with open('C:/Users/feng_jlin/Desktop/douban_250.txt','w') as outputfile: for i in range(10): start = i*25 url_visit = top250_url.format(start) crawl_content = urlrequest.urlopen(url_visit).read() http_content = crawl_content.decode('utf8') soup = BeautifulSoup(http_content,'html.parser') all_item_divs = soup.find_all(class_='item') for each_item_div in all_item_divs: pic_div=each_item_div.find(class_='pic') item_href=pic_div.find('a')['href'] item_name=pic_div.find('img')['alt'] outputfile.write('{} {}\n'.format(item_href,item_name)) print('{} {}\n'.format(item_href,item_name))
現在把他修改為,需要爬去電影詳情,若無則從TOP250頁面爬取相關資料
# -*- coding:utf-8 -* import urllib.request as urlrequest from bs4 import BeautifulSoup import time #休息時間 import random #為了時間隨機 import bs4 #注意點1:引入模組 #item_href 連結 #item_name 名稱 #all_attrs_divs 主演 #movie_type_join 電影型別 #score_soup_divs 電影評分 top250_url = "https://movie.douban.com/top250?start={}&filter=" #top250的連結 movie_url = "https://movie.douban.com/subject/{}/" #movie進去詳情頁面 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'} #表頭防封,360瀏覽器 with open('C:/Users/feng_jlin/Desktop/douban_250.txt','w',encoding='utf8') as outputfile: #開啟本地儲存CSV檔案 for i in range(10): #一共250個,一頁25個,共10頁,這個則是迴圈10頁 start = i*25 #設定放在連結{}中的start url_visit = top250_url.format(start) req_url_visit = urlrequest.Request(url=url_visit, headers=headers) #將防封表頭寫入連結 crawl_content = urlrequest.urlopen(req_url_visit).read() #讀取連結 http_content = crawl_content.decode('utf8') #因為有中文,把格式改為utf8 soup = BeautifulSoup(http_content,'html.parser') #用beautifulsoup解析網頁 all_item_divs = soup.find_all(class_='item') #找到所有class=item,形成all_item_divs的列表 for each_item_div in all_item_divs: #進行列表迴圈 pic_div = each_item_div.find(class_='pic') #找到pic item_href = pic_div.find('a')['href'] #找到a中的href連結 item_name=pic_div.find('img')['alt'] #找到電影名稱 https, blank , web, subject, doubanID ,other = item_href.split('/') #分割/得到豆瓣ID movie_url_visit = movie_url.format(doubanID) #movie詳情頁連結補充完整 try: req_movie_url_visit = urlrequest.Request(url=movie_url_visit, headers=headers) #將防封表頭寫入連結 movie_crawl_content = urlrequest.urlopen(req_movie_url_visit).read() #讀取連結 movie_http_content = movie_crawl_content.decode('utf8') #因為有中文,把格式改為utf8 movie_soup = BeautifulSoup(movie_http_content,'html.parser') #用beautifulsoup解析網頁 #獲取主演 all_actor_divs = movie_soup.find(class_='actor') if isinstance(all_actor_divs,bs4.element.Tag) == True: #上面actor類別為空的話下一步會出錯,所以用isinstance過濾空TAG,避免錯誤 all_attrs_divs = all_actor_divs.find(class_='attrs').get_text() #可以用split('/')分出列表,但本次不需要 else: all_attrs_divs = "空" type_soup_divs = movie_soup.find_all(property="v:genre") #獲取電影型別 movie_type = [] #重置 for i in range(0,len(type_soup_divs)): movie_type.append(type_soup_divs[i].get_text()) #獲取get_text()文字,去除tag,放到一個新的列表中 movie_type_join = '/'.join(movie_type) #join連線列表中的元素 score_soup_divs = movie_soup.find(class_="ll rating_num").get_text() #獲取電影評分 outputfile.write('{} {} {} {} {}\n'.format(item_href,item_name,movie_type_join,score_soup_divs,all_attrs_divs)) print('{} {} {} {} {}\n'.format(item_href,item_name,movie_type_join,score_soup_divs,all_attrs_divs)) time_interval = random .uniform(1,5) #隨機1-5秒停止 time.sleep(time_interval) # wait some time, trying to avoid google forbidden (of crawler) except urlrequest.HTTPError as err: other_attrs_divs = re.findall('主演: (.*?)<br/>',str(each_item_div),re.S) #正則抓取TOP250頁面的主演 other_type_join = re.findall('主演: .*?<br/>.*?/.*?/.(.*?)\n.*?</p>',str(each_item_div),re.S) #正則抓取TOP250頁面的型別 other_score_div = re.findall('<span class="rating_num" property="v:average">(.*?)</span>',str(each_item_div),re.S) #正則抓取TOP250頁面的電影評分 if not len(other_attrs_divs): #以防有些內容為空,無法爬取 other_attrs_divs.append('空') print(other_attrs_divs) if not len(other_type_join): other_type_join.append('空') print(other_type_join) if not len(other_score_div): other_score_div.append('空') print(other_score_div) outputfile.write('{} {} {} {} {}\n'.format(item_href,item_name,other_type_join[0],other_score_div[0],other_attrs_divs[0])) print('{} {} {} {} {}\n'.format(item_href,item_name,other_type_join[0],other_score_div[0],other_attrs_divs[0])) continue #防中間爬取的20頁為空,判斷若有錯不跳出,繼續 outputfile.close() print('OK')