当前位置: 首页 > news >正文

Python实例题: Python 的简单电影信息

目录

Python实例题

题目

代码实现

实现原理

网页请求:

内容解析:

数据存储:

反爬策略:

关键代码解析

1. 网页请求处理

2. 电影列表解析

3. 电影详情解析

4. 爬虫主逻辑

使用说明

安装依赖:

修改配置:

运行爬虫:

查看结果:

注意事项

法律合规:

反爬策略:

网站结构变化:

数据使用限制:

Python实例题

题目

 Python 的简单电影信息

代码实现

import requests
from bs4 import BeautifulSoup
import json
import time
import random
import logging
from fake_useragent import UserAgentclass MovieCrawler:"""电影信息爬虫类"""def __init__(self):"""初始化爬虫"""self.ua = UserAgent()self.headers = {'User-Agent': self.ua.random,'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6','Connection': 'keep-alive'}self.logger = self._setup_logger()self.movies = []def _setup_logger(self):"""配置日志记录"""logger = logging.getLogger('movie_crawler')logger.setLevel(logging.INFO)# 创建控制台处理器ch = logging.StreamHandler()ch.setLevel(logging.INFO)# 创建日志格式formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')ch.setFormatter(formatter)# 添加处理器到loggerlogger.addHandler(ch)return loggerdef fetch_movie_list(self, url, page_num=1):"""获取电影列表页Args:url: 电影列表页URLpage_num: 页码Returns:页面内容或None"""try:# 构造完整URLfull_url = f"{url}?page={page_num}" if page_num > 1 else url# 更新User-Agentself.headers['User-Agent'] = self.ua.random# 发送请求response = requests.get(full_url, headers=self.headers, timeout=10)# 检查响应状态if response.status_code == 200:self.logger.info(f"成功获取页面: {full_url}")return response.textelse:self.logger.error(f"获取页面失败,状态码: {response.status_code}, URL: {full_url}")return Noneexcept Exception as e:self.logger.error(f"请求发生异常: {str(e)}")return Nonedef parse_movie_list(self, html_content):"""解析电影列表页Args:html_content: 页面HTML内容Returns:电影信息列表"""if not html_content:return []try:soup = BeautifulSoup(html_content, 'html.parser')movie_items = []# 这里需要根据实际网站结构调整选择器# 以下是一个示例选择器,用于演示目的for item in soup.select('.movie-item'):try:title = item.select_one('.title').text.strip()link = item.select_one('a')['href']rating = item.select_one('.rating').text.strip()year = item.select_one('.year').text.strip()movie_items.append({'title': title,'link': link,'rating': rating,'year': year})except (AttributeError, KeyError) as e:self.logger.warning(f"解析电影项时出错: {str(e)}")continueself.logger.info(f"成功解析 {len(movie_items)} 部电影")return movie_itemsexcept Exception as e:self.logger.error(f"解析页面时发生异常: {str(e)}")return []def fetch_movie_detail(self, url):"""获取电影详情页Args:url: 电影详情页URLReturns:页面内容或None"""try:# 更新User-Agentself.headers['User-Agent'] = self.ua.random# 发送请求response = requests.get(url, headers=self.headers, timeout=15)# 检查响应状态if response.status_code == 200:self.logger.info(f"成功获取详情页: {url}")return response.textelse:self.logger.error(f"获取详情页失败,状态码: {response.status_code}, URL: {url}")return Noneexcept Exception as e:self.logger.error(f"请求详情页发生异常: {str(e)}")return Nonedef parse_movie_detail(self, html_content, base_info):"""解析电影详情页Args:html_content: 页面HTML内容base_info: 从列表页获取的基础信息Returns:完整的电影信息"""if not html_content:return base_infotry:soup = BeautifulSoup(html_content, 'html.parser')# 提取详细信息,这里需要根据实际网站结构调整选择器director = soup.select_one('.director').text.strip() if soup.select_one('.director') else '未知'actors = [a.text.strip() for a in soup.select('.actors li')] if soup.select('.actors li') else []genre = [g.text.strip() for g in soup.select('.genre a')] if soup.select('.genre a') else []duration = soup.select_one('.duration').text.strip() if soup.select_one('.duration') else '未知'description = soup.select_one('.description').text.strip() if soup.select_one('.description') else ''# 合并信息movie_info = {**base_info,'director': director,'actors': actors,'genre': genre,'duration': duration,'description': description}return movie_infoexcept Exception as e:self.logger.error(f"解析详情页时发生异常: {str(e)}")return base_infodef crawl(self, base_url, total_pages=1):"""执行爬虫Args:base_url: 电影列表页基础URLtotal_pages: 要爬取的总页数"""self.logger.info(f"开始爬取电影信息,总页数: {total_pages}")for page in range(1, total_pages + 1):self.logger.info(f"正在爬取第 {page} 页...")# 获取电影列表页list_content = self.fetch_movie_list(base_url, page)# 解析电影列表movie_list = self.parse_movie_list(list_content)# 遍历电影列表,获取详情for movie in movie_list:# 构造完整详情页URLdetail_url = movie['link']if not detail_url.startswith('http'):detail_url = base_url + detail_url# 获取电影详情页detail_content = self.fetch_movie_detail(detail_url)# 解析电影详情full_movie_info = self.parse_movie_detail(detail_content, movie)# 添加到结果列表self.movies.append(full_movie_info)self.logger.info(f"成功获取电影: {full_movie_info['title']}")# 随机延时,避免过快请求time.sleep(random.uniform(1, 3))# 页面间延时time.sleep(random.uniform(2, 5))self.logger.info(f"爬取完成,共获取 {len(self.movies)} 部电影信息")def save_to_json(self, filename='movies.json'):"""将爬取的电影信息保存到JSON文件Args:filename: 保存的文件名"""try:with open(filename, 'w', encoding='utf-8') as f:json.dump(self.movies, f, ensure_ascii=False, indent=2)self.logger.info(f"电影信息已保存到 {filename}")except Exception as e:self.logger.error(f"保存文件时发生异常: {str(e)}")# 示例使用
def example_usage():# 注意:这只是一个示例URL,实际上需要替换为真实的电影网站URLbase_url = "https://example.com/movies"# 创建爬虫实例crawler = MovieCrawler()# 执行爬虫,爬取前3页crawler.crawl(base_url, total_pages=3)# 保存结果crawler.save_to_json('movies.json')if __name__ == "__main__":example_usage()    

