|
|
import re # 导入正则表达式模块
|
|
|
import random # 导入随机数模块
|
|
|
import time # 导入时间模块
|
|
|
import requests # 导入请求模块
|
|
|
from bs4 import BeautifulSoup # 导入BeautifulSoup模块用于解析HTML
|
|
|
import xlwt # 导入xlwt模块用于操作Excel文件
|
|
|
from fake_useragent import UserAgent # 导入UserAgent模块用于生成随机User-Agent
|
|
|
|
|
|
# 定义正则表达式模式
|
|
|
link_pattern = re.compile(r'<a href="(.*?)">') # 匹配电影链接
|
|
|
title_pattern = re.compile(r'<span class="title">(.*)</span>') # 匹配电影标题
|
|
|
rating_pattern = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>') # 匹配评分
|
|
|
inq_pattern = re.compile(r'<span class="inq">(.*)</span>') # 匹配概况
|
|
|
|
|
|
|
|
|
# 主函数
|
|
|
def main():
|
|
|
base_url = "https://movie.douban.com/top250?start=%s&type=" # 豆瓣电影Top250的基础URL
|
|
|
data_list = get_data(base_url) # 获取数据列表
|
|
|
save_path = "豆瓣电影榜单前Top100.xls" # 保存路径
|
|
|
save_data(data_list, save_path) # 保存数据到Excel文件
|
|
|
|
|
|
|
|
|
# 爬取数据函数
|
|
|
def get_data(base_url):
|
|
|
data_list = [] # 创建空列表用于存储数据
|
|
|
user_agents = UserAgent() # 创建UserAgent对象
|
|
|
for i in range(0, 4): # 循环4次,每页25部电影,总共爬取100部
|
|
|
url = base_url % (i * 25) # 构建完整的URL
|
|
|
html = request_url(url, user_agents) # 请求URL获取HTML内容
|
|
|
soup = BeautifulSoup(html, "html.parser") # 使用BeautifulSoup解析HTML
|
|
|
for index, item in enumerate(soup.find_all('div', class_="item"), start=i * 25 + 1): # 遍历每个电影条目
|
|
|
data = [index] # 创建空列表用于存储电影信息
|
|
|
item = str(item) # 转换为字符串方便处理
|
|
|
link = re.findall(link_pattern, item)[0] # 提取电影链接
|
|
|
data.append(link) # 添加电影链接到列表
|
|
|
titles = re.findall(title_pattern, item) # 提取电影标题
|
|
|
data.append(titles[0] if len(titles) == 1 else titles[0]) # 添加电影标题到列表
|
|
|
rating = re.findall(rating_pattern, item)[0] # 提取评分
|
|
|
data.append(rating) # 添加评分到列表
|
|
|
inq = re.findall(inq_pattern, item) # 提取概况
|
|
|
data.append(inq[0] if inq else "") # 添加概况到列表,如果没有概况则为空字符串
|
|
|
data_list.append(data) # 将电影信息列表添加到总列表
|
|
|
time.sleep(random.uniform(1, 3)) # 休眠1到3秒,防止访问频率过高被封IP
|
|
|
return data_list # 返回数据列表
|
|
|
|
|
|
|
|
|
# 发送请求时模拟的浏览器信息函数
|
|
|
def request_url(url, user_agent):
|
|
|
headers = {'User-Agent': user_agent.random} # 使用随机User-Agent头部
|
|
|
try:
|
|
|
response = requests.get(url, headers=headers, timeout=10) # 发送请求
|
|
|
response.raise_for_status() # 检查请求是否成功
|
|
|
return response.text # 返回响应内容
|
|
|
except requests.RequestException as e:
|
|
|
print("Error: ", e) # 打印错误信息
|
|
|
return None # 返回空值
|
|
|
|
|
|
|
|
|
# 打印数据函数
|
|
|
def save_data(data_list, save_path):
|
|
|
print("Saving data...") # 打印保存数据的提示信息
|
|
|
workbook = xlwt.Workbook(encoding="utf-8", style_compression=0) # 创建Excel工作簿
|
|
|
sheet = workbook.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True) # 添加工作表
|
|
|
columns = ("排名", "电影详情链接", "影片名称", "评分", "简介") # 定义列名
|
|
|
for i, column in enumerate(columns): # 遍历列名列表
|
|
|
sheet.write(0, i, column) # 在第一行写入列名
|
|
|
for i, data in enumerate(data_list): # 遍历数据列表
|
|
|
for j, item in enumerate(data): # 遍历每个数据项
|
|
|
sheet.write(i + 1, j, item) # 写入数据到工作表
|
|
|
workbook.save(save_path) # 保存工作簿到文件
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": # 如果当前脚本被直接执行
|
|
|
main() # 调用主函数
|
|
|
print("爬取完毕!") # 打印爬取完毕的提示信息
|