2015-04-03 1 views
0

Я пытаюсь построить на основе Java приложение jsoup автоматически загружать английские субтитры для фильмов (я ленивый, я знаю. Это был вдохновило от аналогичного python на основе приложения). Он должен спросить вас название фильма, а затем загрузить для него английский субтитр от subscene.Сохранить файл с веб-сайта с Java

Я могу довести его до ссылки для скачивания, но получаю Неиспользованный тип содержимого Ошибка при попытке «перейти» к этой ссылке. Вот мой код

public static void main(String[] args) { 
    try { 
      String videoName = JOptionPane.showInputDialog("Title: "); 
     subscene(videoName); 
     } 
     catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 
} 

public static void subscene(String videoName){ 
     try { 
      String siteName = "http://www.subscene.com"; 
      String[] splits = videoName.split("\\s+"); 
      String codeName = ""; 
      String text = ""; 
      if(splits.length>1){ 
       for(int i=0;i<splits.length;i++){ 
        codeName = codeName+splits[i]+"-"; 
       } 
       videoName = codeName.substring(0, videoName.length()); 
      } 
      System.out.println("videoName is "+videoName); 
      // String url = "http://www.subscene.com/subtitles/"+videoName+"/english"; 
      String url = "http://www.subscene.com/subtitles/title?q="+videoName+"&l="; 
      System.out.println("url is "+url); 
      Document doc = Jsoup.connect(url).get(); 
      Element exact = doc.select("h2.exact").first(); 
      Element yuel = exact.nextElementSibling(); 
      Elements lis = yuel.children(); 

       System.out.println(lis.first().children().text()); 
       String hRef = lis.select("div.title > a").attr("href"); 
       hRef = siteName+hRef+"/english"; 

      System.out.println("hRef is "+hRef); 
      doc = Jsoup.connect(hRef).get(); 

      Element nonHI = doc.select("td.a40").first(); 
      Element papa = nonHI.parent(); 
      Element link = papa.select("a").first(); 
      text = link.text(); 
      System.out.println("Subtitle is "+text); 
      hRef = link.attr("href"); 
      hRef = siteName+hRef; 

      Document subDownloadPage = Jsoup.connect(hRef).get(); 
      hRef = siteName+subDownloadPage.select("a#downloadButton").attr("href"); 
      Jsoup.connect(hRef).get(); //<-- Here's where the problem lies 

      } 
      catch (java.io.IOException e) { 
       System.out.println(e.getMessage()); 
      } 
    } 

Может кто-нибудь, пожалуйста, помогите мне, поэтому мне не нужно вручную загружать субмарины?

Я только что узнал, что с помощью

java.awt.Desktop.getDesktop().browse(java.net.URI.create(hRef)); 

вместо

Jsoup.connect(hRef).get(); 

загружает файл после того, как побуждая меня, чтобы сохранить его. Но я не хочу, чтобы меня запрашивали, потому что я не смогу прочитать имя загруженного zip-файла (я хочу разархивировать его после сохранения с помощью java).

+0

Не могли бы вы предоставить более подробную информацию об исключении? –

+0

В нем указано ** Тип необработанного контента. Должен быть текст/*, application/xml или application/xhtml + xml ** – Amber

+0

то, что печатается с 'System.out.println (« hRef is »+ hRef);' –

ответ

2

Здесь:

Document subDownloadPage = Jsoup.connect(hRef).get(); 
hRef = siteName+subDownloadPage.select("a#downloadButton").attr("href"); 
//specifically here 
Jsoup.connect(hRef).get(); 

Похоже jsoup ожидает, что результат Jsoup.connect(hRef) должен быть HTML или текст, который он в состоянии разобрать, поэтому сообщение гласит:

Unhandled тип контента , Должен быть текст/*, приложение/XML или приложение/XHTML + XML

Я последовал за выполнение кода вручную и последний URL, который вы пытаетесь получить доступ возвращает тип содержимого application/x-zip-compressed, таким образом, причиной исключения.

Для загрузки файла необходимо использовать другой подход. Вы можете использовать старый, но все еще полезный, URL или использовать стороннюю библиотеку, такую ​​как Apache HttpComponents, для запуска запроса GET и получения результата в виде InputStream, оберните его в подходящую запись и напишите файл на свой диск.

Вот пример об этом с помощью URL:

URL url = new URL(hRef); 
InputStream in = url.openStream(); 
OutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\foo.zip")); 
final int BUFFER_SIZE = 1024 * 4; 
byte[] buffer = new byte[BUFFER_SIZE]; 
BufferedInputStream bis = new BufferedInputStream(in); 
int length; 
while ((length = bis.read(buffer)) > 0) { 
    out.write(buffer, 0, length); 
} 
out.close(); 
in.close(); 
+0

OMG это сработало. Большое вам спасибо ... – Amber

+1

@Amber приветствую вас. Я обновил код, чтобы быть более эффективным. Используйте этот код, а не старый код, указанный ранее. –

+0

Вы должны просто указать JSoup игнорировать contentType. (см. мой ответ) Размер вашего буфера 4 КБ, и большинство файлов srt составляют всего около 100 КБ. Таким образом, влияние на использование памяти невелико. Стоит ли уродство вашего кода? Вы можете сделать то же самое в двух строках. – bvdb

3

Предполагая, что ваши файлы малы, вы можете сделать это следующим образом. Обратите внимание, что Jsoup может игнорировать тип содержимого.

// get the file content 
Connection connection = Jsoup.connect(path); 
connection.timeout(5000); 
Connection.Response resultImageResponse = connection.ignoreContentType(true).execute(); 

// save to file 
FileOutputStream out = new FileOutputStream(localFile); 
out.write(resultImageResponse.bodyAsBytes()); 
out.close(); 

Я бы порекомендовал вам проверить содержимое перед сохранением. Поскольку некоторые серверы просто вернут HTML-страницу, когда файл не может быть найден, то есть сломанная гиперссылка.

... 
String body = resultImageResponse.body(); 
if (body == null || body.toLowerCase().contains("<body>")) 
{ 
    throw new IllegalStateException("invalid file content"); 
} 
... 
+0

Этот подход хорош, но я не рекомендую использовать это: 'out.write (resultImageResponse.bodyAsBytes());'. Лучше ** читать части файла в небольших фрагментах 4 или 8 КБ, как показано в моем ответе. Вероятно, вы не можете видеть * проблему *, так как это очень маленькие файлы, а это когда вы работаете с огромными файлами, особенно по сети, например. загрузка/загрузка файлов. –

+1

Как я уже сказал: «Предполагая, что ваши файлы маленькие», что здесь и есть. Файлы субтитров - это небольшие файлы. Итак, я думаю, что это более читаемо. – bvdb