【问题标题】:How to specify User Agent and Referer in FileUtils.copyURLToFile(URL, File) method?如何在 FileUtils.copyURLToFile(URL, File) 方法中指定 User Agent 和 Referer?
【发布时间】:2016-03-14 18:38:00
【问题描述】:

我正在使用 FileUtils.copyURLToFile(URL, File)Apache Commons IO 2.4 部件)下载文件并将其保存在我的计算机上。问题是一些网站拒绝没有引荐来源和用户代理数据的连接。

我的问题:

  1. 有没有办法指定copyURLToFile 方法的用户代理和引荐来源?
  2. 或者我应该使用其他方法下载文件,然后将给定的InputStream 保存到文件中?

【问题讨论】:

    标签: java apache http-headers apache-commons


    【解决方案1】:

    我已经使用HttpComponents 而不是Commons-IO 重新实现了该功能。此代码允许您根据其 URL 下载 Java 中的文件并将其保存在特定的目标位置。

    最终代码:

    public static boolean saveFile(URL imgURL, String imgSavePath) {
    
        boolean isSucceed = true;
    
        CloseableHttpClient httpClient = HttpClients.createDefault();
    
        HttpGet httpGet = new HttpGet(imgURL.toString());
        httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.11 Safari/537.36");
        httpGet.addHeader("Referer", "https://www.google.com");
    
        try {
            CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity imageEntity = httpResponse.getEntity();
    
            if (imageEntity != null) {
                FileUtils.copyInputStreamToFile(imageEntity.getContent(), new File(imgSavePath));
            }
    
        } catch (IOException e) {
            isSucceed = false;
        }
    
        httpGet.releaseConnection();
    
        return isSucceed;
    }
    

    当然,上面的代码比单行代码占用更多空间:

    FileUtils.copyURLToFile(imgURL, new File(imgSavePath),
                            URLS_FETCH_TIMEOUT, URLS_FETCH_TIMEOUT);
    

    但它可以让您更好地控制流程,让您不仅可以指定超时时间,还可以指定 User-AgentReferer 值,这对于许多网站至关重要。

    【讨论】:

      【解决方案2】:

      完成关于如何处理超时的公认答案:

      如果你想设置超时,你必须像这样创建CloseableHttpClient

      RequestConfig config = RequestConfig.custom()
                       .setConnectTimeout(connectionTimeout)
                       .setConnectionRequestTimeout(readDataTimeout)
                       .setSocketTimeout(readDataTimeout)
                       .build();
      
      CloseableHttpClient httpClient = HttpClientBuilder
                       .create()
                       .setDefaultRequestConfig(config)
                       .build();
      

      而且,使用 try-with-resource 语句创建 CloseableHttpClient 来处理它的关闭可能是个好主意:

      try (CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build()) {
        ... rest of the code using httpClient
      }
      

      【讨论】:

        【解决方案3】:

        可能不会,除非你能掌握打开 URL 的底层机制。

        我建议使用https://hc.apache.org/ 库。这有很多关于标题等的功能。

        【讨论】:

        • 我已经使用Apache HttpComponents,但不知道如何结合copyURLToFileHttpComponents的功能。
        • 你不使用copyToUrl,可以使用https组件nio包并使用文件通道将数据写入文件
        猜你喜欢
        • 2013-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-08
        • 1970-01-01
        相关资源
        最近更新 更多