zoukankan      html  css  js  c++  java
  • 获取豆瓣网1980-2010年电影详情

    #coding=utf-8
    '''
    爬虫豆瓣电影,支持分年代爬取
    '''
    
    import time
    import requests
    import os
    import re
    import json
    import Save_Data
    import logging
    
    
    #定义日志级别及日志文件名
    logging.basicConfig(
        # 日志级别
        level = "ERROR",
        # 日志打印时间格式
        datefmt = "%Y-%m-%d %H:%M:%S",
        # 日志打印内容格式
        format = '%(asctime)s %(filename)s[line:%(lineno)d] %(message)s',
        # 日志输出到文件
        filename = ("log_2010.txt"),
        # 覆盖模式
        filemode = 'w'
    )
    
    # 定义请求头
    headers = {
        "Referer":"https://movie.douban.com/explore",
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
    }
    
    # 定义获取年份的时间区间
    year_dict = {
        "80年代":"1980,1989",
        "90年代":"1990,1999",
        "2000年代":"2000,2009",
        "2010年代":"2010,2019",
    }
    
    # 定义各个年代获取的电影页数
    max_page = {
        "80年代":"376",
        "90年代":"752",
        "2000年代":"1342",
        "2010年代":"2315",
    }
    
    
    def get_doubanmovie_index(time_start,idx,headers):
        '''
        获取电影类别页面内容
        :param movie_type:电影类别
        :param headers:请求头部信息
        :return:电影类别页面数据
        '''
        global proxy
        proxy= ''
        my_proxy = {
            'http': 'http://' + proxy,
            'https': 'https://' + proxy,
        }
        logging.error(proxy)
        logging.error(my_proxy)
        # page_idx = idx * 20
        url = "https://movie.douban.com/j/new_search_subjects?" 
              "sort=U&range=0,10&tags=%E5%8A%A8%E6%BC%AB&start={}" 
              "&countries=%E6%97%A5%E6%9C%AC&year_range={}".format(idx,time_start)
        try:
            logging.error(my_proxy)
            ret = requests.get(url,headers=headers,timeout=(2,4))
            # ret.raise_for_status()  #判断http头中的状态码是否为200
        except:
            print("获取电影:%s 页面内容出错;url:%s"%(time_start,url))
            logging.error("获取电影:%s 页面内容出错;url:%s"%(time_start,url))
            logging.error('')
            return ""
        return ret.text
    
    def get_movie_list(data):
        '''
        解析电影页面数据,主要为了获取电影名称及电影详情页url
        :param data:电影类别页面数据
        :return:电影名称及电影详情页url
        '''
        movie_list = []
        try:
            tmp_data = json.loads(data)
            subjects_data = tmp_data["data"]
            for i in subjects_data:
                movice_name = i["title"]
                movie_url = i["url"]
                movie_list.append([movice_name,movie_url])
        except:
            print("获取电影名称及电影详情页失败~")
            logging.error("获取电影名称及电影详情页失败~")
            logging.error(data)
        if len(movie_list) == 0:
            logging.error(data)
            return []
        return movie_list
    
    def movie_content_page(url,headers):
        '''
        获取电影详情页内容
        :param url:电影详情页url
        :param headers:请求头
        :return:电影详情页数据
        '''
        global proxy
        my_proxy = {
            'http': 'http://' + proxy,
            'https': 'https://' + proxy,
        }
        logging.error(proxy)
        logging.error(my_proxy)
        try:
            logging.error(my_proxy)
            ret = requests.get(url,headers = headers,timeout=(2,4))
            # ret.raise_for_status()
        except:
            # proxy = MyProxy.get_proxy()
            print("获取电影详情页失败,url:%s"%url)
            logging.error("获取电影详情页失败,url:%s"%url)
            logging.error('')
            return ""
        return ret.text
    
    def handle_movie_data(data):
        '''
        解析电影详情页数据,提取演员表、剧情介绍
        :param data:电影详情页所有数据
        :return:电影演员表
        :return:电影剧情介绍
        '''
        movie_info = []
        mark_pattern = re.compile('property="v:average">(.*?)</strong>')
        mark_and_count = re.findall(mark_pattern,data)
        count_pattern = re.compile('property="v:votes">(.*?)</span>')
        count = re.findall(count_pattern,data)
        movie_year_pattern = re.compile('"datePublished".*?:.*?"(.*?)"')
        movie_name_pattern = re.compile('property="v:itemreviewed">(.*?)</span>')
        movie_name = re.findall(movie_name_pattern,data)
        movie_year_bk = re.findall('class="year">(.*?)</span>',data)
        movie_year = re.findall(movie_year_pattern,data)
        try:
            #电影名称
            _name = (movie_name[0])
        except:
            _name = ""
        try:
            # 电影年份
            _year_bk = (str(movie_year_bk[0]).replace("(","").replace(")",""))
        except:
            _year_bk = ""
        try:
            _year = (movie_year[0])
        except:
            _year = ""
        try:
            _count = (count[0])
        except:
            _count = ""
        try:
            _mark = (mark_and_count[0])
        except:
            _mark = ""
        try:
            movie_info.append([_name,_year_bk,_year,_mark,_count])
        except:
            print("err")
            logging.error("ERROR movie_name:%s movie_year:%s movie_mark:%s movie_count:%s"%(
                movie_name,
                movie_year_bk,
                movie_year,
                mark_and_count,
                count))
        return movie_info
    
    def main(year_type,count):
        global proxy
        my_count = 1
        mk_path = '数据集' + "\" + year_type
        # 类别文件夹如果不存在,就创建
        if not os.path.exists(mk_path):
            os.makedirs(mk_path)
        # 提取开始年份
        time_start = year_dict.get(year_type)
        for idx in range(count):
            page_idx = idx * 20
            if page_idx > int(max_page.get(year_type)):
                break
            for i in range(5):
                # 获取该类别的电影主页内容
                index_data = get_doubanmovie_index(time_start,page_idx,headers)
                # 解析该主页内容,得到["电影名称","电影详情页url"]
                movie_url_list = get_movie_list(index_data)
                if len(index_data) > 0 and len(movie_url_list) > 0:
                    break
                else:
                    logging.error("------------%s"%proxy)
                    time.sleep(2)
                if i > 3:
                    break
            logging.error("第%d页获取成功! length_html:%d"%(
                (page_idx+1),
                len(index_data)
                )
            )
            for url_list in movie_url_list:
                logging.error(url_list)
                movie_url = url_list[1]
                for i in range(5):
                    # 获取电影详情页的内容
                    movie_content_data = movie_content_page(movie_url, headers)
                    # 获取电影演员表及剧情介绍
                    movie_info_list = handle_movie_data(movie_content_data)
                    if len(movie_content_data) > 0 and len(movie_info_list) > 0:
                        print('已经获取%d部电影数据'%my_count)
                        my_count += 1
                        break
                    else:
                        logging.error("------------%s" % proxy)
                    if i > 3:
                        break
                # 保存电影剧情介绍
                Save_Data.save_content(mk_path,movie_info_list)
                logging.error("第%d页获取成功! url:%s"%(
                    (page_idx+1),
                    url_list[1]
                    )
                )
    
    if __name__ == '__main__':
        if not os.path.exists('数据集'):
            os.mkdir('数据集')
        # 定义需要爬取的类别列表
        want_get_movie = ["80年代","90年代","2000年代","2010年代"]
        # 定义爬取页数,每页20条
        COUNT = 2315
        # 遍历需要爬取的类别列表
        for type_name in want_get_movie:
            main(type_name,COUNT)
            #coding=utf-8
    '''
    数据存储模块,保存电影数据
    '''
    
    import csv
    import logging
    
    def save_actor(file_path,data):
        '''
        保存电影演员信息
        :param file_path:保存的路径信息
        :param data: 电影演员信息
        :return:
        '''
        file_name = file_path + "\" + "演员表.csv"  #在电影名的文件夹下,将数据保存到演员表.csv
        o_file = open(file_name,"w",newline="",encoding="utf-8-sig")
        f = csv.writer(o_file)
        for i in data:
            f.writerow(i)
        o_file.close()
    
    def save_content(file_path,data):
        '''
        :param file_path: 保存的路径信息
        :param data: 电影信息
        :return:
        '''
        try:
            file_name = file_path + "\" + "动漫数据.csv"
            f = open(file_name, "a", encoding="utf-8-sig",newline="")
            c_f = csv.writer(f)
            for i in data:
                c_f.writerow(i)
            f.close()
        except:
            logging.error("保存数据失败:%s"%data)
    

      

  • 相关阅读:
    python中创建函数和调用函数
    python中函数的参数
    python 函数中的关键字参数
    python中创建集合
    python中函数文档
    python中函数形式参数、实际参数、位置参数、关键字参数
    python中不可变集合
    我是谁?(程序员版)
    《林阴小路》疏辨
    用户接口常用术语英语德语对照
  • 原文地址:https://www.cnblogs.com/48520-xc/p/12699060.html
Copyright © 2011-2022 走看看