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

如何通过代码无需Git Bash安装指定GitHub YARA规则仓库内容?

不用Git工具获取GitHub仓库内容的实现方案

核心思路

不用Git客户端的话,有两种可靠实现方式:

  1. 直接下载仓库的完整ZIP归档(最简单,适合一次性获取全部内容)
  2. 通过GitHub REST API遍历仓库目录结构,逐个下载文件(适合按需获取或增量更新)

Python 实现

方法1:下载完整ZIP包

用requests库下载ZIP后解压:

import requests
import zipfile
import os

# 仓库main分支的ZIP下载地址
zip_url = "https://github.com/reversinglabs/reversinglabs-yara-rules/archive/refs/heads/main.zip"
save_path = "./reversinglabs-yara-rules.zip"
extract_dir = "./reversinglabs-yara-rules"

# 流式下载ZIP
response = requests.get(zip_url, stream=True)
with open(save_path, "wb") as f:
    for chunk in response.iter_content(chunk_size=8192):
        f.write(chunk)

# 解压到目标目录
os.makedirs(extract_dir, exist_ok=True)
with zipfile.ZipFile(save_path, "r") as zip_ref:
    zip_ref.extractall(extract_dir)

# 可选:删除临时ZIP包
os.remove(save_path)

方法2:通过API递归下载文件

遍历仓库目录,逐个下载文件:

import requests
import os

API_BASE = "https://api.github.com/repos/reversinglabs/reversinglabs-yara-rules/contents"
target_dir = "./reversinglabs-yara-rules"

def download_file(file_url, save_path):
    response = requests.get(file_url)
    os.makedirs(os.path.dirname(save_path), exist_ok=True)
    with open(save_path, "wb") as f:
        f.write(response.content)

def traverse_dir(api_path, local_path):
    response = requests.get(api_path)
    items = response.json()
    for item in items:
        if item["type"] == "file":
            download_file(item["download_url"], os.path.join(local_path, item["name"]))
        elif item["type"] == "dir":
            traverse_dir(item["url"], os.path.join(local_path, item["name"]))

traverse_dir(API_BASE, target_dir)

注:仓库较大时建议添加请求延时,避免触发GitHub API限流。


C# 实现

方法1:下载并解压ZIP包

用HttpClient下载,ZipArchive处理解压:

using System;
using System.IO;
using System.IO.Compression;
using System.Net.Http;

class Program
{
    static async System.Threading.Tasks.Task Main(string[] args)
    {
        string zipUrl = "https://github.com/reversinglabs/reversinglabs-yara-rules/archive/refs/heads/main.zip";
        string savePath = "./reversinglabs-yara-rules.zip";
        string extractDir = "./reversinglabs-yara-rules";

        // 下载ZIP包
        using (HttpClient client = new HttpClient())
        {
            using (HttpResponseMessage response = await client.GetAsync(zipUrl, HttpCompletionOption.ResponseHeadersRead))
            {
                response.EnsureSuccessStatusCode();
                using (Stream stream = await response.Content.ReadAsStreamAsync())
                using (FileStream fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
                {
                    await stream.CopyToAsync(fileStream);
                }
            }
        }

        // 解压到目标目录
        Directory.CreateDirectory(extractDir);
        ZipFile.ExtractToDirectory(savePath, extractDir);

        // 删除临时ZIP包
        File.Delete(savePath);
    }
}

方法2:通过API递归下载文件

用System.Text.Json解析API返回的JSON数据:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

class GithubRepoDownloader
{
    private static readonly HttpClient _client = new HttpClient();
    private const string ApiBase = "https://api.github.com/repos/reversinglabs/reversinglabs-yara-rules/contents";
    private static string _targetDir = "./reversinglabs-yara-rules";

    class GithubItem
    {
        public string type { get; set; }
        public string url { get; set; }
        public string download_url { get; set; }
        public string name { get; set; }
    }

    static async Task DownloadFile(string url, string localPath)
    {
        Directory.CreateDirectory(Path.GetDirectoryName(localPath));
        using (var response = await _client.GetAsync(url))
        {
            response.EnsureSuccessStatusCode();
            using (var stream = await response.Content.ReadAsStreamAsync())
            using (var fileStream = new FileStream(localPath, FileMode.Create))
            {
                await stream.CopyToAsync(fileStream);
            }
        }
    }

