You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
6.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import os
import re
import time
from wsgiref import headers
import requests # 导入requests库用于发送HTTP请求
from bs4 import BeautifulSoup # 导入BeautifulSoup库用于解析HTML
from fake_useragent import UserAgent # 导入UserAgent用于生成随机的User-Agent
from openpyxl import Workbook, load_workbook # 导入openpyxl库用于操作Excel文件
# 定义一个函数,用于获取单个页面的电影列表
def getonepagelist(url, headers):
try:
# 发送HTTP GET请求
r = requests.get(url, headers=headers, timeout=10)
r.raise_for_status() # 如果响应状态码不是200则抛出异常
r.encoding = 'utf-8' # 设置响应内容的编码为utf-8
soup = BeautifulSoup(r.text, 'html.parser') # 使用BeautifulSoup解析HTML
lsts = soup.find_all(attrs={'class': 'hd'}) # 查找所有class为'hd'的元素,即电影列表项
# 遍历电影列表项
for lst in lsts:
href = lst.a['href'] # 获取电影详情页链接
# 从 BeautifulSoup 解析出的 HTML 元素 lst 中提取链接地址。lst.a 选择了 lst 元素内的 <a> 标签,
# 而 ['href'] 则提取了该 <a> 标签的 href 属性,即链接地址。这样,变量 href 就存储了提取出的链接地址。
time.sleep(0.5) # 休眠0.5秒防止访问频率过高被封IP
getfilminfo(href, headers)
except: # 捕获所有异常
print('getonepagelist error!') # 打印错误信息
# 定义一个函数,用于获取电影详情信息
#注意国家/地区的处理,为了数据分析更方便,这里时长只取电影的第一个时长(部分电影有多个时长)
def getfilminfo(url, headers):
filminfo = [] # 初始化电影信息列表
r = requests.get(url, headers=headers, timeout=10) # 发送HTTP GET请求
r.raise_for_status() # 如果响应状态码不是200则抛出异常
r.encoding = 'utf-8' # 设置响应内容的编码为utf-8
soup = BeautifulSoup(r.text, 'html.parser') # 使用BeautifulSoup解析HTML
# 获取电影名称
# 使用 BeautifulSoup 的 find 方法来找到 HTML 标签中 property 属性为 'v:itemreviewed' 的元素,通常这个元素包含电影的名称。
# 然后通过 .text 获取其文本内容,并使用 split(' ') 将名称以空格分割成列表,取列表的第一个元素即为电影名称。
name = soup.find(attrs={'property': 'v:itemreviewed'}).text.split(' ')[0]
# 获取上映年份
# 找到 HTML 标签中 class 属性为 'year' 的元素,通常包含电影的上映年份。然后使用 .text 获取文本内容,并通过 replace 方法去掉括号。
year = soup.find(attrs={'class': 'year'}).text.replace('(', '').replace(')', '')
# 获取评分
# 找到 HTML 标签中 property 属性为 'v:average' 的元素,通常包含电影的评分。
score = soup.find(attrs={'property': 'v:average'}).text
# 获取评价人数
# 找到 HTML 标签中 property 属性为 'v:votes' 的元素,通常包含电影的评价人数。
votes = soup.find(attrs={'property': 'v:votes'}).text
infos = soup.find(attrs={'id': 'info'}).text.split('\n')[1:11] # 获取电影详细信息
# 获取导演、编剧、主演、类型、国家/地区、语言等信息
# 通过列表切片和字符串处理,提取了导演、编剧、主演、类型、国家/地区等信息。
director = infos[0].split(': ')[1]
scriptwriter = infos[1].split(': ')[1]
actor = infos[2].split(': ')[1]
filmtype = infos[3].split(': ')[1]
area = infos[4].split(': ')[1]
# 用来处理国家/地区和语言信息的格式,因为有时候这些信息会以字符串列表的形式呈现,需要进行额外的处理。
if '.' in area: # 处理国家/地区和语言的格式
area = infos[5].split(': ')[1].split(' / ')[0]
language = infos[6].split(': ')[1].split(' / ')[0]
else:
area = infos[4].split(': ')[1].split(' / ')[0]
language = infos[5].split(': ')[1].split(' / ')[0]
# 对国家/地区进行处理
if '大陆' in area or '香港' in area or '台湾' in area:
area = '中国'
if '戛纳' in area:
area = '法国'
# 获取电影时长
# 到 HTML 标签中 property 属性为 'v:runtime' 的元素,通常包含电影的时长。然后使用正则表达式 re.findall('\\d+', times0)
# 找到文本中的数字部分,并取第一个数字,即电影的时长。
times0 = soup.find(attrs={'property': 'v:runtime'}).text
times = re.findall('\\d+', times0)[0]
# 将获取的信息添加到电影信息列表中
filminfo.append(name)
filminfo.append(year)
filminfo.append(score)
filminfo.append(votes)
filminfo.append(director)
filminfo.append(scriptwriter)
filminfo.append(actor)
filminfo.append(filmtype)
filminfo.append(area)
filminfo.append(language)
filminfo.append(times)
filepath = 'TOP250.xlsx' # Excel文件路径
insert2excel(filepath, filminfo) # 将电影信息插入到Excel文件中
# 定义一个函数用于将电影信息插入到Excel文件中
# 这里我们使用openpyxl将数据保存到Excel中
def insert2excel(filepath, allinfo):
try:
if not os.path.exists(filepath): # 如果Excel文件不存在则创建一个新的文件并添加表头
tableTitle = ['片名', '上映年份', '评分', '评价人数', '导演', '编剧', '主演', '类型', '国家/地区', '语言', '时长(分钟)']
wb = Workbook() # 创建一个Workbook对象
ws = wb.active # 获取当前活动的工作表
ws.title = 'sheet1' # 设置工作表的标题为'sheet1'
ws.append(tableTitle) # 添加表头
wb.save(filepath) # 保存Excel文件
time.sleep(3) # 休眠3秒
wb = load_workbook(filepath) # 加载Excel文件
ws = wb.active # 获取当前活动的工作表
ws.title = 'sheet1' # 设置工作表的标题为'sheet1'
ws.append(allinfo) # 添加电影信息
wb.save(filepath) # 保存Excel文件
return True # 返回True表示插入成功
except:
return False # 返回False表示插入失败
# 遍历爬取前11页的电影信息
for i in range(11):
print(f'正在爬取第{i}页,请稍等...')
url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25) # 构造URL
headers = {
'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1'
} # 构造HTTP请求头部信息
getonepagelist(url, headers) # 调用函数获取电影列表