前言

作为本人的第一篇博客,不知道怎么写才好。同时作为一个编程的菜鸟,第一次分享自己的练习之作,希望能够通过写博客这种方式慢慢的提高自己的表述能力。
本人最近学习python,学习了基本的语法,就想着做点东西练练手,反正大家说起python第一反应都是爬虫,那我就做一个爬虫吧。
本人经常由于上豆瓣看各类电影的评分,从中选出自己想要看的电影,但是豆瓣提供的几种筛选方式都不能满足,所以打算做一个爬虫爬取豆瓣的电影,顺便在根据这个数据做一个电影筛选程序,提供一个GUI界面。

第一个类Spider

首先编写了一个类Spider,它的主要功能是将上面的url连接的网页抓取下来,然后分析和提取html其中的电影名字和url,并保存如文本文件中。代码如下:
#coding=utf-8
"""
Created on 2015年12月31日
python的版本是3.4
@author: ypk
本爬虫主要是通过豆瓣的年份标签获取都有那些电影及url并存储,然后在获取这些电影的具体网页并分析,最后提供GUI界面进行查找相关电影。本爬虫用到了BeautifulSoup这个包,必须先引入这个包。
这个类主要是先调用startSpiderHtml,从豆瓣http://www.douban.com/tag/2015/movie?start=0类似网页下载下来,
接下来调用startSpiderMovie,分析之前下载html文件,将其中的电影名字及url提取出来并保存到文本中。
"""
from bs4 import BeautifulSoup
import urllib.request;
import urllib.error;
import string;
import socket
import time;
from email._header_value_parser import Header
import os
class Spider:def getHtml(self,url):#从url网站上获取htmltry:page=urllib.request.urlopen(url,timeout=10)html=page.read()except urllib.error.HTTPError:return Falseexcept socket.timeout:html=Spider().getHtml(url)return htmldef saveHtml(self,html,filename):#将html保存到filenamefb=open(filename,"wb")fb.write(html)def saveMovieUrl(self,html):#将html页面中的电影及url提取并保存起来soup=BeautifulSoup(html,"html.parser")for str in soup.find_all('dl')  :if str==None:return Flasestr=str.ddprint(str.a['href'])#电影名字file=open("./1.txt",'a',encoding="UTF-8")file.write(str.a['href'])file.write('\n')print(str.a.string)#电影urlfile.write(str.a.string,)file.write('\n')return Truedef startSpiderHtml(self,year,start,end_year,end_start):#爬取网页,从year年start页开始,到end_year年end_start结束"""由于是从豆瓣标签年份标签爬取的数据,url格式是http://www.douban.com/tag/year/movie?start=start里面的year和start就是我们需要设置的。这个函数将存放电影目录的网页抓取下来。"""year=yearstart=startproxy_support = urllib.request.ProxyHandler({'sock5': 'localhost:1080'})opener = urllib.request.build_opener(proxy_support)urllib.request.install_opener(opener)while (year>end_year or start<end_start):url="http://www.douban.com/tag/"+str(year)+"/movie?start="+str(start)html=Spider.getHtml(Spider(),url)soup=BeautifulSoup(html,"html.parser")if soup.dl==None:print(str(year)+"已经结束了~")year-=1start=0time.sleep(150)continueelse :Spider.saveHtml(Spider(),html,"./"+str(year)+"_"+str(start)+".html")print(str(year)+"_"+str(start)+".html已经下载")start+=15if start%1200==0:time.sleep(120)def startSpiderMovie(self,year,start,*end):#开始爬取网页中的数据,year是开始年份,start是开始页数"""将startSpiderHtml中获取的html网页解析,从中取出电影名字和具体的url信息,存入文本中。"""year=2015start=0while year>1980:filename="./豆瓣电影列表/"+str(year)+"_"+str(start)+".html"if(os.path.exists(filename)):Spider.saveMovieUrl(Spider(),open(filename,'r',encoding="UTF-8").read())start+=15else:print("~")year-=1start=0
#Spider().startSpiderMovie(2015, 0)
#Spider().saveHtml(Spider().getHtml("http://movie.douban.com/subject/25835474/?from=showing"),"./test.html")
#Spider().startSpiderHtml(1981,90,1980,1)      

