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

如何用Python从HTML中提取RAR文件链接并下载对应文件?

解析HTML中的.rar链接并下载文件的完整解决方案

我来帮你搞定这个需求,先梳理下你原代码里的几个小问题,再给你一套完整的实现方案:

原代码里的问题点

  • 正则表达式写错了:re.compile("$rar")应该是re.compile(r'\.rar$'),要匹配以.rar结尾的链接,点号需要转义,$放在结尾表示匹配字符串末尾。
  • 缺少re模块的导入,正则表达式没法正常使用。
  • BeautifulSoup的导入建议更新为from bs4 import BeautifulSoup(现在主流是这个版本,旧版的BeautifulSoup包已经停止维护了)。
  • 循环语句末尾缺少冒号,会触发语法错误。
  • 获取链接时应该用link.get('href'),而不是直接写字符串'href'。
  • 没有添加文件保存到本地的逻辑,下载后没法留存文件。
  • 你创建了session对象s,但后续请求没用到它,应该用s.get()来保持会话一致性(比如页面需要登录状态时)。

完善后的完整代码

import requests
import re
import random
import os
from bs4 import BeautifulSoup  # 推荐使用新版BeautifulSoup

# 用户代理列表
user_agent_list = [
    # Windows
    'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0',
    # Linux
    'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:60.0) Gecko/20100101 Firefox/60.0',
]

# 目标URL和保存目录
url = 'http://example.com'
save_dir = './rar_files'  # 自定义保存目录,不存在则自动创建
if not os.path.exists(save_dir):
    os.makedirs(save_dir)

# 建立会话,保持登录状态(如果headers里的账号密码有效)
session = requests.session()
user_agent = random.choice(user_agent_list)
headers = {
    'login_username': 'user',
    'login_password': 'pass',
    'User-Agent': user_agent
}

try:
    # 请求目标页面
    response = session.get(url, headers=headers)
    response.raise_for_status()  # 请求失败时抛出异常,避免静默报错
    print("页面请求成功")

    # 解析HTML内容
    soup = BeautifulSoup(response.content, 'html.parser')  # 指定解析器,避免警告

    # 筛选所有指向.rar文件的链接
    rar_links = soup.find_all('a', attrs={'href': re.compile(r'\.rar$')})
    print(f"找到 {len(rar_links)} 个.rar文件链接")

    # 遍历链接并下载文件
    for link in rar_links:
        rar_url = link.get('href')
        # 处理相对链接(如果页面里有相对路径的话)
        if not rar_url.startswith('http'):
            rar_url = requests.compat.urljoin(url, rar_url)
        
        # 从URL中提取文件名
        filename = os.path.basename(rar_url)
        save_path = os.path.join(save_dir, filename)

        print(f"正在下载: {rar_url}")
        try:
            # 分块下载大文件(避免内存占用过高)
            with session.get(rar_url, stream=True) as r:
                r.raise_for_status()
                with open(save_path, 'wb') as f:
                    for chunk in r.iter_content(chunk_size=8192):
                        f.write(chunk)
            print(f"下载完成: {filename}")
        except Exception as e:
            print(f"下载 {rar_url} 失败: {str(e)}")

except Exception as e:
    print(f"页面请求失败: {str(e)}")

代码额外优化说明

  1. 自动创建目录:提前检查保存目录是否存在,不存在则自动创建,避免保存文件时出错。
  2. 会话保持:用session.get()替代requests.get(),确保登录状态(如果你的headers账号密码有效的话)。
  3. 异常捕获:添加raise_for_status()捕获请求失败的情况,不会默默忽略错误。
  4. 相对链接处理:用requests.compat.urljoin()把相对链接转为绝对链接,避免下载错误地址。
  5. 分块下载:通过stream=True和iter_content()分块写入文件,适合大文件下载,不会占满内存。

如果想加速下载,可以用多线程并行处理,比如把下载逻辑封装成函数后启动线程:

import threading

# 定义下载函数
def download_rar(rar_url, save_path, session):
    try:
        print(f"正在下载: {rar_url}")
        with session.get(rar_url, stream=True) as r:
            r.raise_for_status()
            with open(save_path, 'wb') as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
        print(f"下载完成: {os.path.basename(save_path)}")
    except Exception as e:
        print(f"下载 {rar_url} 失败: {str(e)}")

# 遍历链接并启动线程
threads = []
for link in rar_links:
    rar_url = link.get('href')
    if not rar_url.startswith('http'):
        rar_url = requests.compat.urljoin(url, rar_url)
    filename = os.path.basename(rar_url)
    save_path = os.path.join(save_dir, filename)
    thread = threading.Thread(target=download_rar, args=(rar_url, save_path, session))
    threads.append(thread)
    thread.start()

# 等待所有线程完成
for thread in threads:
    thread.join()

这样就能同时下载多个文件,提升下载效率啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:46:18