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

没有全部完成,没有过程解释,只有整体框架,等我写完,下周末继续完成。

如题,我要爬取豆瓣电影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详细信息)