一、主题式网络爬虫设计方案
1.主题式网络爬虫名称:
爬取豆瓣电影排名
2.主题式网络爬虫爬取的内容与数据特征分析:主要爬取 豆瓣电影评分
2.主题式网络爬虫爬取的内容与数据特征分析:主要爬取 豆瓣电影评分
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)
实现思路为先对网页源代码分析,用BeautifulSoup对数据进行清洗,最后通过进行数据可视化。技术难点主要包括对数据的清洗以及可视化。
二、主题页面的结构特征分析
1.主题页面的结构与特征分析
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的兴趣。