实现原理

这个简单的电影爬虫基于以下技术实现:

  • 网页请求

    • 使用 requests 库发送 HTTP 请求
    • 随机更换 User-Agent 模拟不同浏览器
    • 设置合理的请求间隔避免被封 IP
  • 内容解析

    • 使用 BeautifulSoup 解析 HTML 内容
    • 通过 CSS 选择器提取所需信息
    • 处理可能的解析异常
  • 数据存储

    • 将爬取的电影信息存储为 JSON 格式
    • 提供清晰的日志记录功能
  • 反爬策略

    • 随机延时请求
    • 动态更换请求头
    • 异常处理和日志记录

关键代码解析

1. 网页请求处理

def fetch_movie_list(self, url, page_num=1):try:full_url = f"{url}?page={page_num}" if page_num > 1 else urlself.headers['User-Agent'] = self.ua.randomresponse = requests.get(full_url, headers=self.headers, timeout=10)if response.status_code == 200:self.logger.info(f"成功获取页面: {full_url}")return response.textelse:self.logger.error(f"获取页面失败,状态码: {response.status_code}, URL: {full_url}")return Noneexcept Exception as e:self.logger.error(f"请求发生异常: {str(e)}")return None

2. 电影列表解析

def parse_movie_list(self, html_content):if not html_content:return []try:soup = BeautifulSoup(html_content, 'html.parser')movie_items = []for item in soup.select('.movie-item'):try:title = item.select_one('.title').text.strip()link = item.select_one('a')['href']rating = item.select_one('.rating').text.strip()year = item.select_one('.year').text.strip()movie_items.append({'title': title,'link': link,'rating': rating,'year': year})except (AttributeError, KeyError) as e:self.logger.warning(f"解析电影项时出错: {str(e)}")continueself.logger.info(f"成功解析 {len(movie_items)} 部电影")return movie_itemsexcept Exception as e:self.logger.error(f"解析页面时发生异常: {str(e)}")return []

3. 电影详情解析

