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。

更新时间:2026-09-14 20:46:11
上一篇:Python 开机自启脚本设置:Windows 启动项与 Linux systemd