You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Python递归提取网站href链接时重复且不全的问题?

网站递归爬取href链接的问题修复方案

原程序核心问题

  1. 正则匹配局限性:仅适配href="格式的链接,未兼容单引号、无引号的href写法,且直接对bytes类型内容做正则匹配,易出现编码异常。
  2. 已爬链接无全局记录:links_list是crawl函数的局部变量,每次递归都会重新初始化,无法追踪已爬取内容,导致重复爬取或遗漏链接。
  3. 域名判断逻辑过严:if url in link的判断会漏掉同一域名下、但路径不包含完整target_url的子页面链接。
  4. 无异常处理机制:请求失败时直接抛出异常,中断整个爬取流程。

修复后代码实现

import requests
import urllib.parse as urlparse
import re
from urllib.parse import urlsplit

# 全局集合存储已爬链接,查询效率优于列表
crawled_links = set()

def extract_links_from(url):
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()  # 抛出HTTP错误状态码异常
        content = response.text
        # 匹配双引号/单引号包裹的href值,兼容常见写法
        links = re.findall(r'href=(["\'])(.*?)\1', content, re.IGNORECASE)
        # 提取链接部分,过滤引号
        return [link[1] for link in links]
    except requests.exceptions.RequestException as e:
        print(f"请求{url}失败: {str(e)}")
        return []

def crawl(url):
    target_domain = urlsplit(target_url).netloc
    
    if url in crawled_links:
        return
    crawled_links.add(url)
    print(url)
    
    href_links = extract_links_from(url)
    for link in href_links:
        full_link = urlparse.urljoin(url, link)
        # 移除锚点部分
        if "#" in full_link:
            full_link = full_link.split("#")[0]
        # 判断是否为目标域名下的链接
        link_domain = urlsplit(full_link).netloc
        if link_domain == target_domain and full_link not in crawled_links:
            crawl(full_link)

target_url = "https://www.free-power-point-templates.com/"
crawl(target_url)

关键修改说明

  • 正则与编码优化:改用r'href=(["\'])(.*?)\1'兼容双/单引号的href写法,同时用response.text获取解码后的文本内容,避免编码错误。
  • 全局已爬集合:用crawled_links全局集合记录已爬链接,爬取前先做存在性判断,避免重复递归。
  • 域名判断优化:通过urlsplit解析链接域名,确保仅爬取目标域名下的内容,解决原判断逻辑的局限性。
  • 异常处理:添加try-except捕获请求异常,打印错误后继续爬取其他链接,提升程序稳定性。

内容的提问来源于stack exchange,提问作者Mohammad dehghani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:17:10