爬取豆瓣电影排行榜


一、主题式网络爬虫设计方案
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