本文示範如何使用 Python BeautifulSoup 解析 HTML,提取指定網域下的所有內部連結,並檢查連結有效性(HTTP 狀態碼)。適用於網站地圖生成、死連結檢測、爬蟲入口收集等場景。
from bs4 import BeautifulSoup
import urllib2
import time
def scan_page(base_url):
visited = set()
to_visit = {base_url}
results = []
while to_visit:
url = to_visit.pop()
if url in visited:
continue
visited.add(url)
try:
html = urllib2.urlopen(url, timeout=10).read()
except Exception as e:
print(f"[連線失敗] {url}: {e}")
results.append((url, 'CONNECT_FAILED'))
continue
soup = BeautifulSoup(html, 'html.parser')
for link in soup.find_all('a', href=True):
href = link['href']
# 簡易判斷內部連結:屬於同網域且非錨點、非外部
if href.startswith(base_url) and href not in visited and href not in to_visit:
to_visit.add(href)
# 檢查當前頁面狀態碼
try:
status = urllib2.urlopen(url).getcode()
results.append((url, status))
print(f"[OK] {url} -> {status}")
except Exception as e:
results.append((url, f'ERROR: {e}'))
print(f"[ERROR] {url}: {e}")
time.sleep(0.5) # 禮貌延遲
return results
if __name__ == '__main__':
start = time.time()
res = scan_page("https://news.163.com/")
print(f"\n共檢查 {len(res)} 個連結,耗時 {time.time()-start:.2f} 秒")
# 可選:輸出至 CSV
import csv
with open('links_report.csv', 'wb') as f:
writer = csv.writer(f)
writer.writerow(['URL', 'Status'])
writer.writerows(res)
visited 集合記錄已處理 URL,to_visit 集合管理待處理隊列,避免重複請求與無限迴圈。href.startswith(base_url) 簡易判斷,實際專案建議使用 urlparse 比對 netloc(網域),並處理相對路徑(urljoin)。try/except 捕獲超時、DNS 失敗、HTTP 錯誤等。time.sleep 避免對目標伺服器造成過大壓力,並遵守 robots.txt。concurrent.futures 或 aiohttp 大幅提升掃描速度。visited、to_visit 序列化至磁碟,支援中斷後繼續。pandas、matplotlib 產生狀態碼分佈圖、回應時間熱力圖。pip install beautifulsoup4
# Python 2 使用 urllib2,Python 3 請改用 urllib.request
BeautifulSoup 配合 urllib 提供了極簡潔的網頁解析與連結提取能力。配合合理的去重、異常處理與禮貌策略,即可構建實用的站內連結掃描工具。