爬取豆瓣電影排行榜


一、主題式網絡爬蟲設計方案
1.主題式網絡爬蟲名稱:
       爬取豆瓣電影排名
2.主題式網絡爬蟲爬取的內容與數據特征分析:主要爬取 豆瓣電影評分      
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)
      實現思路為先對網頁源代碼分析,用BeautifulSoup對數據進行清洗,最后通過進行數據可視化。技術難點主要包括對數據的清洗以及可視化。
二、主題頁面的結構特征分析
1.主題頁面的結構與特征分析
我們需要找到作品的名稱,評分,評價,通過瀏覽頁面元素,定位並爬取所需內容

 

 三、網絡爬蟲程序設計
1.數據爬取與采集

import json  
import requests  
from requests.exceptions import RequestException  
import re  
import time  
#判斷爬取是否錯誤
def get_one_page(url):  
    try:  
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'  
        }

        response = requests.get(url, headers=headers)  
        if response.status_code == 200:  
            return response.text  
        return None  
    except RequestException:  
        return None  
    
def parse_one_page(html):  
   pattern = re.compile('<li>.*?<em class="">(.*?)</em>.*?title.*?>(.*?)</span>.*? <span class="rating_num" property="v:average">(.*?)</span>.*?<span class="inq">(.*?)</span>',re.S)  
   items = re.findall(pattern, html)  
   for item in items:  
        yield {'排名': item[0],  
            '名字': item[1],  
            '評分': item[2],
            '簡介':item[3]
        }  
def write_to_file(content):  
    with open('douban250.txt', 'a', encoding='utf-8') as f:  
        f.write(json.dumps(content, ensure_ascii=False) + '\n')  
    
def main(offset):  
    url = 'https://movie.douban.com/top250?start='+str(offset)+'&filter='  
    html = get_one_page(url)  
    for item in parse_one_page(html):  
        print(item)  
        write_to_file(item)  
        
if __name__ == '__main__':  
    for i in range(10):  
        main(offset=i * 25)  
        time.sleep(1)

  截圖顯示結果

 

 數據的采集並生成文件

import requests
from bs4 import BeautifulSoup
import pandas as pd

page_indexs = range(0, 100, 25) # 構造分頁列表
list(page_indexs)

def download_all_htmls(): # 爬取4個頁面的HTML,用於后續的分析
    htmls = []
    for idx in page_indexs:
        url = f"https://movie.douban.com/top250?start={idx}&filter=" # 替換分頁參數
        print("craw html:", url)
        r = requests.get(url,
                         headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"}) 
        # r返回一個包含服務器資源的Response對象
        if r.status_code != 200:
            raise Exception("error") # 當程序出錯時通過raise語句顯示引發異常
        htmls.append(r.text)
    return htmls
 
 # 執行爬取
htmls = download_all_htmls() # 爬取4個頁面的HTML

def parse_single_html(html): # 解析單個HTML,得到數據
    soup = BeautifulSoup(html, 'html.parser') # 解析HTML數據
    article_items = (                         # 對照HTML結構寫
        soup.find("div", class_="article")
            .find("ol", class_="grid_view")
            .find_all("div", class_="item")
    )
    datas = [] # 將數據存入列表
    for article_item in article_items:
        rank = article_item.find("div", class_="pic").find("em").get_text()
        info = article_item.find("div", class_="info")
        title = info.find("div", class_="hd").find("span", class_="title").get_text()
        stars = (
            info.find("div", class_="bd")
                .find("div", class_="star")
                .find_all("span") # 有4個span,所以用find_all
        )
        rating_star = stars[0]["class"][0] #由於class屬性有多個,所以取第0個
        rating_num = stars[1].get_text()
        comments = stars[3].get_text()
        
        datas.append({
            "rank":rank,
            "title":title,
            "rating_star":rating_star.replace("rating","").replace("-t",""),
            "rating_num":rating_num,
            "comments":comments.replace("人評價", "")
        })
    return datas

# 執行所有的HTML頁面的解析
all_datas = []
for html in htmls:
    all_datas.extend(parse_single_html(html))

df = pd.DataFrame(all_datas)
df.to_csv("豆瓣電影Top100.csv")
df = pd.DataFrame(pd.read_csv('douban.csv'))
print(df)

  

 

 

 

 

 

 

 

 

對數據進行處理

#輸出信息檢驗文件是否成功
df = pd.DataFrame(pd.read_csv('douban.csv'))
print(df)

  截圖

 

 

# 刪除無效列
df.drop('title', axis = 1, inplace=True)
df.head()

  

# 查找重復值
df.duplicated()

  

 

 

# 刪除重復值
df = df.drop_duplicates()
df.head()

  

 

 扇形圖 條形圖

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #顯示中文
plt.rcParams['axes.unicode_minus']=False 
Type = ['9分以上', '8分~9分', '7分~8分', '6分~7分']
Data = [1, 8, 8, 1]
plt.pie(Data ,labels=Type, autopct='%1.1f%%')
plt.axis('equal')
plt.title('電影所占評分的比例')
plt.show()
plt.bar(['6分~7分','7分~8分','8分~9分','9分以上'], 
        [1, 8, 8, 1], 
        label="電影評分所占比例")
plt.legend()
plt.show()

  

 

 代碼匯總

import json  
import requests  
from requests.exceptions import RequestException  
import re  
import time  
from bs4 import BeautifulSoup
import pandas as pd
#判斷爬取是否錯誤
def get_one_page(url):  
    try:  
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'  
        }

        response = requests.get(url, headers=headers)  
        if response.status_code == 200:  
            return response.text  
        return None  
    except RequestException:  
        return None  
    
