我的第1個爬蟲程序——豆瓣Top250爬蟲的詳細步驟指南

我的第1個爬蟲程序——豆瓣Top250爬蟲的詳細步驟指南

在這里插入圖片描述


一、創建隔離開發環境

1. 使用虛擬環境(推薦venv
# 在項目目錄打開終端執行
python -m venv douban_env      # 創建虛擬環境
source douban_env/bin/activate # Linux/macOS激活
douban_env\Scripts\activate   # Windows激活
2. 安裝依賴庫
pip install requests beautifulsoup4 lxml
3. 生成依賴清單
pip freeze > requirements.txt

二、項目架構設計

douban_top250/
├── config/               # 配置文件
│   └── settings.py
├── core/                 # 核心邏輯
│   ├── spider.py
│   └── storage.py
├── utils/                # 工具函數
│   └── helper.py
├── output/               # 輸出目錄
├── main.py               # 主入口
└── requirements.txt      # 依賴清單

三、分步實現

步驟1:創建配置文件 config/settings.py
# 請求配置
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36','Referer': 'https://movie.douban.com/'
}# 目標URL配置
BASE_URL = 'https://movie.douban.com/top250'# 存儲配置
OUTPUT_DIR = './output'
CSV_HEADERS = ['標題', '評分', '年份', '國家', '類型', '鏈接']# 容錯配置
SAFE_MODE = True  # 遇到錯誤時跳過條目而不是終止
UNKNOWN_PLACEHOLDER = "未知"  # 數據缺失時的占位符
步驟2:編寫工具類 utils/helper.py
import random
import timedef random_delay(min=1, max=3):"""隨機延遲防止被封"""time.sleep(random.uniform(min, max))def make_soup(html):"""創建BeautifulSoup對象"""from bs4 import BeautifulSoupreturn BeautifulSoup(html, 'lxml')
步驟3:核心爬蟲邏輯 core/spider.py
import requests
from config import settings
from utils.helper import random_delay, make_soupclass DoubanSpider:def __init__(self):self.session = requests.Session()self.session.headers.update(settings.HEADERS)def fetch_page(self, url):"""獲取頁面內容"""try:random_delay()response = self.session.get(url)response.raise_for_status()  # 自動處理HTTP錯誤return response.textexcept requests.RequestException as e:print(f"請求失敗: {str(e)}")return Nonedef parse_page(self, html):"""改進后的解析方法"""soup = make_soup(html)movies = []for item in soup.find_all('div', class_='item'):try:# 標題與鏈接title = item.find('span', class_='title').text.strip()rating = item.find('span', class_='rating_num').text.strip()link = item.find('a')['href']# 詳細信息解析(穩健版)info_div = item.find('div', class_='bd')info_text = info_div.p.get_text(" ", strip=True)  # 用空格替代換行# 使用正則表達式提取年份/國家/類型import repattern = r'(\d{4})[^/]*(.*?)\s+/\s+(.*?)$'match = re.search(pattern, info_text)if match:year = match.group(1).strip()country = match.group(2).strip().replace('/', ' ')  # 處理國家中的斜杠genre = match.group(3).strip()else:year = country = genre = "N/A"  # 無法解析時填充默認值movies.append({'標題': title,'評分': rating,'年份': year,'國家': country,'類型': genre,'鏈接': link})except Exception as e:print(f"解析條目失敗: {str(e)}")continue  # 跳過當前條目return moviesdef get_all_pages(self):"""處理分頁"""all_movies = []start = 0while True:url = f"{settings.BASE_URL}?start={start}"html = self.fetch_page(url)if not html:breakmovies = self.parse_page(html)if not movies:breakall_movies.extend(movies)start += 25# 檢查是否還有下一頁if start >= 250:  # Top250最多250條breakreturn all_movies
步驟4:數據存儲模塊 core/storage.py
import csv
import json
import os
from config import settingsclass DataStorage:@staticmethoddef save_csv(data, filename='douban_top250.csv'):os.makedirs(settings.OUTPUT_DIR, exist_ok=True)path = os.path.join(settings.OUTPUT_DIR, filename)with open(path, 'w', newline='', encoding='utf-8') as f:writer = csv.DictWriter(f, fieldnames=settings.CSV_HEADERS)writer.writeheader()writer.writerows(data)print(f"數據已保存至 {path}")@staticmethoddef save_json(data, filename='douban_top250.json'):os.makedirs(settings.OUTPUT_DIR, exist_ok=True)path = os.path.join(settings.OUTPUT_DIR, filename)with open(path, 'w', encoding='utf-8') as f:json.dump(data, f, ensure_ascii=False, indent=2)print(f"數據已保存至 {path}")
步驟5:主程序 main.py
from core.spider import DoubanSpider
from core.storage import DataStoragedef main():# 檢查robots協議print("豆瓣 robots.txt 重要條款:")print("User-agent: *")print("Disallow: /search")  # 實際需查看最新內容# 執行爬蟲spider = DoubanSpider()movies_data = spider.get_all_pages()# 存儲數據if movies_data:DataStorage.save_csv(movies_data)DataStorage.save_json(movies_data)else:print("未獲取到有效數據")if __name__ == '__main__':main()

