Python 爬蟲案例:爬取豆瓣電影 Top250 數據

一、案例背景與目標

豆瓣電影 Top250 是國內權威的電影評分榜單之一,包含電影名稱、評分、評價人數、導演、主演、上映年份、國家 / 地區、類型等關鍵信息。本案例將使用 Python 編寫爬蟲,實現以下目標:

  1. 自動請求豆瓣電影 Top250 的 10 個分頁(每頁 25 部電影);
  2. 解析頁面 HTML 結構,提取每部電影的 8 項核心信息;
  3. 數據清洗(處理異常字符、統一格式);
  4. 將最終數據保存到 Excel 文件,方便后續分析。

二、技術棧選擇

本案例使用輕量級且易上手的技術組合,適合爬蟲初學者:

工具 / 庫作用
requests發送 HTTP 請求,獲取網頁源代碼
BeautifulSoup4解析 HTML 文檔,提取目標數據(非結構化→結構化)
pandas數據清洗、整理,并將數據寫入 Excel
time控制請求間隔,避免觸發網站反爬機制
user-agent偽裝瀏覽器請求頭,繞過基礎反爬

三、完整代碼實現

# 1. 導入所需庫
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time# 2. 定義核心配置
# 豆瓣電影 Top250 分頁 URL 規律:start 參數從 0 開始,每次加 25(0、25、50...225)
BASE_URL = "https://movie.douban.com/top250?start={}&filter="
# 偽裝瀏覽器請求頭(避免被識別為爬蟲)
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
}
# 存儲所有電影數據的列表
movie_list = []# 3. 定義頁面解析函數(提取單頁電影數據)
def parse_movie_page(html):# 初始化 BeautifulSoup 解析器(指定 lxml 解析器,效率更高)soup = BeautifulSoup(html, "lxml")# 定位所有電影項的父容器(每個 li 對應一部電影)movie_items = soup.find_all("li", class_="item")for item in movie_items:# 3.1 提取電影名稱(默認取第一個中文名稱)title_tag = item.find("span", class_="title")movie_name = title_tag.get_text(strip=True) if title_tag else "未知名稱"# 3.2 提取評分rating_tag = item.find("span", class_="rating_num")rating = rating_tag.get_text(strip=True) if rating_tag else "0.0"# 3.3 提取評價人數(處理格式,如 "123.4萬人評價" → "1234000")comment_tag = item.find("span", text=lambda x: x and "人評價" in x)comment_count = comment_tag.get_text(strip=True).replace("人評價", "").replace("萬", "0000") if comment_tag else "0"# 3.4 提取導演和主演(格式:"導演: 張藝謀 主演: 沈騰, 馬麗")info_tag = item.find("div", class_="bd").find("p", class_="")info_text = info_tag.get_text(strip=True).split("\n") if info_tag else ["", ""]director_actor = info_text[0].strip() if len(info_text) > 0 else "未知信息"# 3.5 提取上映年份、國家/地區、類型(格式:"2023 / 中國大陸 / 喜劇, 劇情")detail_text = info_text[1].strip() if len(info_text) > 1 else "未知 / 未知 / 未知"detail_list = detail_text.split(" / ")release_year = detail_list[0].strip() if len(detail_list) > 0 else "未知年份"country = detail_list[1].strip() if len(detail_list) > 1 else "未知國家"genre = detail_list[2].strip() if len(detail_list) > 2 else "未知類型"# 3.6 提取電影簡介(處理可能的空值)quote_tag = item.find("span", class_="inq")intro = quote_tag.get_text(strip=True) if quote_tag else "無簡介"# 3.7 將單部電影數據存入字典movie_dict = {"電影名稱": movie_name,"評分": rating,"評價人數": comment_count,"導演&主演": director_actor,"上映年份": release_year,"國家/地區": country,"類型": genre,"簡介": intro}movie_list.append(movie_dict)# 4. 定義主爬蟲函數(循環請求所有分頁)
def crawl_douban_top250():# 循環 10 個分頁(start=0,25,...,225)for page in range(10):start = page * 25url = BASE_URL.format(start)print(f"正在爬取第 {page+1} 頁,URL:{url}")try:# 4.1 發送 GET 請求(添加超時控制,避免無限等待)response = requests.get(url, headers=HEADERS, timeout=10)# 4.2 檢查請求是否成功(狀態碼 200 表示正常)response.raise_for_status()  # 若狀態碼非 200,拋出 HTTPError 異常# 4.3 解析當前頁面數據parse_movie_page(response.text)# 4.4 控制請求間隔(1-2 秒),避免給服務器造成壓力,降低反爬風險time.sleep(1.5)except requests.exceptions.RequestException as e:print(f"爬取第 {page+1} 頁失敗,錯誤原因:{str(e)}")continue  # 跳過失敗頁面,繼續爬取下一頁# 5. 定義數據保存函數(保存到 Excel)
def save_to_excel():if not movie_list:print("無數據可保存!")return# 5.1 將列表轉換為 DataFrame(pandas 數據結構,便于處理)df = pd.DataFrame(movie_list)# 5.2 數據清洗:處理評價人數的數值格式(如 "123.4000" → 1234000)df["評價人數"] = pd.to_numeric(df["評價人數"].str.replace(".", ""), errors="coerce").fillna(0).astype(int)# 5.3 保存到 Excel(index=False 表示不保存行號)excel_path = "豆瓣電影Top250數據.xlsx"df.to_excel(excel_path, index=False, engine="openpyxl")print(f"數據已成功保存到:{excel_path}")print(f"共爬取到 {len(movie_list)} 部電影數據")# 6. 程序入口(執行爬蟲流程)
if __name__ == "__main__":print("開始爬取豆瓣電影 Top250 數據...")crawl_douban_top250()  # 1. 爬取數據save_to_excel()        # 2. 保存數據print("爬取任務完成!")