这个时候我们就得到了这个文本:

这个这个文本文件中存储的是电影名字及url,这个URL类似这个http://movie.douban.com/subject/26366465/?from=tag_all,其中存放着电影的具体信息。

第二个类DetailSpider

接下来编写第二个类DetailSpider,这个类的功能第一是从之前的文本中获得电影名字及url,并将url指向的网页抓取下来;第二是分析抓取下来的这些网页,从中获得具体的电影信息,存储到文本中。代码如下:

#coding=utf-8
from Spider import Spider
from bs4 import BeautifulSoup
import urllib.request
import re
from _codecs import encode
import time
import threading
class DetailSpider:'''Created on 2015年12月31日python的版本是3.4@author: ypk首先调用getMovieHtml,将Spider中抓取的电影名字及url提取出来,并将url指向的网页抓取下来,接下来调用getMovieDetail将分析和提取使用getMovieHtml抓取的html页面,这个提取的信息就是影片的具体信息,保存到文本文件中'''def getMovieHtml(self,filename,name,j,end):#从filename中获取影片存放影片具体信息的网页url,抓取url指向的网页,name是开始url,抓取下来保存文件的名字,end是结束urlfile=open(filename,'r',encoding="UTF-8")i=0j=jflag=Falsefor url in file:if i%4==0:m=re.search(r'h.*', url)if m.group()==name:flag=Trueif flag:html=Spider().getHtml(m.group())if html:Spider().saveHtml(html, "./豆瓣电影详细信息/"+str(j)+".html")print(str(m)+" :"+str(j)+".html已存储~")j+=1if m.group()==end:returnelse:print(url.strip())i+=1if j%90==0 :time.sleep(120)#为了防止请求过于频繁,抓取一定页数就暂停一下def getMovieDetail(self,filename):#分析网页,获取网页中的数据,存入文本中file=open(filename,'r',encoding="UTF-8")html=file.read()soup=BeautifulSoup(html,"html.parser")if not soup.find("div",id='content'):returnsoup=soup.find("div",id='content')if not soup.find('span',property="v:itemreviewed"):returnprint(soup.find('span',property="v:itemreviewed").string)dict={'name':soup.find('span',property="v:itemreviewed").string}dict['name']=soup.find('span',property="v:itemreviewed").string#电影名称if  soup.find('span',class_="year"):print(soup.find('span',class_="year").string.strip('(').strip(')'))dict['year']=soup.find('span',class_="year").string.strip('(').strip(')')#大致时间info=soup.find(id='info')s="{"#print(info.getText().replace(": ",":"))for line in info.getText().replace(": ",":").replace(":\n",":").split("\n"):line=line.replace("'","")if line !='':#print(line.split(":",1))s+="'"+line.split(":",1)[0]+"'"+":"+"'"+line.split(":",1)[1]+"',"s=s[:-1]+"}"dict.update(eval(s))#print(dict)score=soup.find(id="interest_sectl")#print(score.getText().replace(" ","").replace("\n"," ").replace("  "," ").split())s="{"count=0for temp in score.getText().replace(" ","").replace("\n"," ").replace("  "," ").split():if count==2:s=str(s+"'"+"评价人数"+"':")s=str(s+"'"+temp+"',")count+=2continueif re.match("好于", temp):breakif count%2==0:s=str(s+"'"+temp+"':")else:s=str(s+"'"+temp+"',")count+=1s=s+"}"#dict1=dict.copy()dict.update(eval(s))print(dict)file=open("./movieDetail.txt","a",encoding="UTF-8")file.write(str(dict))file.write("\n")file.close()
#使用下面的循环,分析你抓取的下来的html页面
"""
start=0
while start<17093:print("start="+str(start))filename="./豆瓣电影详细信息/"+str(start)+".html"DetailSpider().getMovieDetail(filename)start+=1
"""
#使用下面的线程,从豆瓣上抓取html页面
#threading.Thread(target=DetailSpider().getMovieHtml,args=("./DouBanMovie.txt","http://movie.douban.com/subject/3526311/?from=tag_all",14573,"http://movie.douban.com/subject/5050645/?from=tag_all")).start()
#threading.Thread(target=DetailSpider().getMovieHtml,args=("./DouBanMovie.txt","http://movie.douban.com/subject/2282473/?from=tag_all",8392,"http://movie.douban.com/subject/1303280/?from=tag_all")).start()
#threading.Thread(target=DetailSpider().getMovieHtml,args=("./DouBanMovie.txt","http://movie.douban.com/subject/2346837/?from=tag_all",13088,"http://movie.douban.com/subject/5050645/?from=tag_all")).start()
#DetailSpider().getMovieHtml("./DouBanMovie.txt","http://movie.douban.com/subject/2252775/?from=tag_all",3254)

这样我们就获得了我们想要的电影信息,如图所示:

可以说,到这里为止,豆瓣电影爬虫的工具基本都完成了,我们已经将我们想要的豆瓣电影数据获取下来了。接下来,就要编写一个类,能够对这个文本中的数据进行相应的查找。

第三个类Seek

第三个类Seek,能够通过(‘导演’,’编剧’,’演员’,’类型’,’时间’,’名字’,’得分’,’人数’,’国家’)关键字进行查找相应的影片。代码如下:

#coding=utf-8
'''
Created on 2015年12月31日
python的版本是3.4
这个类通过调用movieSearch函数,获取具体电影信息,比如获取张艺谋的电影。
@author: ypk
'''
import re
class Seek:def movieByDirector(self,dict,director):#搜索dict数据中导演是否是directortry:if re.search(director, dict["导演"]):return Trueelse:return Falseexcept:return Falsedef movieByAuthor(self,dict,author):try:if re.search(author, dict["编剧"]):return Trueelse:return Falseexcept:return Falsedef movieByActor(self,dict,actor):try:if re.search(actor, dict["主演"]):return Trueelse:return Falseexcept:return Falsedef movieByType(self,dict,type):try:if re.search(type, dict["类型"]):return Trueelse:return Falseexcept:return Falsedef movieByYear(self,dict,year):try:for s in dict['year'].split('/'):if s.strip()==str(year):return Trueelse:return Falseexcept:return Falsedef movieByName(self,dict,name):try:if re.search(name, dict["name"]):return Trueelse:return Falseexcept:return Falsedef movieByScore(self,dict,score):try:for s in dict['豆瓣评分'].split('/'):if float(s.strip())>=float(score):return Trueelse:return Falseexcept:return False    def movieByNum(self,dict,num):try:for s in dict['评价人数'].split('/'):if int(re.match('\d*', s.strip()).group())>=int(num):return Trueelse:return Falseexcept:return False            def movieByCountry(self,dict,country):try:if re.search(country, dict["制片国家/地区"]):return Trueelse:return Falseexcept:return Falsedef movieSearch(self,filename,director,author,actor,type,year,name,score,num,country):#调用顺序如下:导演,编剧,演员,类型,时间,名字,得分,评价人数,国家list=[]flag=Falseif director!='*':print("start")for line in open(filename,'r',encoding="UTF-8"):if self.movieByDirector(eval(line),director):list.append(line)#print(line)flag=Trueif author!='*':if flag:temp=list.copy()list.clear()for line in temp:if self.movieByAuthor(eval(line), author):list.append(line)else:for line in open(filename,'r',encoding="UTF-8"):if self.movieByAuthor(eval(line), author):list.append(line)#print(line)flag=Trueif actor!='*':if flag:temp=list.copy()list.clear()for line in temp:if self.movieByActor(eval(line), actor):list.append(line)else:for line in open(filename,'r',encoding="UTF-8"):if self.movieByActor(eval(line), actor):list.append(line)#print(line)flag=Trueif type!='*':if flag:temp=list.copy()list.clear()for line in temp:if self.movieByType(eval(line), type):list.append(line)  else:for line in open(filename,'r',encoding="UTF-8"):if self.movieByType(eval(line), type):list.append(line)#print(line)flag=Trueif year!='*':if flag:temp=list.copy()list.clear()for line in temp:if self.movieByYear(eval(line), year):list.append(line)else:for line in open(filename,'r',encoding="UTF-8"):if self.movieByYear(eval(line), year):list.append(line)#print(line)flag=True             if name!='*':if flag:temp=list.copy()list.clear()for line in temp:if self.movieByName(eval(line), name):list.append(line) else:for line in open(filename,'r',encoding="UTF-8"):if self.movieByName(eval(line), name):list.append(line)#print(line)flag=True            if score!='*':if flag:temp=list.copy()list.clear()for line in temp:if self.movieByScore(eval(line), score):list.append(line)   else:for line in open(filename,'r',encoding="UTF-8"):if self.movieByScore(eval(line), score):list.append(line)#print(line)flag=Trueif num!='*':if flag:temp=list.copy()list.clear()for line in temp:if self.movieByNum(eval(line), num):list.append(line)  else:for line in open(filename,'r',encoding="UTF-8"):if self.movieByNum(eval(line), num):list.append(line)#print(line)flag=True        if country!='*':if flag:temp=list.copy()list.clear()for line in temp:if self.movieByCountry(eval(line), country):list.append(line)else:for line in open(filename,'r',encoding="UTF-8"):if self.movieByCountry(eval(line), country):list.append(line)#print(line)flag=Truereturn list
#下面循环是展示如何使用上面的类的功能
for s in Seek.movieSearch(self=Seek(),filename="./movieDetail.txt", director="张艺谋", author="*", actor="*", type="*", year="*", name="*", score="*", num="*", country="*"):print(s)
#dict=eval("{'上映日期': '2011-12-15(中国大陆) / 2011-12-23(美国)', '又名': 'The Flowers Of War', 'IMDb链接': 'tt1410063', '主演': '克里斯蒂安·贝尔 / 倪妮 / 张歆怡 / 黄天元 / 韩熙庭 / 张逗逗 / 佟大为 / 曹可凡 / 渡部笃郎 / 黄海波 / 窦骁 / 聂远 / 高虎 / 秦昊 / 李玥敏 / 白雪 / 袁杨纯子 / 孙佳 / 朱良奇 / 小林成男 / 山中崇 / 保罗·施耐德', '4星': '44.7%', '3星': '20.6%', 'year': '2011', '类型': '剧情 / 历史 / 战争', '评价人数': '269660人评价', '豆瓣评分': '8.0', 'name': '金陵十三钗', '片长': '145分钟', '制片国家/地区': '中国大陆 / 香港', '官方小站': '金陵十三钗 ', '语言': '汉语普通话 / 英语 / 日语 / 南京话 / 上海话', '导演': '张艺谋', '5星': '30.4%', '2星': '3.0%', '编剧': '刘恒 / 严歌苓', '1星': '1.4%'}")
#print(dict)
#print(dict['导演']=='张艺谋')#print(Seek.movieByDirector(Seek(),dict, "张艺谋"))                                                

