上打不開/排版亂“的頁面)
目錄引言核心概念代碼示例總結(jié)2026年用Python檢測移動端適配SEO問題一鍵掃出手機(jī)上打不開/排版亂的頁面谷歌從 2019 年起就是移動優(yōu)先索引mobile-first indexing它用手機(jī)版判斷排名不是桌面版。你的網(wǎng)站桌面端再漂亮手機(jī)端如果字體小到看不清、按鈕點(diǎn)不準(zhǔn)、還要左右橫滑——谷歌直接給你降權(quán)。本文給一套可運(yùn)行的 Python 工具批量掃出全站移動端適配問題附修復(fù)建議和超鏈接。一、為什么 2026 年還得死磕移動端移動優(yōu)先索引已全覆蓋谷歌主要用移動版內(nèi)容做抓取、索引和排名。移動端 Core Web Vitals 是硬指標(biāo)LCP / INP / CLS 以移動端真實(shí)字段數(shù)據(jù)CrUX p75為準(zhǔn)桌面過了沒用。移動友好測試工具已下線2024 年后官方現(xiàn)在讓你用GSC 移動易用性報告 PageSpeed Insights自查——但這兩個都只能逐頁看沒法批量掃全站。所以自己寫腳本批量掃是獨(dú)立站/SEO 團(tuán)隊的必備動作。二、移動端適配到底查什么Google 歷史判分維度檢查項(xiàng)問題表現(xiàn)后果viewport 配置缺widthdevice-width手機(jī)按桌面寬度渲染字小需縮放字號過小 12px或過小固定值可讀性差易判移動不友好點(diǎn)擊目標(biāo)太小/太密按鈕 48×48 CSS px 或間距不足誤觸體驗(yàn)差橫向溢出內(nèi)容寬于視口需橫滑直接判定內(nèi)容不適配插件依賴Flash / 舊 object移動端無法運(yùn)行錯誤移動跳轉(zhuǎn)relalternate mediaonly screen配錯手機(jī)用戶被導(dǎo)到錯誤頁圖片尺寸缺失img無 width/height/srcset布局抖動CLS↑三、工具mobile_seo_checker.py純requests bs4無需 API key本地即跑。靜態(tài)層能覆蓋 80% 問題需要真實(shí)布局測量字號/點(diǎn)擊目標(biāo)實(shí)測的文末給 Playwright 進(jìn)階版。#!/usr/bin/env python3# mobile_seo_checker.py# 批量檢測全站移動端適配問題靜態(tài)啟發(fā)式版importcsvimportsysimportrequestsfrombs4importBeautifulSoupfromurllib.parseimporturljoin,urlparse MOBILE_UA(Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Mobile Safari/537.36)# 移動端 UA 頭模擬手機(jī)抓取HEADERS{User-Agent:MOBILE_UA}classMobileSEOChecker:def__init__(self,start_url,max_pages50):self.startstart_url self.domainurlparse(start_url).netloc self.max_pagesmax_pages self.visitedset()self.results[]# 每條: (url, [issues])def_is_internal(self,url):returnurlparse(url).netlocself.domaindef_fetch(self,url):try:rrequests.get(url,headersHEADERS,timeout10)ifr.status_code200andtext/htmlinr.headers.get(Content-Type,):returnr.textexceptExceptionase:returnNonereturnNonedef_check_html(self,url,html):soupBeautifulSoup(html,html.parser)issues[]# 1. viewport 配置vpsoup.find(meta,attrs{name:viewport})ifnotvporwidthdevice-widthnotin(vp.get(content)or).lower():issues.append(缺少/錯誤 viewport應(yīng)含 widthdevice-width)# 2. 插件依賴Flash/舊 object/embedifsoup.find(embed)orsoup.find(object)orsoup.find(param):issues.append(檢測到 embed/object可能為插件依賴移動端慎兼容)# 3. 錯誤移動跳轉(zhuǎn)relalternate mediaonly screen 但指向不同頁forlinkinsoup.find_all(link,relalternate):media(link.get(media)or).lower()ifonly screeninmediaandmax-widthinmedia:issues.append(存在 relalternate media 移動跳轉(zhuǎn)需確認(rèn)目標(biāo)正確)# 4. 內(nèi)聯(lián)樣式里的小字號啟發(fā)式small_font_hits0fortaginsoup.find_all(styleTrue):styletag.get(style,).lower()fortokeninstyle.split(;):tokentoken.strip()iftoken.startswith(font-size):num.join(chforchintokenifch.isdigit())ifnumandint(num)12andpxintoken:small_font_hits1ifsmall_font_hits:issues.append(f發(fā)現(xiàn){small_font_hits}處內(nèi)聯(lián)字號 12px可讀性風(fēng)險)# 5. 圖片缺尺寸CLS 風(fēng)險imgssoup.find_all(img)no_size0forimginimgs:ifnotimg.get(width)andnotimg.get(height)andnotimg.get(srcset):no_size1ifno_size:issues.append(f{no_size}/{len(imgs)}張圖片缺 width/height/srcset布局抖動風(fēng)險)# 6. 橫向溢出無法靜態(tài)判定真實(shí)寬度提示用真實(shí)瀏覽器復(fù)核returnissuesdefcrawl(self):queue[self.start]whilequeueandlen(self.visited)self.max_pages:urlqueue.pop(0)ifurlinself.visited:continueself.visited.add(url)htmlself._fetch(url)ifnothtml:continueissuesself._check_html(url,html)self.results.append((url,issues))# 收集內(nèi)鏈繼續(xù)爬soupBeautifulSoup(html,html.parser)forainsoup.find_all(a,hrefTrue):next_urlurljoin(url,a[href])ifself._is_internal(next_url)andnext_urlnotinself.visited:queue.append(next_url)defexport(self,pathmobile_seo_issues.csv):withopen(path,w,newline,encodingutf-8-sig)asf:wcsv.writer(f)w.writerow([URL,問題數(shù),問題明細(xì)])forurl,issuesinself.results:w.writerow([url,len(issues), | .join(issues)ifissueselseOK])print(f已導(dǎo)出{path}共檢測{len(self.results)}個頁面)if__name____main__:targetsys.argv[1]iflen(sys.argv)1elsehttps://example.comcheckerMobileSEOChecker(target,max_pages50)checker.crawl()checker.export()# 打印有問題的頁面bad[(u,i)foru,iinchecker.resultsifi]print(f\n發(fā)現(xiàn){len(bad)}個頁面存在移動端適配問題)foru,iinbad:print(f{u}\n - \n - .join(i))運(yùn)行示例python mobile_seo_checker.py https://你的獨(dú)立站.com輸出示意發(fā)現(xiàn) 7 個頁面存在移動端適配問題 https://site.com/product/a - 缺少/錯誤 viewport應(yīng)含 widthdevice-width - 12/15 張圖片缺 width/height/srcset布局抖動風(fēng)險 https://site.com/blog/old-post - 發(fā)現(xiàn) 3 處內(nèi)聯(lián)字號 12px可讀性風(fēng)險導(dǎo)出的mobile_seo_issues.csv可直接交給開發(fā)排期修復(fù)。四、靜態(tài)檢測不夠上真實(shí)瀏覽器Playwright 進(jìn)階版字號大小、點(diǎn)擊目標(biāo)間距、橫向溢出必須真實(shí)渲染才能測準(zhǔn)。下面用 Playwright 量真實(shí)布局# mobile_seo_real.py需 pip install playwright playwright install chromiumfromplaywright.sync_apiimportsync_playwright MOBILE{viewport:{width:390,height:844},# iPhone 12 邏輯分辨率is_mobile:True,has_touch:True,user_agent:Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15}defaudit(url):withsync_playwright()asp:bp.chromium.launch()pgb.new_page(**MOBILE)pg.goto(url,wait_untilnetworkidle)# 橫向溢出文檔寬 視口寬overflowpg.evaluate(document.documentElement.scrollWidth window.innerWidth)# 點(diǎn)擊目標(biāo)找過小的可點(diǎn)元素small_targetspg.evaluate(() { const els [...document.querySelectorAll(a,button)]; return els.filter(e { const r e.getBoundingClientRect(); return (r.width0 r.height0) (r.width48 || r.height48); }).length; })print(f{url}: 橫向溢出{overflow}, 過小點(diǎn)擊目標(biāo){small_targets}個)b.close()audit(https://你的站.com/product/a)把它套進(jìn)上面的MobileSEOChecker就能做全站真實(shí)渲染體檢。五、修復(fù)動作表交給開發(fā)直接抄問題修復(fù)缺 viewportmeta nameviewport contentwidthdevice-width, initial-scale1字號小正文 ≥ 16px最小可點(diǎn)文字 ≥ 12px點(diǎn)擊目標(biāo)小按鈕/鏈接 ≥ 48×48 CSS px間距 ≥ 8px橫向溢出用響應(yīng)式布局圖片max-width:100%圖片缺尺寸加width/height屬性或用aspect-ratio占位插件依賴用 HTML5/CSS 替代 Flash六、權(quán)威參考自查與提交Google移動優(yōu)先索引Google Search Central移動易用性問題web.dev響應(yīng)式設(shè)計基礎(chǔ)web.dev點(diǎn)擊目標(biāo)尺寸MDNviewport meta 標(biāo)簽PageSpeed Insights測移動端 CWV七、總結(jié)移動端適配不是錦上添花是 2026 年谷歌排名的入場券。后臺測試工具下線后批量自測成了剛需——上面這套腳本靜態(tài)層免費(fèi)掃全站Playwright 層量真實(shí)體驗(yàn)足夠你每月做一次移動端體檢。本文工具來自公眾號「全域SEO增長」更多 SEO/GEO 實(shí)戰(zhàn)腳本持續(xù)更新想交流具體站點(diǎn)問題歡迎在 CSDN 評論區(qū)或私信找我。更多實(shí)戰(zhàn)工具合集請看我的 CSDN 專欄。