    static async Task TraverseDirectory(string apiPath, string localPath)
    {
        using (var response = await _client.GetAsync(apiPath))
        {
            response.EnsureSuccessStatusCode();
            var json = await response.Content.ReadAsStringAsync();
            var items = JsonSerializer.Deserialize<List<GithubItem>>(json);

            foreach (var item in items)
            {
                if (item.type == "file")
                {
                    await DownloadFile(item.download_url, Path.Combine(localPath, item.name));
                }
                else if (item.type == "dir")
                {
                    await TraverseDirectory(item.url, Path.Combine(localPath, item.name));
                }
            }
        }
    }

    static async Task Main(string[] args)
    {
        // GitHub API要求设置User-Agent,否则会拒绝请求
        _client.DefaultRequestHeaders.UserAgent.ParseAdd("C#-Repo-Downloader");
        await TraverseDirectory(ApiBase, _targetDir);
    }
}

C/C++ 实现

方法1:跨平台下载ZIP包(依赖libcurl)

#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>

// 回调函数:写入下载内容到文件
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
    return fwrite(ptr, size, nmemb, stream);
}

int main(void) {
    CURL *curl_handle;
    FILE *fp;
    const char *zip_url = "https://github.com/reversinglabs/reversinglabs-yara-rules/archive/refs/heads/main.zip";
    const char *save_path = "./reversinglabs-yara-rules.zip";

    curl_global_init(CURL_GLOBAL_ALL);
    curl_handle = curl_easy_init();

    if(curl_handle) {
        fp = fopen(save_path, "wb");
        if(!fp) {
            fprintf(stderr, "无法打开文件写入\n");
            return 1;
        }

        curl_easy_setopt(curl_handle, CURLOPT_URL, zip_url);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, fp);
        curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); // 跟随重定向

        CURLcode res = curl_easy_perform(curl_handle);
        if(res != CURLE_OK) {
            fprintf(stderr, "下载失败: %s\n", curl_easy_strerror(res));
        }

        fclose(fp);
        curl_easy_cleanup(curl_handle);
    }

    curl_global_cleanup();
    printf("ZIP包已下载到: %s\n", save_path);
    // 解压需额外依赖minizip/zlib,可自行集成实现
    return 0;
}

编译命令(Linux/macOS):gcc github_download.c -o github_download -lcurl

方法2:Windows原生下载(WinHTTP,无需第三方库)

#include <windows.h>
#include <winhttp.h>
#include <stdio.h>

#pragma comment(lib, "winhttp.lib")

int main() {
    HINTERNET hSession = WinHttpOpen(L"C-Github-Downloader", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
    if(!hSession) {
        printf("WinHttpOpen失败: %d\n", GetLastError());
        return 1;
    }

    HINTERNET hConnect = WinHttpConnect(hSession, L"github.com", INTERNET_DEFAULT_HTTPS_PORT, 0);
    if(!hConnect) {
        printf("WinHttpConnect失败: %d\n", GetLastError());
        WinHttpCloseHandle(hSession);
        return 1;
    }

    HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", L"/reversinglabs/reversinglabs-yara-rules/archive/refs/heads/main.zip", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
    if(!hRequest) {
        printf("WinHttpOpenRequest失败: %d\n", GetLastError());
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return 1;
    }

    BOOL bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
    if(bResults) {
        bResults = WinHttpReceiveResponse(hRequest, NULL);
        if(bResults) {
            FILE *fp = fopen("./reversinglabs-yara-rules.zip", "wb");
            if(fp) {
                char buffer[8192];
                DWORD bytesRead;
                while(WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
                    fwrite(buffer, 1, bytesRead, fp);
                }
                fclose(fp);
                printf("ZIP包下载成功\n");
            } else {
                printf("无法打开文件写入\n");
            }
        }
    } else {
        printf("WinHttpSendRequest失败: %d\n", GetLastError());
    }

    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);

    return 0;
}

编译命令(MSVC):cl winhttp_download.c winhttp.lib


注意事项

  • GitHub API对未认证用户限流为每小时60次请求,仓库文件较多时建议添加认证(请求头加入Authorization: token YOUR_TOKEN)
  • 下载ZIP包适合一次性获取全部内容,API方式适合灵活控制下载范围
  • C/C++解压ZIP需额外依赖minizip或zlib,可根据平台选择集成

内容的提问来源于stack exchange,提问作者Lord Touch Me

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:50:26