四、代碼解析(關鍵步驟拆解)

1. 環境準備(安裝依賴庫)

在運行代碼前,需要確保所有必要的 Python 庫都已正確安裝。這些庫分別承擔不同的功能:

  • requests:用于發送 HTTP 請求,獲取網頁內容
  • beautifulsoup4:用于解析 HTML 文檔,提取所需數據
  • pandas:用于數據處理和分析
  • openpyxl:作為 pandas 的依賴,用于寫入 Excel 文件
  • lxml:作為 BeautifulSoup 的解析器,提供高效的 HTML 解析能力

安裝命令:

pip install requests beautifulsoup4 pandas openpyxl lxml

提示:如果是在國內網絡環境,建議使用國內鏡像源加速安裝,例如:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests beautifulsoup4 pandas openpyxl lxml

2. 反爬機制規避(核心細節)

網絡爬蟲需要尊重目標網站的規則,同時也要采取適當措施避免被網站識別并封鎖。本代碼中采用了多種反爬策略:

2.1 偽裝請求頭
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
}

這是最基礎也最重要的反爬措施。網站服務器通過User-Agent字段識別訪問者身份,默認情況下,requests庫的請求頭會顯示為 "python-requests/xx.x.x",很容易被識別為爬蟲。通過設置一個真實的瀏覽器User-Agent,可以模擬正常用戶的瀏覽器訪問。

你可以通過訪問https://httpbin.org/get查看自己瀏覽器的User-Agent并替換。

2.2 控制請求頻率
time.sleep(1.5)

這行代碼的作用是在爬取完一頁后暫停 1.5 秒再繼續。短時間內發送大量請求是爬蟲最明顯的特征之一,通過添加合理的延遲,可以模擬人類瀏覽網頁的行為,降低被網站識別的概率。

延遲時間可以根據實際情況調整,一般建議在 1-3 秒之間。對于反爬嚴格的網站,可能需要更長的延遲。

2.3 異常處理機制
try:# 發送請求的代碼
except requests.exceptions.RequestException as e:print(f"爬取第 {page+1} 頁失敗,錯誤原因:{str(e)}")continue

這段異常處理代碼可以捕獲所有與請求相關的異常,包括網絡連接錯誤、超時、HTTP 錯誤狀態碼等。當某一頁爬取失敗時,程序不會崩潰,而是會打印錯誤信息并繼續爬取下一頁,保證了程序的健壯性。