def parse_one_page(html):  
   pattern = re.compile('<li>.*?<em class="">(.*?)</em>.*?title.*?>(.*?)</span>.*? <span class="rating_num" property="v:average">(.*?)</span>.*?<span class="inq">(.*?)</span>',re.S)  
   items = re.findall(pattern, html)  
   for item in items:  
        yield {'排名': item[0],  
            '名字': item[1],  
            '評分': item[2],
            '簡介':item[3]
        }  
def write_to_file(content):  
    with open('douban250.txt', 'a', encoding='utf-8') as f:  
        f.write(json.dumps(content, ensure_ascii=False) + '\n')  
    
def main(offset):  
    url = 'https://movie.douban.com/top250?start='+str(offset)+'&filter='  
    html = get_one_page(url)  
    for item in parse_one_page(html):  
        print(item)  
        write_to_file(item)  
        
if __name__ == '__main__':  
    for i in range(10):  
        main(offset=i * 25)  
        time.sleep(1)

page_indexs = range(0, 100, 25) # 構造分頁列表
list(page_indexs)

def download_all_htmls(): # 爬取4個頁面的HTML,用於后續的分析
    htmls = []
    for idx in page_indexs:
        url = f"https://movie.douban.com/top250?start={idx}&filter=" # 替換分頁參數
        print("craw html:", url)
        r = requests.get(url,
                         headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"}) 
        # r返回一個包含服務器資源的Response對象
        if r.status_code != 200:
            raise Exception("error") # 當程序出錯時通過raise語句顯示引發異常
        htmls.append(r.text)
    return htmls
 
 # 執行爬取
htmls = download_all_htmls() # 爬取4個頁面的HTML

def parse_single_html(html): # 解析單個HTML,得到數據
    soup = BeautifulSoup(html, 'html.parser') # 解析HTML數據
    article_items = (                         # 對照HTML結構寫
        soup.find("div", class_="article")
            .find("ol", class_="grid_view")
            .find_all("div", class_="item")
    )
    datas = [] # 將數據存入列表
    for article_item in article_items:
        rank = article_item.find("div", class_="pic").find("em").get_text()
        info = article_item.find("div", class_="info")
        title = info.find("div", class_="hd").find("span", class_="title").get_text()
        stars = (
            info.find("div", class_="bd")
                .find("div", class_="star")
                .find_all("span") # 有4個span,所以用find_all
        )
        rating_star = stars[0]["class"][0] #由於class屬性有多個,所以取第0個
        rating_num = stars[1].get_text()
        comments = stars[3].get_text()
        
        datas.append({
            "rank":rank,
            "title":title,
            "rating_star":rating_star.replace("rating","").replace("-t",""),
            "rating_num":rating_num,
            "comments":comments.replace("人評價", "")
        })
    return datas

# 執行所有的HTML頁面的解析
all_datas = []
for html in htmls:
    all_datas.extend(parse_single_html(html))

df = pd.DataFrame(all_datas)
df.to_csv("豆瓣電影Top100.csv")
df = pd.DataFrame(pd.read_csv('douban.csv'))
print(df)


#輸出信息檢驗文件是否成功
df = pd.DataFrame(pd.read_csv('douban.csv'))
print(df)


df.drop('title', axis = 1, inplace=True)
df.head()

df.duplicated()

df = df.drop_duplicates()
df.head()


import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #顯示中文
plt.rcParams['axes.unicode_minus']=False 
Type = ['9分以上', '8分~9分', '7分~8分', '6分~7分']
Data = [1, 8, 8, 1]
plt.pie(Data ,labels=Type, autopct='%1.1f%%')
plt.axis('equal')
plt.title('電影所占評分的比例')
plt.show()
plt.bar(['6分~7分','7分~8分','8分~9分','9分以上'], 
        [1, 8, 8, 1], 
        label="電影評分所占比例")
plt.legend()
plt.show()

  總結

1.經過對主題數據的分析與可視化,可以得到哪些結論?

可以直觀的看到熱播電影的評分情況
2.對本次程序設計任務完成的情況做一個簡單的小結

在完成本次程序設計任務的過程中,鞏固了以前學習的知識,學會了以前沒有掌握的,既是對之前課程的復習與運用,也是對我們掌握的實質的考察與補充。我也對之前的課程進行了一個復習,也找到了很多自我的短板和遺漏的知識點,也在不斷的探索中學習到更多新東西,了解到其實還有很多值得我們去學習,也提高了我對Python的興趣。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM