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

如何实现可终止的递归爬取西班牙语维基百科超链接?

递归爬取西班牙语维基百科超链接实现方案

核心实现思路

要完成递归爬取+手动停止的需求,需解决三个关键问题:避免重复爬取、递归遍历逻辑、手动终止机制,同时要过滤维基百科的非文章类链接(如编辑页、讨论页等)。

完整代码实现

import requests
from bs4 import BeautifulSoup
from urllib.parse import unquote, urljoin
import sys

# 初始化已访问链接集合(去重)和总链接列表
visited_urls = set()
collected_links = []

# 配置请求头,遵守维基百科爬虫规则
HEADERS = {
    'User-Agent': 'WikiLinkCollector/1.0 (your-email@example.com)'
}

def is_valid_wiki_article(href):
    """判断是否是有效的西班牙语维基百科文章链接"""
    if not href.startswith('/wiki/'):
        return False
    # 排除特殊页面(如讨论页、编辑页、特殊功能页)
    exclude_prefixes = ('/wiki/Special:', '/wiki/Talk:', '/wiki/User:', '/wiki/Wikipedia:', '/wiki/File:')
    return not any(href.startswith(prefix) for prefix in exclude_prefixes)

def crawl_wiki_page(base_url, current_url):
    """递归爬取单个维基页面的所有有效链接"""
    # 补全完整URL
    full_url = urljoin(base_url, current_url)
    
    # 跳过已访问或无效的链接
    if full_url in visited_urls or not is_valid_wiki_article(current_url):
        return
    
    print(f"正在爬取: {full_url}")
    visited_urls.add(full_url)
    collected_links.append(full_url)
    
    try:
        # 发送请求,设置超时避免卡住
        response = requests.get(full_url, headers=HEADERS, timeout=10)
        response.raise_for_status()  # 捕获HTTP错误
    except Exception as e:
        print(f"爬取失败 {full_url}: {str(e)}")
        return
    
    # 解析页面提取链接
    soup = BeautifulSoup(response.content, 'lxml')
    for a_tag in soup.find_all('a', href=True):
        href = unquote(a_tag.get('href'))
        # 递归调用爬取子链接
        crawl_wiki_page(base_url, href)

if __name__ == "__main__":
    start_url = "https://es.wikipedia.org/wiki/Olula_del_Río"
    try:
        # 从初始页面开始递归爬取
        crawl_wiki_page(start_url, start_url.split('wiki/')[1])
    except KeyboardInterrupt:
        # 捕获Ctrl+C,手动停止爬取
        print("\n用户手动停止爬取")
        print(f"共收集到 {len(collected_links)} 个唯一链接")
        
        # 可选:保存结果到文件
        with open('wiki_links.txt', 'w', encoding='utf-8') as f:
            for link in collected_links:
                f.write(f"{link}\n")
        print("结果已保存到 wiki_links.txt")
        sys.exit(0)

关键细节说明

  • 去重机制:用visited_urls集合记录已爬取的链接,避免重复请求同一页面,提升效率。
  • 链接过滤:is_valid_wiki_article函数只保留/wiki/开头且排除特殊前缀的链接,确保只爬取维基百科的正文文章。
  • 手动停止:通过捕获KeyboardInterrupt异常,用户按下Ctrl+C即可终止爬取,同时保存已收集的链接。
  • 合规爬取:设置自定义User-Agent并遵守超时规则,避免触发维基百科的反爬机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:39:23