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

代码遇服务器请求错误挂起、返回404时停止,如何修改仅将无404错误的URL加入列表?

解决PDF下载时404错误终止与请求挂起的问题

我来帮你搞定这个问题!你的代码现在遇到404就直接终止运行,遇到请求异常还会挂住,咱们从两个核心方向修改:一是提前验证PDF链接的有效性,只把能正常访问(非404、无请求错误)的URL加入下载列表;二是给请求加上超时限制和异常捕获,彻底解决挂起和崩溃的问题。

具体修改思路

  • 提前筛选有效链接:在将链接加入pdfs列表前,先发送HEAD请求(比GET请求轻量,只获取响应头)验证链接状态,排除404、500这类无效链接
  • 添加请求超时与异常处理:不管是验证链接还是下载文件,都给请求加超时时间,同时捕获常见的请求异常(比如连接超时、DNS解析失败等),避免程序挂起或崩溃
  • 修正循环索引:原代码从i=1开始循环,会漏掉第一个PDF链接,改成从i=0开始遍历更合理

修改后的完整代码

import requests
import httplib2
import os
from bs4 import BeautifulSoup, SoupStrainer

def is_link_valid(url, timeout=5):
    """验证链接是否有效,返回True/False"""
    try:
        # 用HEAD请求,只获取响应头,节省带宽
        response = requests.head(url, timeout=timeout)
        # 只保留状态码为200(正常)的链接,排除404、500等错误
        return response.status_code == requests.codes.OK
    except requests.exceptions.RequestException:
        # 捕获所有请求异常(超时、连接失败等),直接标记为无效
        return False

def baixa_arquivo(url, endereco, timeout=10):
    """下载文件,带超时和异常处理"""
    try:
        resposta = requests.get(url, timeout=timeout)
        resposta.raise_for_status()  # 仅在状态码异常时抛出错误
        with open(endereco, 'wb') as novo_arquivo:
            novo_arquivo.write(resposta.content)
        print(f'Download concluído. Salvo em {endereco}')
    except requests.exceptions.RequestException as e:
        print(f'Falha ao baixar {url}: {str(e)}')

if __name__ == '__main__':
    artigos = []
    pdfs = []
    http = httplib2.Http()
    status, response = http.request('https://www.snh2021.anpuh.org/site/anais')
    
    # 第一步:收集所有页面链接
    for link in BeautifulSoup(response, parse_only=SoupStrainer('a')):
        if link.has_attr('href'):
            artigos.append(link['href'])
    
    # 第二步:筛选有效PDF链接
    url_basica = 'https://www.snh2021.anpuh.org/{}'
    for x in artigos:
        if x.endswith('pdf'):
            full_url = url_basica.format(x)
            print(f'验证链接: {full_url}')
            if is_link_valid(full_url):
                pdfs.append(x)
                print(f'链接有效,加入下载列表')
            else:
                print(f'链接无效,跳过')
    
    print(f'\n待下载的有效PDF链接共 {len(pdfs)} 个: {pdfs}')
    
    # 创建下载目录(如果不存在)
    output = 'Download'
    os.makedirs(output, exist_ok=True)
    
    # 第三步:下载所有有效PDF
    for i, pdf_path in enumerate(pdfs):
        nome_do_arquivo = os.path.join(output, f'artigo{i+1}.pdf')  # 文件名从1开始
        full_url = url_basica.format(pdf_path)
        baixa_arquivo(full_url, nome_do_arquivo)

关键改进点说明

  1. is_link_valid函数:用HEAD请求快速验证链接,避免下载整个文件浪费带宽,同时捕获所有请求异常,确保不会因为某个链接的问题导致程序中断
  2. baixa_arquivo函数:添加超时时间,捕获所有请求异常,即使单个文件下载失败,程序也会继续处理下一个文件
  3. 目录创建:用os.makedirs(output, exist_ok=True)确保下载目录存在,避免因目录不存在报错
  4. 遍历优化:用enumerate遍历PDF列表,同时获取索引和链接,代码更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 19:12:31