response.raise_for_status()方法會在 HTTP 請求返回錯誤狀態碼(4xx 或 5xx)時拋出異常,讓我們能夠及時發現并處理請求錯誤。

3. HTML 解析邏輯(如何定位數據)

解析 HTML 是爬蟲的核心步驟,需要仔細分析網頁結構,找到目標數據所在的位置。我們可以通過瀏覽器的開發者工具(F12)來查看網頁的 HTML 結構。

3.1 分析網頁結構

豆瓣電影 Top250 的頁面結構具有一定的規律性:

  • 所有電影條目都包含在<ul class="grid_view">標簽中
  • 每個電影條目對應一個<li class="item">標簽
  • 每個條目中包含了電影的各種信息:名稱、評分、評價人數等
3.2 提取電影列表
movie_items = soup.find_all("li", class_="item")

這行代碼使用find_all方法查找所有class為 "item" 的li標簽,每個標簽對應一部電影的信息。返回的movie_items是一個列表,包含了當前頁面所有電影的信息。

3.3 提取單個電影信息
3.3.1 提取電影名稱
title_tag = item.find("span", class_="title")
movie_name = title_tag.get_text(strip=True) if title_tag else "未知名稱"

電影名稱位于class為 "title" 的span標簽中。get_text(strip=True)方法用于獲取標簽內的文本內容,并去除前后的空白字符。通過if title_tag else "未知名稱"的判斷,可以處理標簽不存在的情況,避免程序出錯。

3.3.2 提取評分
rating_tag = item.find("span", class_="rating_num")
rating = rating_tag.get_text(strip=True) if rating_tag else "0.0"

評分信息位于class為 "rating_num" 的span標簽中。同樣使用了條件判斷來處理可能的缺失情況。

3.3.3 提取評價人數
comment_tag = item.find("span", text=lambda x: x and "人評價" in x)
comment_count = comment_tag.get_text(strip=True).replace("人評價", "").replace("萬", "0000") if comment_tag else "0"

評價人數的提取相對復雜一些,因為它沒有特定的class名稱。這里使用了一個 lambda 函數作為篩選條件,查找文本中包含 "人評價" 的span標簽。

提取到文本后,還需要進行處理:

  • 去除 "人評價" 字符串
  • 將 "萬" 轉換為 "0000",以便后續轉換為數字
3.3.4 提取導演和主演
info_tag = item.find("div", class_="bd").find("p", class_="")
info_text = info_tag.get_text(strip=True).split("\n") if info_tag else ["", ""]
director_actor = info_text[0].strip() if len(info_text) > 0 else "未知信息"

導演和主演信息位于class為 "bd" 的div標簽下的第一個p標簽中。這里的find("p", class_="")表示查找沒有class屬性的p標簽。

獲取文本后,使用split("\n")按換行符分割,取第一部分作為導演和主演信息。

3.3.5 提取上映年份、國家 / 地區、類型
detail_text = info_text[1].strip() if len(info_text) > 1 else "未知 / 未知 / 未知"
detail_list = detail_text.split(" / ")
release_year = detail_list[0].strip() if len(detail_list) > 0 else "未知年份"
country = detail_list[1].strip() if len(detail_list) > 1 else "未知國家"
genre = detail_list[2].strip() if len(detail_list) > 2 else "未知類型"

這部分信息位于上一步中分割得到的info_text的第二部分,格式為 "年份 / 國家 / 地區 / 類型"。我們使用split(" / ")按 "/" 分割,得到一個包含三個元素的列表,分別對應年份、國家 / 地區和類型。

每個字段都添加了條件判斷,以處理可能的缺失情況,保證程序的穩定性。

3.3.6 提取電影簡介
quote_tag = item.find("span", class_="inq")
intro = quote_tag.get_text(strip=True) if quote_tag else "無簡介"

電影簡介位于class為 "inq" 的span標簽中。同樣添加了條件判斷,處理沒有簡介的情況。

3.3.7 存儲電影數據
movie_dict = {"電影名稱": movie_name,"評分": rating,"評價人數": comment_count,"導演&主演": director_actor,"上映年份": release_year,"國家/地區": country,"類型": genre,"簡介": intro
}
movie_list.append(movie_dict)

