我的知识记录

Python抓取网页链接批量提取:正则与BeautifulSoup两种方案

讲解用BeautifulSoup和正则两种方式从网页中提取所有超链接,过滤外链和无效链接,去重后导出成CSV清单,适合做站点地图、链接巡检。

场景痛点

手上有一个网站想整理出所有内部链接,或者检查死链、整理文章列表。手动浏览一个个复制URL太慢,用程序把页面里所有 <a href> 都抽出来,自动补全相对路径、去重、导出成清单,几十秒就能跑完一个页面。

用到的库

pip install requests beautifulsoup4 lxml

完整代码

# 导入库
import csv
from urllib.parse import urljoin, urlparse
import requests
from bs4 import BeautifulSoup

def extract_links(url):
"""用BeautifulSoup提取页面所有链接"""
headers = {
"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36"),
}
resp = requests.get(url, headers=headers, timeout=10)
resp.encoding = resp.apparent_encoding

soup = BeautifulSoup(resp.text, "lxml")

links = []
for a in soup.find_all("a", href=True):
href = a["href"].strip()
# 跳过空链接和javascript伪协议
if not href or href.startswith("javascript:") or href == "#":
continue
# 相对路径转绝对路径
absolute = urljoin(url, href)
# 只保留http/https链接
parsed = urlparse(absolute)
if parsed.scheme not in ("http", "https"):
continue
# 锚点去掉
absolute = absolute.split("#")[0]
text = a.get_text(strip=True)[:50]
links.append((absolute, text))

# 按URL去重
unique = list(dict.fromkeys(links))
return unique

def extract_links_regex(url):
"""用正则方式提取(备选方案)"""
import re
headers = {"User-Agent": "Mozilla/5.0 Chrome/124.0.0.0"}
resp = requests.get(url, headers=headers, timeout=10)
pattern = re.compile(r'href=["\']([^"\']+)["\']')
return pattern.findall(resp.text)

def main():
url = "https://example.com"
try:
links = extract_links(url)
print(f"共提取 {len(links)} 个去重链接")
for href, text in links[:10]:
print(f"  {text or '(无文字)'}  ->  {href}")

# 存成CSV
with open("links.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.writer(f)
writer.writerow(["链接", "锚文字"])
writer.writerows(links)
print("已保存到 links.csv")

except Exception as e:
print("出错:", e)

if __name__ == "__main__":
main()

代码讲解

  • 主方案用BeautifulSoup:soup.find_all("a", href=True) 找到所有带href属性的 <a> 标签,比正则解析HTML可靠得多。
  • urljoin(base_url, href) 把相对路径(比如 /article/1.html)补全成绝对URL(https://xxx.com/article/1.html),这是新手最容易漏掉的一步。
  • urlparse 解析URL结构,过滤掉 mailto:tel: 这种非网页链接。
  • 去掉 #锚点 部分,避免同一个页面因为锚点不同被当成多条链接。
  • dict.fromkeys(links) 利用字典key唯一的特性去重,比手动写set保持顺序更优雅。
  • 备选方案用正则 href=["\']([^"\']+)["\'],简单粗暴但容错差,遇到畸形HTML容易漏,推荐用BeautifulSoup。

运行结果

运行后控制台打印提取到的链接总数和前10条(显示锚文字和URL),当前目录生成 links.csv,两列:链接、锚文字。

注意事项

  • 一个页面的链接可能有几百条,先去重再导出,不然清单没法看。
  • 提取链接后通常还要做二次过滤:只保留同域名内部链接,去掉外部广告链接。
  • 如果要抓整站链接,需要把抓到的链接放进队列继续爬,做广度优先遍历,同时记录已访问避免死循环。
  • 正则方案只适合简单页面,生产环境用BeautifulSoup。

Python抓取网页链接批量提取:正则与BeautifulSoup两种方案

标签:

更新时间:2026-09-14 20:46:11

上一篇:Python 开机自启脚本设置:Windows 启动项与 Linux systemd

下一篇:Python requests伪装User-Agent反爬:随机切换与Headers池