最后一个模块

最后,我使用Tkinter这个GUI库编写了一个简单的界面,效果如下图:

具体的代码如下:

#coding=utf-8
'''
Created on 2015年12月31日
python的版本是3.4
设置GUI界面,提供图形化界面
@author: ypk
'''
import tkinter as tk
import tkinter.ttk as ttk
from Seek import Seek
import time
t=[]
s=('导演','编剧','演员','类型','时间','名字','得分','人数','国家')
def search():for row in tree.get_children():tree.delete(row)print("shanchu")i=0dict={}for temp in s:if t[i].get().strip()!="":dict[temp]=t[i].get().strip()else:dict[temp]="*"i+=1i=1for temp in Seek.movieSearch(self=Seek(),filename="./movieDetail.txt", director=dict["导演"], author=dict["编剧"], actor=dict["演员"], type=dict["类型"], year=dict["时间"], name=dict["名字"], score=dict["得分"], num=dict["人数"], country=dict["国家"]):treeprint(temp)if temp!=None:temp=eval(temp)tree.insert("",'end',values=(temp.get('导演'),temp.get('编剧'),temp.get('主演'),temp.get('类型'),temp.get('year'),temp.get('name'),temp.get('豆瓣评分'),temp.get('评价人数'),temp.get('制片国家/地区')))print("hi there,everyone")
top = tk.Tk()
top.title("豆瓣电影筛选器")
f=tk.Frame(top,height=100,width=100)
i=0
for temp in s:f1=tk.Frame(f)l=tk.Label(f1,text=temp,fg='green')l.pack(side='left')t.append(tk.Entry(f1,width=20,highlightcolor='red'))t[i].pack(side='right',ipady=3)i+=1f1.pack()
b=tk.Button(f,text="查找",command=search)
b.pack(side='top')
f.pack(side='left')f2=tk.Frame(top,height=240,width=300)tree=ttk.Treeview(f2,show="headings",columns=s,height=15)
for temp in s:tree.column(temp, width=80,anchor='center')tree.heading(temp, text=temp)
#f3.pack(side='top')
tree.pack()
f2.pack(side='right')
#f2.pack_propagate(0)
top.mainloop()