將提取到的各項信息存入一個字典,然后將字典添加到movie_list列表中。這樣處理后,movie_list將包含當前頁面所有電影的信息。

4. 數據清洗與保存

4.1 數據轉換
df = pd.DataFrame(movie_list)

使用 pandas 庫將列表轉換為 DataFrame,這是一種二維表格數據結構,便于進行數據處理和分析。

4.2 數據清洗
df["評價人數"] = pd.to_numeric(df["評價人數"].str.replace(".", ""), errors="coerce").fillna(0).astype(int)

這行代碼對 "評價人數" 進行清洗和轉換:

  • str.replace(".", ""):去除字符串中的小數點,處理 "123.4 萬" 這種格式
  • pd.to_numeric(..., errors="coerce"):將字符串轉換為數值類型,無法轉換的將設為 NaN
  • fillna(0):將 NaN 值替換為 0
  • astype(int):轉換為整數類型

經過這些處理,"評價人數" 字段將成為干凈的整數,便于后續的統計分析。

4.3 保存到 Excel
excel_path = "豆瓣電影Top250數據.xlsx"
df.to_excel(excel_path, index=False, engine="openpyxl")

使用 pandas 的to_excel方法將數據保存到 Excel 文件:

  • index=False:表示不保存 DataFrame 的索引列
  • engine="openpyxl":指定使用 openpyxl 庫作為引擎,支持.xlsx 格式

保存完成后,會打印保存路徑和爬取到的電影數量,方便用戶確認結果。

5. 主程序流程

if __name__ == "__main__":print("開始爬取豆瓣電影 Top250 數據...")crawl_douban_top250()  # 1. 爬取數據save_to_excel()        # 2. 保存數據print("爬取任務完成!")

這是程序的入口點,使用if __name__ == "__main__":確保只有在直接運行該腳本時才會執行以下代碼,而在被導入為模塊時不會執行。

五、運行結果與驗證

  1. 運行代碼:執行程序后,控制臺會輸出爬取進度(如 “正在爬取第 1 頁...”);
  2. 生成文件:程序結束后,當前目錄會生成?豆瓣電影Top250數據.xlsx?文件;
  3. 驗證數據:打開 Excel 文件,可看到 250 行數據(若部分頁面爬取失敗,行數可能少于 250),列包含 “電影名稱”“評分” 等 8 項信息,數據格式統一、無亂碼。

六、拓展與注意事項

1. 功能拓展

  • 多線程爬取:使用?threading?或?concurrent.futures?庫實現多線程,提升爬取速度(注意控制線程數,避免給服務器造成過大壓力);
  • 數據可視化:用?matplotlib?或?seaborn?繪制評分分布直方圖、類型占比餅圖等;
  • 增量爬取:記錄上次爬取的最后一部電影,下次只爬取更新的數據。