四、運行與驗證

  1. 在激活的虛擬環境中執行:
python main.py
  1. 檢查 output/ 目錄生成的 CSV 和 JSON 文件

在這里插入圖片描述

五、高級優化建議

  1. 異常處理增強
# 在spider類中添加重試機制
def fetch_page(self, url, retries=3):for attempt in range(retries):try:# ...原有代碼...except requests.RequestException as e:if attempt == retries - 1:raiseprint(f"重試中 ({attempt+1}/{retries})...")time.sleep(2 ** attempt)  # 指數退避
  1. 請求頭輪換
# 在settings.py中添加多個User-Agent
USER_AGENTS = ['Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
]# 在helper.py中添加選擇函數
def get_random_user_agent():return random.choice(settings.USER_AGENTS)
  1. 代理設置(如果需要):
# 在spider初始化時添加
def __init__(self, proxy=None):if proxy:self.session.proxies = {'http': proxy, 'https': proxy}

六、法律合規檢查

  1. 訪問 https://www.douban.com/robots.txt 查看協議
  2. 重點條款:
User-agent: *
Disallow: /subject_search
Disallow: /amazon_search
Disallow: /search
Disallow: /group/search
Disallow: /event/search
Disallow: /forum/search
Disallow: /game/search
  1. 合規措施:
  • 限制請求頻率(代碼中已實現隨機延遲)
  • 不繞過反爬機制
  • 僅用于學習用途
  • 不存儲敏感信息

通過這個結構化的項目實現,你可以:

  • 保持代碼的可維護性
  • 方便后續擴展功能(如添加代理支持)
  • 符合Python最佳實踐
  • 有效管理依賴項

下一步可以嘗試:

  1. 添加日志記錄模塊
  2. 實現數據庫存儲(MySQL/MongoDB)
  3. 使用Scrapy框架重構項目
  4. 部署到服務器定時運行

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82420.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82420.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82420.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STM32八股【11】-----Linux Bootloader (U-Boot)

參考U-Boot U-Boot是什么 嵌入式Linux系統需要一個bootloader來加載系統 U-boot就是一個通用開源的嵌入式Linux bootloader 主要實現的功能: 初始化硬件資源(如內存、串口、存儲器等)從存儲介質加載Linux內核到內存中傳遞啟動參數給內核啟…

【設計模式】責任鏈+模板+工程模式使用模板

前言 方便寫出優雅,解耦,高內聚,高復用的代碼。 Demo // 1. 定義驗證器接口(責任鏈模式) public interface Validator {Validator setNext(Validator next);boolean validate(Data data); }// 2. 創建抽象驗證器&am…

Unity3D仿星露谷物語開發49之創建云杉樹

1、目標 創建一顆既可以生長又可以砍伐的云杉樹,這個和之前創建橡樹類似。 2、創建云杉樹預制體 創建新物體命名為CropTreeBlueSpruce,并且添加Box Collider 2D和Crop組件。 在CropTreeBlueSpruce下創建子物體命名為CropSprite,添加3個組件…

【C#】消息隊列的使用

在C#中使用消息隊列,通常是指使用微軟的Message Queuing (MSMQ)技術。MSMQ提供了一種異步通信協議,允許應用程序通過暫時存儲要發送到目的地的消息來相互通信。 安裝MSMQ 首先,確保你的開發機器和部署服務器上都安裝了MSMQ。可以通過“控制…

IP-guard發布新版本4.87.2241.0

IP-guard發布新版本4.87.2241.0 新版本下載地址: https://www.tec-development.com/down/IPguard/Release/V4/IPguard4.87.2241.0.zip?s=901D45ADB22CBBFE5C612DC40AFD6BFB1551A9CD54EF418D5E86BBD256813867 新版本升級地址:

【Linux 服務器磁盤映像備份與恢復實戰指南】虛擬機備份,物理機上云都可以用這套方案!

Linux 服務器磁盤映像備份與恢復實戰指南 背景 在服務器運維中,磁盤健康度下降可能導致數據丟失風險,特別是在未配置 RAID 的情況下。針對這種情況,備份磁盤數據并恢復到新設備是確保數據安全的關鍵。本文記錄了使用 dd 命令通過 NFS 實現全…

深入理解 Linux 的 set、env 和 printenv 命令

在 Linux 和類 Unix 系統中,環境變量是配置和管理 Shell 及進程行為的核心機制。set、env 和 printenv 是與環境變量交互的三個重要命令,每個命令都有其獨特的功能和用途。本文將詳細探討這三個命令的區別,幫助大家更好地理解和使用這些命令。…

icexmoon-tree

icexmoon-tree 一個輕量級的 Java 工具庫&#xff0c;提供樹形結構操作功能。 安裝 <dependency><groupId>cn.icexmoon</groupId><artifactId>icexmoon-tree</artifactId><version>1.0.0</version> </dependency>使用 構建…