到此,这个的爬虫文件都编写完成了。那么总结一下这个爬虫的缺点:
1.由于豆瓣对于每个标签的限制,使得在这个标签下查找的页数不能够超过35页,比如说这个http://www.douban.com/tag/2014/movie?start=0链接,你选择35页之后,就没有数据了。所以我们获取的数据不全面。
解决办法:我没有去实现,但是我的想法是除了通过时间这个标签,还可以通过豆瓣其他标签例如:喜剧,爱情等等。通过不同的标签方式获取数据,相同的删除,不同的保存,这样能够最大的获取最多数据。
2.代码写的很乱,函数名起的很差,作为编程菜鸟需要的还是不断努力与提高。
3.效率问题,DetailSpider这个类中爬取网页部分比较慢,而且防止豆瓣检测爬虫采用的方法是爬取一部分数据就间隔一下。其实应该采取代理措施,最起码也应该换一下Header部分。

python豆瓣电影爬虫相关推荐

  1. Python豆瓣电影爬虫实战(超详解)-----我的机器人女友《阿丽塔》

    写在前面 爬虫基础详见我另一篇博客:https://blog.csdn.net/weixin_43329700/article/details/86768422 我的机器人女友----<阿丽塔& ...

  2. 使用Java语言开发在线电影推荐网 电影推荐系统 豆瓣电影爬虫 基于用户、物品的协同过滤推荐算法实现 SSM(Spring+SpringMVC+Mybatis)开发框架 机器学习、人工智能、大数据开发

    使用Java语言开发在线电影推荐网 电影推荐系统 豆瓣电影爬虫 基于用户.物品的协同过滤推荐算法实现 SSM(Spring+SpringMVC+Mybatis)开发框架 机器学习.人工智能.大数据开发 ...

  3. 使用Java+SSM框架+JSP开发简单在线电影推荐网 电影推荐系统 豆瓣电影爬虫 基于用户、物品的协同过滤推荐算法 大数据 机器学习 SimpleMovieRecommendOnline

    使用Java+SSM框架+JSP开发简单在线电影推荐网 电影推荐系统 豆瓣电影爬虫 基于用户.物品的协同过滤推荐算法 大数据 机器学习 SimpleMovieRecommendOnline 一.项目简 ...

  4. Python豆瓣电影评论的爬取及词云显示

    Python豆瓣电影评论的爬取及词云显示 课程设计论文链接 前言 开发工具.核心库 系统相关技术介绍 系统分析与设计 系统功能模块组成 实现功能和目标 爬取模块设计 爬取过程中下一页的处理 窗口界面设 ...

  5. 基于python的电影爬虫可视化系统设计与实现

    大数据时代的到来,随着人们线上互动以及网络交易,用户的信息数据完全充斥着网络,个体对产品及服务的偏好可以从这些数据中完全体现出来,为商家以及平台提供了更好的发展方向.但是要人为获取数据库中的大量数据信 ...

  6. Golang语言快速上手到综合实战(Go语言、Beego框架、高并发聊天室、豆瓣电影爬虫) 下载

    下载Golang语言快速上手到综合实战(Go语言.Beego框架.高并发聊天室.豆瓣电影爬虫) 下载地址:请加QQ:397245854 Go是Google开发的一种编译型,可并行化,并具有垃圾回收功能 ...

  7. 老板,今年有哪些大众好电影?(nodejs豆瓣电影爬虫)

    老板,今年有哪些大众好电影?(nodejs豆瓣电影爬虫) 前言 目标页面分析 设计思路 效果演示 GitHub 和源码 前言 现在看电影通常都会看豆瓣评分,虽然豆瓣本身有筛选功能,但是缺乏了一个重要元 ...

  8. python豆瓣电影需研究的问题_基于Python对豆瓣电影数据爬虫的设计与实现

    本文基于 Python 实现了网络 爬虫豆瓣电影模块的数据信息, 可以根据爬虫得到的信息进行相 关的市场分析,具有一定的商业 价值. 摘 要 能够高效率得完成爬取目标数据. 2 网络爬虫的实现 本 文 ...

  9. python 豆瓣电影top250_[python爬虫]豆瓣电影Top250简单数据分析绘图

    一:简介 通过抓取豆瓣电影Top250的数据,分别进行了三个数据统计,分别是:上榜的电影上映的年份,该年份总共上榜的电影数量,数量为0的就没有统计了:各个国家地区出品的电影数量:250部电影的各个类型 ...