2. 注意事項

  • 遵守網站 robots 協議:豆瓣電影的?robots.txt(https://movie.douban.com/robots.txt)允許爬取 Top250 數據,但需控制頻率;
  • 反爬升級應對:若出現 “驗證碼” 或 “403 禁止訪問”,可嘗試添加?Cookie(模擬登錄狀態)、使用代理 IP 池;
  • 法律風險:不得將爬取的數據用于商業用途,遵守《網絡安全法》《數據安全法》等法律法規。

通過本案例,可掌握爬蟲的核心流程(請求→解析→清洗→保存),理解 HTML 結構分析、反爬規避、數據處理的關鍵技巧,為后續爬取更復雜網站(如動態加載、需要登錄的網站)打下基礎。

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

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

相關文章

SPA安全警示:OAuth2.0致命漏洞

OAuth2.0在SPA應用中的安全陷阱SPA&#xff08;單頁應用&#xff09;通常采用隱式授權&#xff08;Implicit Flow&#xff09;或PKCE&#xff08;Proof Key for Code Exchange&#xff09;授權模式&#xff0c;但存在以下安全隱患&#xff1a;隱式授權模式的漏洞訪問令牌直接暴…

table表格字段明細展示

文章目錄1、字段渲染2、異步請求展示明細3、hover展示問題3.1 基本邏輯3.2 hover時長判斷3.3 renderhover表格字段明細展示&#xff0c;屬于比較小的需求&#xff0c;但是也有一定交互細節&#xff0c;本文選取部分場景。 1、字段渲染 render和渲染組件是有區別的。render常見為…

主網上線后生態極速擴張的 Berachain 生態,有哪些值得關注的項目?

Berachain 是典型的將 DeFi 思維嵌入到共識機制中的 Layer1&#xff0c;其核心是 PoL&#xff08;Proof of Liquidity&#xff09;共識。PoL 要求驗證者在獲得區塊獎勵前&#xff0c;必須將流動性導入白名單協議&#xff0c;并由市場決定資金流向。這樣&#xff0c;驗證者的權重…

claude-code對比GitHub-Copilot

Claude Code 文檔日期&#xff1a;2025 年 08 月 20 日 定位 項目級開發助手&#xff0c;專注于全局視野和復雜任務的處理。 特點 超長上下文支持&#xff1a;支持 200k 超長上下文&#xff0c;適合處理復雜項目。豐富的自定義命令&#xff1a;提供靈活的命令配置&#xff0c;滿…

Roo Code自定義Mode(模式)

什么是自定義模式&#xff1f; 簡單來說&#xff0c;自定義模式就像是給Roo Code穿上不同的"職業裝"。你可以創建針對特定任務或工作流程量身定制的模式&#xff0c;讓Roo在不同場景下表現出專業的行為。 這些模式分為兩種類型&#xff1a;全局模式&#xff08;在所有…

Next.js渲染模式:SSR、SSG與ISR揭秘

Next.js 核心渲染模式深度解析&#xff1a;SSR、SSG 與 ISR 在構建現代 Web 應用時&#xff0c;性能和用戶體驗是至關重要的考量。Next.js 作為 React 生態中一個備受推崇的框架&#xff0c;其強大的服務端渲染&#xff08;SSR&#xff09;、靜態站點生成&#xff08;SSG&#…

Veo Videos Generation API 對接說明

本文介紹了如何對接 Veo Videos Generation API&#xff0c;通過輸入自定義參數生成Veo官方視頻。 下面將詳細闡述 Veo Videos Generation API 的對接流程。 申請流程 使用 API 前&#xff0c;需前往 Veo Videos Generation API 頁面申請服務。進入頁面后&#xff0c;點擊「…

YOLO 目標檢測:YOLOv3網絡結構、特征輸出、FPN、多尺度預測

文章目錄一、YOLOV31、網絡結構1.1 整體結構1.2 主干網絡1.3 特征輸出1.4 特征融合FPN&#xff08;Feature Pyramid Networks&#xff09;FPN 融合上采樣融合2、多尺度預測3、損失函數4、性能對比一、YOLOV3 YOLOv3&#xff08;You Only Look Once v3&#xff09;是YOLO系列中…

【GIS圖像處理】有哪些SOTA方法可以用于將1.5米分辨率遙感圖像超分辨率至0.8米精度的?

針對將1.5米分辨率遙感圖像超分辨率至0.8米的需求,當前主流方法可分為以下幾類,結合最新研究進展和實際應用場景,具體技術方案及SOTA方法如下: 一、基于Transformer的高效建模 1. Top-k標記選擇Transformer(TTST) 核心機制:通過動態選擇前k個關鍵標記(token),消除冗…

【電力電子】逆變器控制策略:PQ Droop下垂控制、電壓電流雙環控制與SPWM調制

逆變器中的 PQ Droop 控制。 1. PQ Droop 控制的定義 PQ Droop(有時也稱為功率下垂控制,Power Droop Control)是微電網、并聯系統或逆變器并網運行中常用的一種分布式功率控制方法。 P-Droop(有功下垂):通過調節逆變器輸出頻率與有功功率之間的關系實現功率分配。 Q-Dro…

【LeetCode 熱題 100】5. 最長回文子串——中心擴散法

Problem: 5. 最長回文子串 文章目錄整體思路完整代碼時空復雜度時間復雜度&#xff1a;O(N^2)空間復雜度&#xff1a;O(1)整體思路 這段代碼旨在解決經典的 “最長回文子串” (Longest Palindromic Substring) 問題。問題要求在一個給定的字符串 S 中&#xff0c;找到一個最長…

六、練習3:Gitee平臺操作

練習3&#xff1a;Gitee平臺操作 練習目標 掌握Gitee平臺的基本操作&#xff0c;包括創建倉庫、推送代碼、團隊協作等。 練習步驟 步驟1&#xff1a;Gitee賬號準備 訪問 gitee.com注冊賬號&#xff08;如果還沒有&#xff09;登錄Gitee 步驟2&#xff1a;配置SSH密鑰 # …

Git軟件版本控制

軟件版本控制作用&#xff1a;軟件源碼版本管理、多人協作開發、版本多分支開發、代碼回滾&#xff08;回退&#xff09;等功能。集中式版本控制&#xff1a;將代碼倉庫放在一臺服務器上&#xff0c;開發時要依賴這臺服務器。優點&#xff1a;簡單、方便管理、適合中小型項目缺…

生產環境Spark Structured Streaming實時數據處理應用實踐分享

生產環境Spark Structured Streaming實時數據處理應用實踐分享 一、業務場景描述 我們所在的電商平臺需要實時監控用戶行為數據&#xff08;如點擊、下單、支付等&#xff09;&#xff0c;基于事件級別的流式數據進行實時統計、會話聚合、漏斗分析&#xff0c;并將結果推送到Da…

海康相機開發---HCNetSDK

HCNetSDK&#xff08;Hikvision Network Software Development Kit&#xff09;是海康威視專為旗下安防監控設備打造的二次開發工具包&#xff0c;是連接上層應用與海康設備的核心橋梁。其封裝了設備底層通信協議&#xff08;包括私有協議與部分標準協議&#xff09;&#xff0…

構建無廣告私人圖書館Reader與cpolar讓電子書庫隨身攜帶

文章目錄前言&#xff1a;告別書荒&#xff0c;拯救靈魂的“摸魚神器”1、關于Reader&#xff1a;小而美的開源在線閱讀器2、Docker部署3、簡單使用reader和添加書源4.群暉安裝Cpolar工具5.創建reader閱讀器的公網地址6.配置固定公網地址前言&#xff1a;告別書荒&#xff0c;拯…

amd cpu是x86架構嗎

是的&#xff0c;AMD CPU屬于x86架構?&#xff0c;其64位擴展&#xff08;x86-64&#xff09;最初由AMD設計并成為行業標準。? ?AMD與x86架構的關系? ?技術淵源?&#xff1a;AMD自1976年起通過技術授權成為x86架構的合法制造商&#xff0c;與英特爾共同主導x86市場。2003…

vercel上線資源無法加載

背景&#xff1a;在本地跑開發服務器沒問題&#xff0c;但是部署到 vercel 上就有問題上一次出現類似問題是在更新游戲引擎方法后本地可以跑但是上線沒有成功&#xff0c;當時是因為 runner.html 是在部署時通過腳本從遠端倉庫拉取的&#xff0c;所以解決方案&#xff1a;1.更新…

Node.js 的模塊化規范是什么?CommonJS 和 ES6 模塊有什么區別?

目錄 一、為什么需要模塊化&#xff1f; 二、Node.js 的模塊化規范 三、CommonJS 模塊化 1. 基本語法 2. 特點 3. 缺點 四、ES6 模塊&#xff08;ESM&#xff09; 1. 基本語法 2. 特點 3. 在 Node.js 中的使用 五、CommonJS 和 ES6 模塊的區別 六、實際開發中的選擇…

設計模式:代理模式(Proxy Pattern)

文章目錄一、代理模式的定義二、實例分析三、示例代碼一、代理模式的定義 代理模式是一種結構型設計模式&#xff0c;它為某個對象提供一個代理或占位符&#xff0c;以控制對這個對象的訪問。簡單來說代理對象在客戶端和目標對象之間起到中介作用&#xff0c;客戶端并不會直接操…