AI 編程實踐:用 Trae 快速開發 HTML 貪吃蛇游戲

1. 背景與目標

貪吃蛇是最適合入門的 2D 網頁小游戲之一:規則簡單、反饋清晰、可擴展空間大(穿墻模式、道具、多食物、排行榜……)。

demo地址:https://game.haiyong.site/snake-game.html

在這里插入圖片描述

本項目的目標是:

  • 純前端、零依賴:一個 HTML 文件搞定(你提供的版本已內聯 CSS/JS;也可輕松拆分為三文件)。
  • 屏幕高清適配(DPR):在 1× 與 2× 屏幕上都不糊。
  • 多端輸入:鍵盤 + 觸控滑動 + 移動端虛擬方向鍵。
  • 基礎玩法完善:吃食物加分加速、不可 180° 反向、穿墻可切換。
  • 體驗細節:音效開關、本地最高分存檔、狀態燈、結束面板。
  • 架構清晰:有狀態機與時間驅動的主循環,易于擴展。

2. 需求拆解與技術選型

2.1 功能需求清單

  • 畫布區域:固定邏輯分辨率 600×600,基于 20×20 網格。
  • 信息面板:分數 / 最高分 / 運行狀態 / 難度選擇。
  • 控制面板:開始/暫停、重置、穿墻模式、音效開關。
  • 交互:鍵盤(方向 / 空格 / R)+ 觸控滑動 + 移動端虛擬方向鍵。
  • 玩法:吃食物 +10 分;每 50 分提速(下限 80ms/格);撞墻或撞自己 Game Over。
  • 存檔:最高分寫入 localStorage
  • 細節:狀態指示燈、結束模態、DPR 適配、觸控閾值、按鈕響應式布局。

2.2 技術棧

  • HTML5 Canvas:繪制網格、食物與蛇體。
  • CSS:控制面板與信息欄;移動端響應式。
  • JavaScript(原生):游戲循環、狀態機、事件綁定、碰撞檢測。
  • Web Audio API(可降級):吃食物與失敗音效。
  • localStorage:最高分記憶。

在這里插入圖片描述


3. 界面與樣式:把玩法信息「可視化」

你提供的 HTML 結構已經非常貼近上線形態:

  • .game-info 頂欄用來展示分數、最高分、狀態文本與狀態燈(.status-indicator)。
  • .game-controls 包含四個按鈕(開始/暫停、重置、穿墻模式、音效)。
  • .mobile-controls 中的 .touch-pad 是 3×3 網格,布局出 ↑ ← ↓ → 的虛擬鍵,僅在 <768px 時顯示。
  • .game-message 是結束/提示用的模態層,避免 alert 破壞體驗。

這里有幾個小亮點:

  1. 狀態燈
    僅用一個 running 類控制顏色(紅/綠)。與 statusText 文本聯動,能快速傳達狀態。

  2. 按鈕語義與可達性
    按鈕文本會隨狀態切換,例如「穿墻模式: 開/關」,讓用戶始終知道當前配置。

  3. 響應式體驗
    使用 @media (max-width: 768px) 切換移動端 UI,桌面端則隱藏虛擬方向。


4. 畫布與 DPR 適配:清晰不糊的關鍵

在高清屏幕上,Canvas 如果只設置 CSS 尺寸會模糊。正確做法是邏輯尺寸 + 像素尺寸分離

const dpr = window.devicePixelRatio || 1;
canvas.width = LOGICAL_WIDTH * dpr;   // 實際像素
canvas.height = LOGICAL_HEIGHT * dpr;
canvas.style.width = `${LOGICAL_WIDTH}px`;  // 邏輯尺寸(CSS)
canvas.style.height = `${LOGICAL_HEIGHT}px`;
ctx.scale(dpr, dpr); // 坐標系仍按邏輯尺寸繪制
  • LOGICAL_WIDTH=600 / GRID_SIZE=20CELL_SIZE=30
  • 在 2× 屏上,實際像素會是 1200×1200,但我們仍然用 600×600 的坐標系繪制,既清晰好算

5. 核心建模:網格、蛇、食物、狀態機

5.1 網格與單位

  • 網格 20×20,單位為格(cell);渲染時乘 CELL_SIZE 得到像素位置。
  • 你使用了淺色網格線(rgba(255,255,255,0.1))作為背景輔助,這是一個很實用的視覺調試手段。

5.2 蛇(Snake)

  • 用數組 snake 表示蛇,從 snake[0]snake[snake.length-1] 依次為頭到尾
  • 每個元素是 {x, y} 的格子坐標。
  • 移動:復制一份 head,根據方向 x±1y±1,再 unshift 到數組前端;如果沒吃到食物,pop() 尾巴(這就是“向前移動一格”的直覺實現)。

5.3 食物(Food)

  • generateFood() 隨機選格,循環重試直到不與蛇體重疊。
  • 對于極端情況(蛇很長快滿屏),這套策略也能靠多次抽樣找到空位;若要更保險,可加入最大重試次數 + 回退(例如掃描第一個空格)。

5.4 狀態機(Game State)

  • pausedrunninggameOver 三態。
  • 開始/暫停按鈕切換 paused ? running,Game Over 僅在碰撞時進入。
  • statusText + 狀態燈 + 按鈕文案 同步反饋當前狀態。

6. 主循環:requestAnimationFrame + Tick 節流

游戲循環由 requestAnimationFrame(drawGame) 驅動,但蛇的邏輯步進用固定 Tick 控制(tickInterval)。核心片段:

if (gameState === 'running') {if (!lastTickTime) lastTickTime = timestamp;const elapsed = timestamp - lastTickTime;if (elapsed >= tickInterval) {lastTickTime = timestamp;updateGame();canChangeDirection = true;}
}

兩個點特別關鍵:

  1. 時間驅動而不是幀驅動
    不同電腦的幀率差異很大,但我們希望“每 N 毫秒前進一格”,這就是“基于時間”的 Tick。

  2. canChangeDirection 防抖
    在一次邏輯步完成之前,禁止再次改向,避免一幀內多次按鍵導致“瞬間 180° 反向”的非法移動


7. 碰撞檢測:邊界與自身

7.1 撞墻

  • 非穿墻模式:只要 head.x/y 越界(<0 或 ≥GRID_SIZE)直接 gameOver()
  • 穿墻模式:越界則從另一側出現(如 x<0 → x=GRID_SIZE-1),讓玩家體驗更自由。