機器學習在智能水泥基復合材料中的應用與實踐

“機器學習在智能水泥基復合材料中的應用與實踐” 課程 內容 機器學習基礎模型與復合材料研究融合 機器學習在復合材料中的應用概述機器學習用于復合材料研究的流程復合材料數據收集與數據預處理 實例&#xff1a;數據的收集和預處理 復合材料機器學習特征工程與選擇 實例&a…

微軟 Build 2025:開啟 AI 智能體時代的產業革命

在 2025 年 5 月 19 日的微軟 Build 開發者大會上&#xff0c;薩提亞?納德拉以 "我們已進入 AI 智能體時代" 的宣言&#xff0c;正式拉開了人工智能發展的新紀元。這場匯聚了奧特曼、黃仁勛、馬斯克三位科技領袖的盛會&#xff0c;不僅發布了 50 余項創新產品&#…

[Java惡補day6] 15. 三數之和

給你一個整數數組 nums &#xff0c;判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i ! j、i ! k 且 j ! k &#xff0c;同時還滿足 nums[i] nums[j] nums[k] 0 。請你返回所有和為 0 且不重復的三元組。 注意&#xff1a;答案中不可以包含重復的三元組。 示例 1&a…

《黃帝內經》數學建模與形式化表征方式的重構

黃帝內經的數學概括&#xff1a;《黃帝內經》數學建模與形式化表征方式的重構 摘要&#xff1a;《黃帝內經》通過現代數學理論如動力系統、代數拓撲和隨機過程&#xff0c;被重構為一個形式化的人體健康模型。該模型包括陰陽動力學的微分幾何、五行代數的李群結構、經絡拓撲與同…

理論篇五:如何優化Webpack的打包速度

優化 Webpack 打包速度是提升前端開發效率的關鍵。以下是 10 種核心優化策略,涵蓋開發和生產環境,附帶具體配置和實測效果對比: 一、縮小文件搜索范圍 1. 指定解析路徑(Resolve) resolve: {extensions: [.js, .jsx],

[Windows] 游戲常用運行庫- Game Runtime Libraries Package(6.2.25.0409)

游戲常用運行庫 合集 整合了許多游戲會用到的運行庫&#xff0c;支持 Windows XP – Windows 11 系統&#xff0c;并且支持自動檢測系統勾選推薦的運行庫&#xff0c;方便快捷。 本版特點&#xff1a; By&#xff1a;mefcl 整合常見最新游戲所需運行庫 根據系統自動勾選推薦…

JDK8中的 Stream流式編程用法優化(工具類在文章最后)

Java從JDK8起提供了Stream流這個功能&#xff0c;于是項目里出現了大量基于Stream流的寫法。隨著項目的進行&#xff0c;慢慢的代碼中鋪天蓋地的都是下面的寫法&#xff1a; List<User> userList null;if (condition) {userList new ArrayList<>();userList.add(…

uni-app學習筆記十二-vue3中組件傳值(對象傳值)

一.單對象傳值 父組件定義對象的值 <template><view><UserInfo :obj"userinfo"></UserInfo></view> </template><script setup>import {ref} from "vue"const userinfo ref({name:"蛛兒",avatar:&…

UV-python環境管理工具 入門教程

在學習使用 MCP 的時候接觸到了 UV 這個環境管理工具&#xff0c;經過對比&#xff0c;發現它在諸多方面比 venv、conda 等工具更為出色&#xff0c;因此整理了這份簡單的入門學習筆記&#xff0c;希望能幫助大家快速上手。 介紹 UV 是一款集 Python 版本管理、虛擬環境創建與…

【漫話機器學習系列】277.梯度裁剪(Gradient Clipping)

【深度學習】什么是梯度裁剪&#xff08;Gradient Clipping&#xff09;&#xff1f;一張圖徹底搞懂&#xff01; 在訓練深度神經網絡&#xff0c;尤其是 RNN、LSTM、Transformer 這類深層結構時&#xff0c;你是否遇到過以下情況&#xff1a; 模型 loss 突然變成 NaN&#xf…

零基礎弄懂 ngx_http_slice_module分片緩存加速

一、為什么需要 Slice&#xff1f; 在 NGINX 反向代理或 CDN 場景中&#xff0c;大文件&#xff08;視頻、軟件包、鏡像等&#xff09;常因單體體積過大而令緩存命中率低、回源代價高。 ngx_http_slice_module 通過把一次完整響應拆分成 固定大小的字節塊&#xff08;Slice&am…

機器人強化學習入門學習筆記(三)

強化學習&#xff08;Reinforcement Learning, RL&#xff09;與監督學習不同——你不需要預先準備訓練數據集&#xff0c;而是要設計環境、獎勵函數&#xff0c;讓智能體通過交互不斷探索和學習。 &#x1f3af; 一、強化學習和訓練數據的關系 強化學習不依賴固定的數據集。它…