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