7.2 撞自己

  • 在把新頭 unshift 之前,先用一個循環與當前蛇身比較坐標,相等即 Game Over。
  • 這里的復雜度是 O(n),在 20×20 網格里瓶頸不明顯;如果擴展到大地圖,可以考慮用 Set(key = x#y)實現 O(1) 查詢。

8. 得分、提速與難度

  • 每吃一個食物 +10 分;每達到 50 分 的整數倍觸發 increaseSpeed()
  • increaseSpeed() 逐步把 tickInterval 每次減少 20ms,但不低于 80ms 的安全下限。
  • 下拉框設置初始難度(200/150/100ms),只影響起步速度,后續仍按分數加速。

這種“有限加速”的節奏設計能讓玩家感覺逐步緊張但不至于失控


9. 輸入系統:鍵盤 + 觸控滑動 + 虛擬方向鍵

9.1 鍵盤

  • 方向鍵與 WASD 等價;空格暫停/開始;R 重置。
  • 方向設置統一走 setDirection(newDirection),在此處封裝禁止 180°canChangeDirection 的邏輯,避免重復校驗。

9.2 觸控滑動

  • touchstart 記錄起點;touchend 計算 dx/dy,絕對值較大者代表滑動方向,并設置一個閾值(50px)過濾誤觸。
  • 移動端滑動比點擊按鈕更自然,尤其在全屏 Canvas 上。

9.3 虛擬方向鍵

  • <768px 顯示,由 3×3 網格排布四個方向按鈕構成。
  • 綁定 touchstart 即可,不爭搶 touchend,手感更靈敏。

小建議:如果想進一步提升移動端操控,可給虛擬方向鍵加入按下/抬起的視覺反饋(例如 scale(0.96) + 投影增強)。


10. 視聽與可達性:音效、狀態可見、模態反饋

10.1 Web Audio 小音效(可降級)

你用原生 Web Audio 生成了“吃到食物(sine,高音短促)”與“失敗(sawtooth,低音略長)”。優點是體積 0、無資源加載。
瀏覽器未授權或不支持時靜默降級,不會阻塞游戲。

10.2 狀態可視化

  • 文本 + 狀態燈(顏色切換)雙重反饋。
  • 開始/暫停 文案與狀態保持一致,減少認知負擔。
  • Game Over 用自定義模態層(非 alert),用戶體驗更柔和,還能在面板上放“重新開始”。

11. 存檔:localStorage 的最高分

  • 啟動時 loadHighScore() 讀取,Game Over 時 saveHighScore() 更新。
  • 只在分數超過歷史時寫入,避免無謂的存取。

進階:你可以把難度、穿墻、是否靜音也一并持久化,做到“偏好記憶”。


12. 性能與邊界:穩定運行的小技巧

  1. 標簽頁切換自動暫停
    當前版本在 visibilitychange 未處理。如果實現:

    • 不要在隱藏時繼續 RAF + Tick;主動暫停并在信息欄提示“已自動暫停”。

    參考代碼:

    document.addEventListener('visibilitychange', () => {if (document.hidden && gameState === 'running') {startPauseGame(); // 觸發暫停statusTextElement.textContent = '已自動暫停';}
    });
    
  2. Resize 的冪等性
    你在 resize 時調用 initGame(),這會重置蛇與分數。文案已有“適配新窗口”的注釋,但對玩家不友好。
    更好的做法是:僅重配畫布與縮放,不改動游戲狀態與數據:

    function resizeCanvasOnly() {const dpr = window.devicePixelRatio || 1;ctx.setTransform(1, 0, 0, 1, 0, 0); // 重置 transformcanvas.width = LOGICAL_WIDTH * dpr;canvas.height = LOGICAL_HEIGHT * dpr;canvas.style.width = `${LOGICAL_WIDTH}px`;canvas.style.height = `${LOGICAL_HEIGHT}px`;ctx.scale(dpr, dpr);
    }
    window.addEventListener('resize', resizeCanvasOnly);
    
  3. 自碰撞的優化
    當前 O(n) 遍歷在 20×20 內完全足夠。若你把地圖放大,可用 Setx#y 哈希來 O(1) 查詢。

  4. 渲染順序與清屏
    你已正確使用 clearRect + “網格→食物→蛇”的順序。若加粒子特效,注意在蛇之后繪制,保證覆蓋關系。


13. 常見 Bug 與排查清單

  • 按住按鍵快速抖動,蛇突然反向?
    確認 canChangeDirection 是否只在 updateGame() 后釋放;不要在 keydown 處反復釋放。

  • 移動端滑動不生效或誤觸嚴重?
    檢查 touchstart/touchend.preventDefault() 是否設置;增大滑動閾值(如 70px);避免與頁面滾動沖突(Canvas 容器設置 touch-action: none)。

  • DPR 下線條斷裂或模糊?
    使用偶數像素或對半像素線進行偏移(本項目用淺色網格,影響不大)。

  • 最高分沒有保存?
    確認瀏覽器隱私模式下 localStorage 是否可用;或被跨域頁面嵌套導致安全限制。


14. 可擴展清單(附思路與實現要點)

14.1 反彈墻模式(Bumper)

  • 玩法:撞墻不死,方向向內反彈(左右墻翻轉 dx,上下墻翻轉 dy),但扣 1 分或扣生命。
  • 實現:把越界處的判斷從 gameOver() 改為反向修正,同時加一個 livesscore--

14.2 多食物與特殊物品

  • 普通食物:+10 分;
  • 金色食物:限時出現,+30 分,吃到播放不同音效;
  • 毒蘋果:吃到減速或扣分;
  • 實現:維護食物數組與 type 字段,渲染時區分顏色與大小。

14.3 關卡與任務

  • 目標:在 60 秒內達到 200 分;
  • 限制:禁止穿墻、限定初始難度;
  • 獎勵:關卡完成后解鎖皮膚或粒子特效。

14.4 皮膚與主題

  • 預置主題對象:

    const themes = {classic: { bg:'#000', snake:'#4CAF50', head:'#FFC107', food:'#F44336' },neon:    { bg:'#0a0a0a', snake:'#00e5ff', head:'#b388ff', food:'#ff6e40' },
    };
    
  • 在渲染函數里用主題色,配合下拉或按鈕切換。

14.5 錄像與回放(Ghost)

  • 記錄每個 Tick 的方向與食物坐標,生成“幽靈蛇”數據。
  • 回放時在同一張地圖重放路徑,玩家可挑戰自己最佳路線。

15. 關鍵代碼走讀與講解

下面選取幾個代表性的代碼片段做解構說明(與原代碼保持一致/等價),幫助你在文章或講座里逐步帶讀。

15.1 初始化與重置

function initGame() {const dpr = window.devicePixelRatio || 1;canvas.width = LOGICAL_WIDTH * dpr;canvas.height = LOGICAL_HEIGHT * dpr;canvas.style.width = `${LOGICAL_WIDTH}px`;canvas.style.height = `${LOGICAL_HEIGHT}px`;ctx.scale(dpr, dpr);loadHighScore();resetGame();
}function resetGame() {snake = [];for (let i = INITIAL_SNAKE_LENGTH - 1; i >= 0; i--) {snake.push({ x: i, y: Math.floor(GRID_SIZE / 2) });}direction = nextDirection = 'right';generateFood();score = 0;updateScore();gameState = 'paused';statusTextElement.textContent = '已暫停';statusIndicatorElement.classList.remove('running');startPauseBtn.textContent = '開始';setDifficulty(difficultySelectElement.value);gameMessage.style.display = 'none';drawGame(); // 先繪一幀靜態畫面
}

解讀

  • snake 從中線開始,向右排 3 格;
  • 先繪制一幀靜態畫面,再等待開始指令;
  • 所有 UI 狀態(文本、指示燈、按鈕)與 gameState 一致,是“緊耦合”的必要同步

15.2 更新一步(游戲邏輯)

function updateGame() {direction = nextDirection;         // 只在 Tick 邊界切換方向const head = { ...snake[0] };      // 拷貝頭部switch (direction) {case 'up': head.y -= 1; break;case 'down': head.y += 1; break;case 'left': head.x -= 1; break;case 'right': head.x += 1; break;}if (!wallThroughMode) {if (head.x < 0 || head.x >= GRID_SIZE || head.y < 0 || head.y >= GRID_SIZE) {gameOver(); return;}} else {if (head.x < 0) head.x = GRID_SIZE - 1;else if (head.x >= GRID_SIZE) head.x = 0;if (head.y < 0) head.y = GRID_SIZE - 1;else if (head.y >= GRID_SIZE) head.y = 0;}for (let segment of snake) {if (segment.x === head.x && segment.y === head.y) {gameOver(); return;}}snake.unshift(head);if (head.x === food.x && head.y === food.y) {score += 10;updateScore();playSound('eat');generateFood();if (score % SCORE_THRESHOLD === 0) increaseSpeed();} else {snake.pop();}
}

解讀

  • 方向的延遲生效(Tick 邊界切換)配合 canChangeDirection,保證沒有“同幀多次拐彎”的競態。
  • 穿墻與越界死亡兩個分支互斥,邏輯清晰;
  • “吃到食物”才增長,否則移除尾巴維持長度不變。

15.3 觸控滑動的方向判定

canvas.addEventListener('touchend', (e) => {if (gameState === 'gameOver') return;e.preventDefault();if (!touchStartX || !touchStartY) return;const touch = e.changedTouches[0];const dx = touch.clientX - touchStartX;const dy = touch.clientY - touchStartY;if (Math.abs(dx) > Math.abs(dy)) {if (dx > 50) setDirection('right');else if (dx < -50) setDirection('left');} else {if (dy > 50) setDirection('down');else if (dy < -50) setDirection('up');}touchStartX = 0;touchStartY = 0;
});

解讀

  • 方向由主軸位移決定(橫向或縱向);
  • 50px 閾值過濾輕微滑動;
  • preventDefault() 避免瀏覽器把滑動當滾動處理。

16. 代碼打磨:兩處值得改進的小細節

  1. 音頻上下文復用
    每次 playSound 都創建 AudioContext 成本較高,且部分瀏覽器限制實例數量。可以外部維護一個惰性單例:

    let audioCtx;
    function getAudioCtx() {if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();return audioCtx;
    }
    function playSound(type) {if (!soundEnabled) return;try {const audioContext = getAudioCtx();const osc = audioContext.createOscillator();const gain = audioContext.createGain();osc.connect(gain); gain.connect(audioContext.destination);// ...同原邏輯} catch (e) { /* 靜默 */ }
    }
    
  2. 重繪請求的冪等性
    drawGame() 內部會 requestAnimationFrame(drawGame),啟動時你又在 start() 調了 drawGame() 一次是對的,但要避免重復綁定導致多重 RAF(當前代碼沒問題,因為調用鏈單一)。如果以后抽取模塊,注意只在唯一入口里開始 RAF。

總結

把這套工程化骨架掌握住,你基本就擁有了前端小游戲的“模板思維”

  • 數據結構先行(網格→蛇→食物);
  • 狀態機護航(paused/running/gameOver);
  • 時間驅動循環(Tick 節流);
  • 交互合流(鍵盤/觸控/虛擬鍵統一到 setDirection);
  • 體驗閉環(狀態燈/模態/音效/存檔);
  • 漸進增強(DPR/移動端)。

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

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

相關文章

FreeRTOS-C語言指針筆記

文章目錄一級指針指針基本概念指針使用示例代碼說明二、二級指針二級指針重點解析一級指針 C語言中的指針是一個非常重要的概念&#xff0c;它存儲了變量的內存地址。指針的使用可以使程序更加高效&#xff0c;尤其在處理數組、字符串和動態內存分配時。 指針基本概念 指針變…

界面布局智能建議生成:從功能需求到專業UI的AI加速之路

內容簡介: 傳統界面設計讓產品經理陷入"不懂設計、等設計師"的困境&#xff0c;效率低下還容易被挑刺。本文深度解析DeepSeek驅動的界面布局智能生成技術&#xff0c;通過DESIGN框架提示詞模板&#xff0c;讓產品經理在30分鐘內生成3種專業級界面方案&#xff0c;實現…

【BLE系列-第三篇】數據鏈路層(LL):廣播/連接/掃描流程詳解

目錄 引言 一、廣播及連接建立 1.1 廣播類型 1.2 掃描/連接請求與響應 1.2.1 廣播流程說明 1.2.1.1 廣播流程示例圖 1.2.1.2 廣播信息設置 1.2.1.3 信道廣播 1.2.1.4 信道切換 1.2.1.5 廣播間隔 1.2.1.6 接收窗口與理論最小傳輸時間 1.2.2 掃描/連接流程說明 1.2.…

JMeter 測試 WebSocket 接口的詳細教程

1. 安裝 WebSocket 插件 方法一&#xff1a;通過 Plugins Manager 下載并安裝 JMeter Plugins Manager在 JMeter 中&#xff1a;Options → Plugins Manager搜索 WebSocket 并安裝 方法二&#xff1a;手動安裝 下載 jmeter-websocket-samplers 插件將 jar 文件放到 JMeter/…

飛算JavaAI智慧教育場景實踐:從個性化學習到教學管理的全鏈路技術革新

目錄一、智慧教育核心場景的技術突破1.1 個性化學習路徑推薦系統1.1.1 學習者能力建模與評估1.2 智能教學管理系統1.2.1 自動化作業批改與學情分析1.3 教育資源智能管理系統1.3.1 教育資源智能標簽與推薦二、智慧教育系統效能升級實踐2.1 教育數據中臺構建2.1.1 教育數據整合與…

Java面試場景題大全精簡版

1.分布式系統下如何實現服務限流核心算法&#xff1a;固定窗口&#xff1a;將時間劃分為固定窗口&#xff08;如 1 秒&#xff09;&#xff0c;統計窗口內請求數&#xff0c;超過閾值則限流。實現簡單但存在臨界值突發流量問題。滑動窗口&#xff1a;將固定窗口拆分為多個小窗口…

紅帽 AI 推理服務 (vLLM) - 入門篇

《教程匯總》 RedHat AI Inference Server 和 vLLM vLLM (Virtual Large Language Model) 是一款專為大語言模型推理加速而設計的框架。它是由加州大學伯克利分校 (UC Berkeley) 的研究團隊于 2023 年開源的項目&#xff0c;目前 UC Berkeley 和 RedHat 分別是 vLLM 開源社區…

Sql server 命令行和控制臺使用二三事

近來遇到了幾件關于sql server的事情。 第一&#xff1a;低版本sqlserver備份竟然無法還原到高版本 奇怪&#xff01;從來未碰到過。過程如下&#xff1a; 1.在低版本上中備份好了數據庫 2.通過共享將文件拷貝到新服務器上 3.打開控制臺&#xff0c;還原數據庫&#xff0c;結果…

vue excel轉json功能 xlsx

需求&#xff1a; 完成excel表格內容轉json&#xff0c;excel表格內可能存在多個表格&#xff0c;要求全部解析出來。完成表格內合服功能&#xff0c;即&#xff1a;提取表格內老服務器與新服務器數據&#xff0c;多臺老服務器對應合并到一臺新服務器上 3.最終輸出結果為:[{‘1…

Qwen-OCR:開源OCR技術的演進與全面分析

目錄 一、Qwen-OCR的歷史與發展 1.1 起源與早期發展(2018-2020) 1.2 技術突破期(2020-2022) 1.3 開源與生態建設(2022至今) 二、技術競品分析 2.1 國際主流OCR解決方案對比 2.2 國內競品分析 三、部署需求與技術規格 3.1 硬件需求 3.2 軟件依賴 3.3 云部署方案 四、…

可視化+自動化:招聘管理看板軟件的核心技術架構解析

引言&#xff1a;現代招聘的挑戰與轉型隨著全球化和科技的迅速發展&#xff0c;企業的人力資源管理面臨著前所未有的挑戰。尤其是在招聘環節&#xff0c;隨著人才市場的競爭日益激烈&#xff0c;企業必須在確保招聘質量的同時&#xff0c;提升招聘效率。這不僅要求招聘人員具備…

【數據結構】——棧(Stack)的原理與實現

目錄一. 棧的認識1. 棧的基本概念2.棧的基本操作二. 棧的核心優勢1. 高效的時間復雜度2. 簡潔的邏輯設計3. 內存管理優化三. 棧的代碼實現1.棧的結構定義2. 棧的初始化3. 入棧 &#xff08;動態擴容&#xff09;4. 出棧5. 取棧頂數據6. 判斷棧是否為空7. 獲取棧的數據個數8.銷毀…

使用TexLive與VScode排版論文

前言 中文稿目前已經完成了&#xff0c;現在要轉用latex排版&#xff0c;但我對這方面沒有接觸過&#xff0c;這里做一個記錄。 網頁版Overleaf&#xff1a;Overleaf, 在線LaTeX編輯器。 TeXWorks&#xff1a;論文神器teXWorks安裝與使用記錄。 這里我還是決定采用Vscode作…

每日一題:2的冪數組中查詢范圍內的乘積;快速冪算法

題目選自2438. 二的冪數組中查詢范圍內的乘積 還是一樣的&#xff0c;先講解思路&#xff0c;然后再說代碼。 題目有一定難度&#xff0c;所以我要爭取使所有人都能看懂&#xff0c;用的方法會用最常規的思想。關于語言&#xff0c;都是互通的&#xff0c;只要你懂了一門語言…

Ceph數據副本機制詳解

Ceph 數據副本機制詳解 Ceph 的數據副本機制是其保證數據可靠性和高可用性的核心設計&#xff0c;主要通過多副本&#xff08;Replication&#xff09; 和 糾刪碼&#xff08;Erasure Coding&#xff0c;EC&#xff09; 兩種方式實現。以下是對 Ceph 數據副本機制的全面解析&am…

【八股】Mysql中小廠八股

MySQL 基礎 數據庫三大范式&#xff08;中&#xff09; 第一范式: 要求數據庫表的每一列都是不可分割的原子數據項 如詳細地址可以分割為省市區等. 第二范式: 非主鍵屬性必須完全依賴于主鍵, 不能部分依賴 第二范式要確保數據庫表中的每一列都和主鍵相關, 而不能只與主鍵的某一…

怎么使用python查看網頁源代碼

使用python查看網頁源代碼的方法&#xff1a;1、使用“import”命令導入requests包import requests2、使用該包的get()方法&#xff0c;將要查看的網頁鏈接傳遞進去&#xff0c;結果賦給變量xx requests.get(urlhttp://www.hao123.com)3、用“print (x.text)”語句把網頁的內容…

C# 多線程:并發編程的原理與實踐

深入探討 C# 多線程&#xff1a;并發編程的原理與實踐引言在現代應用開發中&#xff0c;性能和響應速度往往決定了用戶體驗的優劣。尤其在計算密集型或者IO密集型任務中&#xff0c;傳統的單線程模型可能無法有效利用多核CPU的優勢。因此&#xff0c;多線程技術成為了解決這些問…

react 常用組件庫

1. Ant Design&#xff08;螞蟻設計&#xff09;特點&#xff1a;國內最流行的企業級 UI 組件庫之一&#xff0c;基于「中后臺設計體系」&#xff0c;組件豐富&#xff08;表單、表格、彈窗、導航等&#xff09;、設計規范統一&#xff0c;支持主題定制和國際化。適用場景&…

Python 爬蟲獲取淘寶商品信息、價格及主圖的實戰指南

在電商數據分析、競品調研或商品信息采集等場景中&#xff0c;獲取淘寶商品的詳細信息&#xff08;如價格、主圖等&#xff09;是常見的需求。雖然淘寶開放平臺提供了官方的 API 接口&#xff0c;但使用這些接口需要一定的開發和配置工作。本文將通過 Python 爬蟲的方式&#x…