一、选题的背景(10分)
本次爬取的内容是豆瓣网站平均评分第一名到第二百五十名的电影名称,电影链接,电影封面图片链接,电影的概况和电影的相关信息。现在电影是人们一种很普遍的娱乐方式,能给社会带来巨大的经济与文化效应,利于增强民族自信心等等,通过这些数据分析,可以看出人们对那些电影感兴趣,从而增加对该电影的投入。
二、设计方案(20分)
1.项目主题:
《python爬虫之豆瓣Top250》
2.实施方案:
先对所需的内容进行爬取,然后把内容存入excel中,再对excel中的内容进行清洗,分析等等
3.技术难点跟实现思路:
先用requests模块对豆瓣网的数据进行爬取,然后再用BeauifulSoup模块对网页内容
解析,接着用re模块对解析过后的内容进行匹配,把所需要的内容存入excel中,最后对excel的内容进行清洗,分析。技术难点主要是要找到网页的内容所需的html对应的正则表达式,并且还要对分析爬取了一些不需要的数据,进行清洗。
三、实现步骤及代码(60分)
1.对html的源码进行分析
发现网页的源代码中有所需要的正则表达式字符,所以我们可以进行正则表达式进行字符匹配从而获取所需要的数据
2.设置多页爬取
我们发现这一页面只有第一名到第二十五名的数据,所以我们要设置,从而对多个页面进行爬取
多次测试后发现,对url中的start=中进行赋值就可以对页面的设置
3.爬取数据的爬取与保存
#在这设置了两种保存方法,此代码采用的是excel保存法。
from bs4 import BeautifulSoup #网页解析,获取数据
import re #正则表达式,进行文字匹配
import urllib.request,urllib.error #制定URL,获取网页数据
import xlwt #进行excel操作
import sqlite3 #进行SQLite数据库操作
def main():
baseurl = "https://movie.douban.com/top250?start="
#1.爬取网页
datalist = getData(baseurl)
savepath = "豆瓣电影Top250.xls"
#3.保存数据
saveData(datalist,savepath)
#saveData2DB(datalist,dbpath)
#影片详情链接
findLink = re.compile(r'<a href="(.*?)">') #创建正则表达式对象,表示规则(字符串的模式)
#影片图片
findImgSrc = re.compile(r'<img.*src="(.*?)"',re.S) #re.S 让换行符包含在字符中
#影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')
#影片评分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#找到评价人数
findJudge = re.compile(r'<span>(\d*)人评价</span>')
#找到概况
findInq = re.compile(r'<span class="inq">(.*)</span>')
#找到影片的相关内容
findBd = re.compile(r'<p class="">(.*?)</p>',re.S)
#爬取网页
def getData(baseurl):
datalist = []
for i in range(0,10): #调用获取页面信息的函数,10次
url = baseurl + str(i*25)
html = askURL(url) #保存获取到的网页源码
# 2.逐一解析数据
soup = BeautifulSoup(html,"html.parser")
for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
data = [] #保存一部电影的所有信息
item = str(item)
#影片详情的链接
link = re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串
data.append(link) #添加链接
imgSrc = re.findall(findImgSrc,item)[0]
data.append(imgSrc) #添加图片
titles = re.findall(findTitle,item) #片名可能只有一个中文名,没有外国名
if(len(titles) == 2):
ctitle = titles[0] #添加中文名
data.append(ctitle)
otitle = titles[1].replace("/","") #去掉无关的符号
data.append(otitle) #添加外国名
else:
data.append(titles[0])
data.append(' ') #外国名字留空
rating = re.findall(findRating,item)[0]
data.append(rating) #添加评分
judgeNum = re.findall(findJudge,item)[0]
data.append(judgeNum) #提加评价人数
inq = re.findall(findInq,item)
if len(inq) != 0:
inq = inq[0].replace("。","") #去掉句号
data.append(inq) # 添加概述
else:
data.append(" ") #留空
bd = re.findall(findBd,item)[0]
bd = re.sub('<br(\s+)?/>(\s+)?'," ",bd) #去掉<br/>
bd = re.sub('/'," ",bd) #替换/
data.append(bd.strip()) #去掉前后的空格
datalist.append(data) #把处理好的一部电影信息放入datalist
return datalist
#得到指定一个URL的网页内容
def askURL(url):
head = { #模拟浏览器头部信息,向豆瓣服务器发送消息
"User-Agent": "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 80.0.3987.122 Safari / 537.36"
}
#用户代理,表示告诉豆瓣服务器,我们是什么类型的机器、浏览器(本质上是告诉浏览器,我们可以接收什么水平的文件内容)
request = urllib.request.Request(url,headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
#print(html)
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e,"reason"):
print(e.reason)
return html
#保存数据
def saveData(datalist,savepath):
print("save....")
book = xlwt.Workbook(encoding="utf-8",style_compression=0) #创建workbook对象
sheet = book.add_sheet('豆瓣电影Top250',cell_overwrite_ok=True) #创建工作表
col = ("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息")
for i in range(0,8):
sheet.write(0,i,col[i]) #列名
for i in range(0,250):
print("第%d条" %(i+1))
data = datalist[i]
for j in range(0,8):
sheet.write(i+1,j,data[j]) #数据
book.save(savepath) #保存
def saveData2DB(datalist,dbpath):
init_db(dbpath)
conn = sqlite3.connect(dbpath)
cur = conn.cursor()
for data in datalist:
for index in range(len(data)):
if index == 4 or index == 5:
continue
data[index] = '"'+data[index]+'"'
sql = '''
insert into movie250 (
info_link,pic_link,cname,ename,score,rated,instroduction,info)
values(%s)'''%",".join(data)
print(sql)
cur.execute(sql)
conn.commit()
cur.close()
conn.close()
if __name__ == "__main__": #当程序执行时
#调用函数
main()
print("爬取完毕!")
4.数据的清洗
#删除无效行
import pandas as pd
data=pd.read_excel('C:/Users/王受杰/Desktop/豆瓣电影Top250.xls')
data.drop('图片链接',axis = 1,inplace = True)
data.drop('电影详情链接',axis = 1,inplace = True)
print(data.head(10))
#查找重复值
data.duplicated()
#计算空值数量
print(data['影片外国名'].isnull().value_counts())
print(data['概况'].isnull().value_counts())
print(data['电影详情链接'].isnull().value_counts())
print(data['影片中文名'].isnull().value_counts())
print(data['评价数'].isnull().value_counts()
5.数据的分析
#计算回归系数
from sklearn.linear_model import LinearRegression
data_mark=data.iloc[0:100,4:5]
data_munber=data.iloc[0:100,5:6]
predict_model = LinearRegression()
predict_model.fit(data_mark,data_munber)
print("回归系数为:",predict_model.coef_)
#绘制回归图
import matplotlib.pyplot as plt
import seaborn as sns
data_mark=data.iloc[0:100,4:5]
data_number=data.iloc[0:100,5:6]
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
sns.regplot(data_mark,data_munber)
#绘制折线图
import matplotlib.pyplot as plt
import numpy as np
data_mark=data.iloc[0:100,3:4] #把数据转换成数组
data_munber=data.iloc[0:100,2:3]
data_mark=np.array(data_mark)
data_munber=np.array(data_munber) #绘制折线图
plt.plot(data_munber,data_mark,label='评分跟评价人数的关系')
plt.show()
6.云词图的制作
#对概况进行分词
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import jieba.posseg as psg
# 打开文本
text = open('C:/Users/coss/Desktop/python爬虫/云词图.txt',encoding='utf-8').read()
# 中文分词
words=[(x.word,x.flag)for x in psg.cut(text)if len(x.word)>=2]
with open('C:/Users/coss/Desktop/python爬虫/云词分词.txt','w+') as f:
for x in words:
f.write('{0}\t{1}\n'.format(x[0],x[1]))
#从文件中读取词性的分词结果列表
db_words=[]
with open('C:/Users/coss/Desktop/python爬虫/云词分词.txt','r') as f:
for x in f.readlines():
pair= x.split()
db_words.append((pair[0],pair[1]))
#stop_attr中存放要过滤的词性列表
stop_attr=['a','ad','b','c','d','f','df','m','mq','p','r','rr','s','t','u','v','z']
#过滤清晰数据,将结果存放在words中
words=[x[0] for x in db_words if x[1] not in stop_attr]
with open('C:/Users/coss/Desktop/python爬虫/云词分词1.txt','w+') as f:
for x in words:
f.write('{0}{1}\n'.format(x[0],x[1]))
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
font = r'C:\Windows\Fonts\simfang.ttf'
# 打开文本
text = open('C:/Users/coss/Desktop/python爬虫/云词分词1.txt',encoding='gbk').read()
#设置云词图形状
mask = np.array(Image.open('C:/Users/coss/Desktop/python爬虫/哆啦a梦.jpg'))
# 生成云词图
wc = WordCloud(background_color="white",mask=mask,font_path=font).generate(text)
# 保存文件
wc.to_file('C:/Users/coss/Desktop/python爬虫/WordCloud.png')
四、总结(10分)
通过这次对数据的分析以及对云词图的制作,可以得到一些结论,比如评论数代表着知名度,虽然随着评分的上升,评论数也相对上升,不过其中很多评分没有很高的,评论数却可以远远超过一些评分高的电影。说明这类电影其实更让大众接受,或者说更让大众喜欢。(因为电影是取自前250名,不存在烂片)制作出的云词图,对云词图进行分析,这些电影跟爱情、人生、生活、战争、科幻、家庭等等有关,获取的信息相对是比较多的,基本到达预期的目标。不足,没有把评论数对电影进行排名,以及国内电影与国外电影数量的比较等等。
标签:Top250,电影,爬虫,爬取,re,print,import,data,append From: https://www.cnblogs.com/qq13379913826/p/17204610.html