def parse_movie_detail(self, html_content, base_info):if not html_content:return base_infotry:soup = BeautifulSoup(html_content, 'html.parser')director = soup.select_one('.director').text.strip() if soup.select_one('.director') else '未知'actors = [a.text.strip() for a in soup.select('.actors li')] if soup.select('.actors li') else []genre = [g.text.strip() for g in soup.select('.genre a')] if soup.select('.genre a') else []duration = soup.select_one('.duration').text.strip() if soup.select_one('.duration') else '未知'description = soup.select_one('.description').text.strip() if soup.select_one('.description') else ''movie_info = {**base_info,'director': director,'actors': actors,'genre': genre,'duration': duration,'description': description}return movie_infoexcept Exception as e:self.logger.error(f"解析详情页时发生异常: {str(e)}")return base_info

4. 爬虫主逻辑

def crawl(self, base_url, total_pages=1):self.logger.info(f"开始爬取电影信息,总页数: {total_pages}")for page in range(1, total_pages + 1):self.logger.info(f"正在爬取第 {page} 页...")# 获取电影列表页list_content = self.fetch_movie_list(base_url, page)# 解析电影列表movie_list = self.parse_movie_list(list_content)# 遍历电影列表,获取详情for movie in movie_list:# 构造完整详情页URLdetail_url = movie['link']if not detail_url.startswith('http'):detail_url = base_url + detail_url# 获取电影详情页detail_content = self.fetch_movie_detail(detail_url)# 解析电影详情full_movie_info = self.parse_movie_detail(detail_content, movie)# 添加到结果列表self.movies.append(full_movie_info)self.logger.info(f"成功获取电影: {full_movie_info['title']}")# 随机延时,避免过快请求time.sleep(random.uniform(1, 3))# 页面间延时time.sleep(random.uniform(2, 5))self.logger.info(f"爬取完成,共获取 {len(self.movies)} 部电影信息")

使用说明

  • 安装依赖

pip install requests beautifulsoup4 fake-useragent
  • 修改配置

    • 在代码中替换base_url为实际的电影网站 URL,并根据目标网站的 HTML 结构调整解析部分的 CSS 选择器。

  • 运行爬虫

python movie_crawler.py
  • 查看结果

    • 爬取的电影信息会保存到movies.json文件中。

注意事项

  • 法律合规

    • 此程序仅用于演示爬虫技术,请勿用于非法获取受版权保护的内容
    • 爬取网站前请查看其 robots.txt 文件和使用条款
    • 遵守相关国家和地区的法律法规
  • 反爬策略

    • 控制爬取速度,避免对目标网站造成压力
    • 添加合理的延时和请求头信息
    • 考虑使用代理 IP 池
  • 网站结构变化

    • 网站结构可能随时变化,需要相应调整解析代码
    • 建议添加适当的错误处理和重试机制
  • 数据使用限制

    • 爬取的数据仅供个人学习研究使用,不可用于商业用途
    • 尊重原网站的版权和数据使用政策
http://www.xdnf.cn/news/865387.html

相关文章:

  • 舆情监控系统爬虫技术解析
  • go语言学习 第5章:函数
  • SQL-为什么缺少 COUNT(*) 会导致总行数返回1
  • Android 轻松实现 增强版灵活的 滑动式表格视图
  • 前端面试三之控制语句
  • el-input限制输入数字,输入中文后数字校验失效
  • 【输入URL到页面展示】
  • 一文读懂RAG流程中用到的请求参数与返回字段
  • HTMLCSS 学习总结
  • (T/SAIAS 020-2024)《医疗大模型语料一体机应用指南》深度解读与实施分析
  • Shiro安全权限框架
  • OpenCV CUDA模块图像处理------图像连通域标记接口函数connectedComponents()
  • iOS UIActivityViewController 组头处理
  • OSPF域间路由
  • fastadmin fildList 动态下拉框默认选中
  • parquet :开源的列式存储文件格式
  • 【PhysUnits】15.13 SI类型级量纲(dimension.rs)
  • 针对KG的神经符号集成综述 两篇
  • 企业级实战之Iptables防火墙案例分析
  • 11. 试学内容-如何理解隔离性2(原理)
  • mysql知识点
  • Axios学习笔记
  • 技术文档的降维打击:3大原则+5步结构+CSDN流量密码
  • 瀚文机械键盘固件开发详解:HWKeyboard.cpp文件解析与应用
  • linux 故障处置通用流程-36计+1计
  • 传输层协议 UDP 介绍 -- UDP 协议格式,UDP 的特点,UDP 的缓冲区
  • OPENCV的AT函数
  • 验证负载均衡与弹性伸缩
  • Nginx+Tomcat负载均衡与动静分离架构
  • 保险丝选型