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

爬取维基国旗SVG时遇urllib.error.HTTPError 404,手动访问正常

解决维基百科国旗SVG爬取的404问题

问题根源

  1. URL构造错误:当前用split('.svg')截断URL的方式,在部分特殊结构的缩略图路径下会生成无效地址,导致服务器返回404。
  2. 请求头缺失:维基百科服务器会拦截无浏览器标识的爬虫请求,手动访问时浏览器自带UA所以正常,代码请求因无标识被拒绝。
  3. 无异常处理机制:遇到错误请求直接崩溃,无法跳过或继续处理后续国旗。

修正方案

1. 重构代码(核心优化)

import requests
from bs4 import BeautifulSoup
import os

# 自动创建保存目录,避免路径不存在错误
os.makedirs('flags', exist_ok=True)

page = requests.get("https://en.wikipedia.org/wiki/Gallery_of_sovereign_state_flags")
soup = BeautifulSoup(page.content, 'html.parser')

# 模拟浏览器请求头,绕过爬虫拦截
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}

for flag in soup.find_all('a', attrs={'class': "image"}):
    # 直接定位img标签的src,避免contents[0]的不确定性
    img_src = flag.find('img')['src']
    # 移除缩略图标识"thumb/"
    img_src = img_src.replace('thumb/', '')
    # 分割路径,去掉末尾的宽度参数段(比如"120px-Flag_of_Australia.svg")
    path_parts = img_src.split('/')
    original_svg_path = '/'.join(path_parts[:-1])
    fixed_src = f"https:{original_svg_path}"
    
    # 匹配国家名称并下载
    for country in data["Country"]:
        # 适配URL中的下划线命名规则
        country_url_name = country.replace(' ', '_')
        if country_url_name in fixed_src:
            try:
                # 用requests替代wget,支持自定义请求头和异常捕获
                response = requests.get(fixed_src, headers=headers)
                response.raise_for_status()  # 触发HTTP错误抛出
                with open(f'flags/{country}.svg', 'wb') as f:
                    f.write(response.content)
                print(f"已下载:{country}")
            except requests.exceptions.HTTPError as e:
                print(f"{country}下载失败:{e}")
            break  # 匹配到对应国家后跳出循环,避免重复匹配

2. 关键优化点

  • URL精准处理:通过分割路径移除缩略图的宽度参数,避免字符串截断带来的错误。
  • 模拟浏览器请求:添加User-Agent请求头,绕过维基百科的爬虫检测。
  • 异常捕获机制:遇到404或网络错误时,仅打印日志不中断程序,继续处理后续国旗。
  • 匹配逻辑优化:将国家名称的空格替换为下划线,适配URL中的命名格式,减少匹配失败。
  • 替换wget为requests:更灵活地控制请求流程,处理复杂的HTTP场景。

3. 额外建议

  • 若仍有少量URL失败,可检查国家名称与URL文件名的对应关系(部分国家存在全称/简称差异)。
  • 对失败请求添加1-2次重试机制,规避临时网络波动导致的错误。
  • 添加请求间隔(比如time.sleep(1)),避免频繁请求触发IP封禁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:45:37