最新文章

  1. inet_ntoa()返回字符串的生命周期
  2. Kafka controller重设计
  3. zabbix mysql复制延迟_mysql 主从复制延迟监控
  4. 【Envi风暴】Envi插件大全:多波段拆分工具的巧妙使用
  5. java控制cmd导出dmp文件_cmd的操作命令导出导入.dmp文件
  6. loj2245 [NOI2014]魔法森林 LCT
  7. Xshell远程访问工具及epel-release包安装
  8. Bootstrap 流式布局
  9. mysql 常用命令
  10. java线程池饱和策略_干货:Java几种线程池的分析和使用。
  11. Go_io.Reader
  12. python百例练习之第三例-字典dict()
  13. java graphics类_java_关于Graphics类
  14. Google Chrome 常用插件清单
  15. 四足机器人|机器狗|仿生机器人|多足机器人|MATLAB动画仿真|Simulink动画仿真
  16. PC端自适应-rem
  17. 爱因斯坦是人类历史上最伟大的科学家吗?
  18. SQL--Transact-SQL
  19. 服务端开发基础知识点
  20. 【luogu P3426】SZA-Template(字符串)(KMP)

热门文章

  1. 酷派改变者S1(C105/C105-6/C105-8) 解锁BootLoader 并刷入recovery root
  2. 循环神经网络中梯度爆炸的原因
  3. Fluent的porous jump边界条件
  4. 修改win7电脑主题脚本
  5. torch.bmm()函数解读
  6. 计算机与科学技术专业毕业设计,计算机科学与技术专业毕业设计论文
  7. 浏览器 User-Agent 大全
  8. MacOS Monterey 12.1 (21C52) OC 0.7.6 / Cl 5142 / PE 三分区原版黑苹果镜像
  9. ie怎么修改html代码,如何修改IE默认网页源码查看器
  10. html设置背景颜色无效,设置背景颜色无效果(第二种实现方式 背景颜色设置不起作用)...