如何实现可终止的递归爬取西班牙语维基百科超链接?
递归爬取西班牙语维基百科超链接实现方案
核心实现思路
要完成递归爬取+手动停止的需求,需解决三个关键问题:避免重复爬取、递归遍历逻辑、手动终止机制,同时要过滤维基百科的非文章类链接(如编辑页、讨论页等)。
完整代码实现
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
相关产品推荐
相关产品推荐

