diff --git a/爬取数据.py b/爬取数据.py new file mode 100644 index 0000000..8b62e02 --- /dev/null +++ b/爬取数据.py @@ -0,0 +1,120 @@ +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 元素内的 标签, + # 而 ['href'] 则提取了该 标签的 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) # 调用函数获取电影列表 +