美文网首页Python
python爬虫-爬取豆瓣电影top250详细信息

python爬虫-爬取豆瓣电影top250详细信息

作者: DKider | 来源:发表于2019-03-10 20:26 被阅读19次
    没有全部完成,没有过程解释,只有整体框架,等我写完,下周末继续完成。

    如题,我要爬取豆瓣电影Top250的相关信息,包括但不限于——电影排名、电影名、电影导演、主演、编剧、类型、制片国家、语言、 上映时间、片长、别名、评分、评分人数、5星占比等。
    希望用到的技能:

    • 爬虫基础知识
    • BeautifulSoup的使用
    • 多进程
    • 操作数据库
    • 使用队列
    • 文件操作
    • MATLAB画图统计,实现数据可视化
    • 下载图片
    • 正则表达式
    • 使用代理池、防止封锁
    • 克服反爬机制等

    我分析过了整个网站,大致分为以下几个步骤进行:

    1. 先获取250个电影的详情页的地址,保存为txt文件,并将其保存到队列中等待处理
    2. 从队头开始爬取页面,保存为BeautifulSoup对象,同时队首出队。这里可能会遇到反爬机制
    3. 处理BeautifulSoup对象,清洗数据,获得电影相关信息,以及其电影海报页面地址,其中会用到正则表达式,这里也可能会遇到反爬机制
    4. 将清洗后的数据存入数据库
    5. 下载相关电影海报图,并附上相关信息,将其存到一个文件夹下txt+pic
    6. 利用MATLAB处理数据,输出统计图
      2、3、5尝试使用多进程加快处理速度

    目前已经完成的步骤:1、2、5
    正在进行的步骤:3
    遇到的问题:多进程在win10上遇到了神奇的bug,还没解决、在清洗数据时遇到了一点小问题,是对BeautifulSoup掌握度不够的问题、基础不扎实。

    在写的时候我就注意了爬虫的礼仪,设定了访问间隔时间,并没有遇到封锁,很幸运。可以说豆瓣简直就是爬虫新手的乐园,难度不大、但有一定挑战性。


    通过这次练习,我对自己的水平有了大致的了解,远远不够——MATLAB不会使、代理IP不熟悉、多进程不会用、相关基础知识不深刻、数据结构使用不合理、代码结构不规范等很多问题。

    在写代码时,发现了很多问题,这都将是我接下来努力的方向!!


    目标

    代码没写完,主程序没写,下周末更新!
    全部代码:

    import time
    import os
    from bs4 import BeautifulSoup
    from urllib.request import urlopen
    from urllib.request import urlretrieve
    
    #我用的自己写的队列,模块QUEUE使用不熟练
    class LNode:
        def __init__(self,arg):
            self.data=arg
            self.next=None
    class MyQueue:
        #模拟队列
        def __init__(self):
            #phead=LNode(None)
            self.data=None
            self.next=None
            self.front=self#指向队列首
            self.rear=self#指向队列尾
        #判断队列是否为空,如果为空返回True,否则返回false
        def isEmpty(self):
            return self.front==self.rear
        #返回队列的大小
        def size(self):
            p=self.front
            size=0
            while p.next!=self.rear.next:
                p=p.next
                size+=1
            return size
        #返回队列首元素
        def top(self):
            if not self.isEmpty():
                return self.front.next.data
            else:
                print("队列为空")
                return None
        #返回队列尾元素
        def bottom(self):
            if not self.isEmpty():
                return self.rear.data
            else:
                print("队列为空")
                return None
        #出队列
        def pop(self):
            if self.size()==1:
                data=self.front.next
                self.rear=self
                return data.data
    
            elif not self.isEmpty():
                data=self.front.next
                self.front.next=self.front.next.next
                print("出队列成功")
                return data.data
            else:
                print("队列已为空")
                return None
        #入队列
        def push(self,item):
            tmp=LNode(item)
            self.rear.next=tmp
            self.rear=self.rear.next
            print("入队列成功")
        #清空队列
        def destroy(self):
            self.next=None
            print("队列已清空")
        #打印队列
        def showQueue(self):
            if not self.isEmpty():
                p=self.front.next
                while p != self.rear.next:
                    print(p.data)
                    p=p.next
    #获得10页包含250个简介的页面地址 
    def get_ten_pageurl():
        array=[]
        for i in range(0,250,25):
            array.append("https://movie.douban.com/top250?start="+str(i)+"&filter=")
        return array
    
    # 得到每一个电影的详情页地址     
    def get_250movie_page_url(ten_pageurl,Directory):
        """
        输入10页地址
        将top250 的电影首页地址保存下来,同时存到队列中和本地text
        """
        if not os.path.exists(Directory):
            os.makedirs(Directory)
        url_queue=MyQueue()
        for page_url in ten_pageurl:
            try:
                html = urlopen(page_url)
                bsobj = BeautifulSoup(html, features="html.parser")
                # 得到当前页面上25个包含序号、详情页的地址的div标签,存为列表
                movie_info_items = bsobj.findAll("div", {"class": "pic"})
                for movie_info in movie_info_items:
                    try:
                        movie_id = int(movie_info.find("em").get_text())
                        movie_info_url = movie_info.find("a").attrs["href"]
                        movie_name=movie_info.find("img").attrs["alt"]
                        url_queue.push(movie_info_url)
                        with open(Directory + "/250homepage_url.txt", "a") as f:
                            f.write(str(movie_id))
                            f.write("\t")
                            f.write(movie_name)
                            f.write("\t")
                            f.write(movie_info_url)
                            f.write("\n")
                        print("获取movie_id/movie_info_url成功:", movie_id)
                    except:
                        print("获取movie_id/movie_info_url失败:", movie_info[30:34])
                        continue
                time.sleep(2)
            except:
                print("页面%s处理失败"%(page_url))
                time.sleep(1)
                continue
        return url_queue
    
    #获取详情页
    def get_movie_info(url):
        try:
            html = urlopen(url)
            bsobj = BeautifulSoup(html, features="html.parser")
            time.sleep(2)
            return bsobj
        except:
            print("页面%s处理失败"%(url[-8:]))
            time.sleep(1)
            return None
    #处理详情页
    def configure_infopage(bsobj):
        try:
            #电影排名:
            movie_id=bsobj.find("span", {"class": "top250-no"}).get_text()
            # 得到当前页面上的电影名称
            movie_name = bsobj.find("span", {"property": "v:itemreviewed"}).get_text()
            #电影简介
            movie_intro=bsobj.find("span",{"property":"v:summary"})
            #获取电影海报页面链接
            movie_photos=bsobj.find("a",{"class":"nbgnbg"}).attrs["href"]
            #电影详细信息左
            movie_info_items=bsobj.find("div",{"class":"subjectwrap clearfix"})
            #处理电影详细信息
            #导演: 弗兰克·德拉邦特
            movie_directer=movie_info_items.find("a",{"rel":"v:directedBy"}).get_text()
            #编剧: 弗兰克·德拉邦特 / 斯蒂芬·金
            movie_attrs=None
            #主演: 蒂姆·罗宾斯 / 摩根·弗里曼 / 鲍勃·冈顿 / 威廉姆·赛德勒 / 克兰西·布朗 / 吉尔·贝罗斯 / 马克·罗斯顿 / 詹姆斯·惠特摩 / 杰弗里·德曼 / 拉里·布兰登伯格 / 尼尔·吉恩托利 / 布赖恩·利比 / 大卫·普罗瓦尔 / 约瑟夫·劳格诺 / 祖德·塞克利拉 / 保罗·麦克兰尼 / 芮妮·布莱恩 / 阿方索·弗里曼 / V·J·福斯特 / 弗兰克·梅德拉诺 / 马克·迈尔斯 / 尼尔·萨默斯 / 耐德·巴拉米 / 布赖恩·戴拉特 / 唐·麦克马纳斯
            movie_actors=None
            #类型: 剧情 / 犯罪
            movie_genre=None
            #制片国家/地区: 美国
            movie_saition=movie_info_items.find("a",{"rel":"v:directedBy"}).get_text()
            #语言: 英语
            movie_language=None
            #上映日期: 1994-09-10(多伦多电影节) / 1994-10-14(美国)
            movie_initialReleaseDate=None
            #片长: 142分钟
            movie_Runtime=None
            #又名: 月黑高飞(港) / 刺激1995(台) / 地狱诺言 / 铁窗岁月 / 消香克的救赎
            movie_alias=None
            #IMDb链接: tt0111161
            movie_IMDb_url=None
            #电影评分信息
            movie_votes_info=bsobj.find("div",{"id":"interest_sectl"})
            #处理电影评分信息
            #评分
            movie_vote=None
            #评分人数
            movie_voters=None
            #5星数量
            movie_vote_5_stars=None
        except:
            print("电影信息处理失败")
            return None
        return [movie_id,movie_name,movie_vote,movie_voters,movie_vote_5_stars,movie_directer,movie_attrs,movie_actors,movie_genre,movie_saition,movie_language,\
                movie_initialReleaseDate,movie_Runtime,movie_alias,movie_IMDb_url,movie_intro,movie_photos]
    
    # 下载海报
    def download_img(url,download_directory):
        """
        保存海报
        输入:下载文件地址,和板存路径
        输出:将文件保存到相应文件下
        """
        if not os.path.exists(download_directory):
            os.makedirs(download_directory)
        file_path=download_directory+url[-14:]
        try:
            urlretrieve(url, file_path)
            print("1")
            print("下载图片:%s完成!\n存储在:%s" % (url[-14:],file_path))
            time.sleep(2)
        except :
            print("下载图片:%s失败!" % (url[-14:]))
            return None
    
    

    相关文章

      网友评论

        本文标题:python爬虫-爬取豆瓣电影top250详细信息

        本文链接:https://www.haomeiwen.com/subject/rktphqtx.html