获取豆瓣网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)



浙公网安备 33010602011771号