2014-05-13 4 views
-1

여기 내 문제가 있습니다. "sites.txt"라는 txt 파일이 있습니다. 이 i 유형 무작위 인터넷 사이트에서. 내 목표는 각 사이트의 첫 번째 이미지를 저장하는 것입니다. img 태그로 서버 응답을 필터링하려고했지만 일부 사이트에서는 실제로 작동하지만 일부에서는 작동하지 않습니다.URL의 첫 번째 이미지 저장

img src에서 작동하는 사이트는 http : // ...로 시작합니다. 사이트는 작동하지 않는 사이트로 시작합니다.

나는 또한 HTTP를 추가하려고 : // 그것을 가지고 didnt가 지정한 IMG SRC의 이미지,하지만 난 여전히 같은 오류 얻을 :

Exception in thread "main" java.net.MalformedURLException: no protocol: 
    at java.net.URL.<init>(Unknown Source) 

내 현재 코드는 다음과 같습니다

public static void main(String[] args) throws IOException{ 
    try { 
     File file = new File ("sites.txt"); 
     Scanner scanner = new Scanner (file); 
     String url; 
     int counter = 0; 
      while(scanner.hasNext()) 
       { 
        url=scanner.nextLine(); 
        URL page = new URL(url); 
        URLConnection yc = page.openConnection(); 
         BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream())); 
         String inputLine = in.readLine(); 
         while (!inputLine.toLowerCase().contains("img"))inputLine = in.readLine(); 
         in.close(); 
         String[] parts = inputLine.split(" "); 
         int i=0; 
         while(!parts[i].contains("src"))i++; 
         String destinationFile = "image"+(counter++)+".jpg"; 
         saveImage(parts[i].substring(5,parts[i].length()-1), destinationFile); 
         String tmp=scanner.nextLine(); 
         System.out.println(url); 

       } 
     scanner.close(); 
     } 
      catch (FileNotFoundException e) 
      { 
       System.out.println ("File not found!"); 
       System.exit (0); 
      } 

} 

public static void saveImage(String imageUrl, String destinationFile) throws IOException { 
    // TODO Auto-generated method stub 
    URL url = new URL(imageUrl); 
    String fileName = url.getFile(); 
    String destName = fileName.substring(fileName.lastIndexOf("/")); 
    System.out.println(destName); 
    InputStream is = url.openStream(); 
    OutputStream os = new FileOutputStream(destinationFile); 

    byte[] b = new byte[2048]; 
    int length; 

    while ((length = is.read(b)) != -1) { 
     os.write(b, 0, length); 
    } 

    is.close(); 
    os.close(); 
} 

나는 또한 apache jakarte http 클라이언트 라이브러리를 사용하는 팁을 가지고있다. 그러나 나는 그들이 내가 어떤 도움을 주겠다고 어떻게 사용할 수 있는지 전혀 모른다.

+0

http://hc.apache.org/httpcomponents-client-ga/examples.html – px5x2

+0

에서 몇 가지 예제를 살펴볼 수 있습니다. [jsoup] (http : // jsoup. org /)를 사용하면 HTML을 매우 쉽게 파싱 할 수 있습니다. 구성표가 누락 된 이미지 URL을 실행할뿐만 아니라 ** 상대 ** 경로도 실행하게되므로 사이트의 URL에 추가해야합니다. 예를 들어' ''이 표시되며,'https://www.google.com/ ''에 추가해야합니다. – sgbj

+0

텍스트 파일에 URL의 몇 가지 샘플을 표시 할 수 있습니까? 영업 게시물 – Braj

답변

3

URL (URI 유형) 은 유효하려면scheme이 필요합니다. 이 경우 http.

브라우저에 www.google.com을 입력하면 브라우저에서 http://을 자동으로 앞에 추가합니다. Java는이 작업을 수행하지 않으므로 예외가 발생합니다.

항상 http://이어야합니다. 간단히 ImageReadersImageWriters를, 위치 및 간단한 수행하기위한 정적 인 편리한 메소드를 포함 ImageIO으로 시도

String fixedUrl = stringUrl.replaceAll("^((?!http://).{7})", "http://$1"); 

또는

if(!stringUrl.startsWith("http://")) 
    stringUrl = "http://" + stringUrl; 
+0

봐 다시 ** 나는 또한 HTTP를 추가하려고 : // 그것을 가지고,하지만 난 여전히 같은 오류가 didnt가 지정한 IMG SRC의 이미지 : **는 IMG의 SRC 시작을 작동 – Braj

+0

'사이트를 http : //'및'MalformedURLException : no protocol'을 사용합니다. 이것은 분명히 그의 문제입니다. – Qix

+2

안녕하세요, 휴대 전화에서 atm 너무 내일까지 물건을 확인할 수 있지만 귀하의 번개 빠른 답변 주셔서 감사합니다. 나는 또한 if (! parts [i] .startsWith ("http :"))) parts [i] = "http :"+ parts [i]로 http : //를 추가하려고 시도했다. "(?!. : //) {7} (HTTP) ^", "HTTP를 : // $ 1"'정규식 같은 오류'사용 – user3634163

1

대안 솔루션

: 당신은 쉽게이 사용하는 정규식을 해결할 수 있습니다 인코딩 및 디코딩

샘플 코드 :

// read a image from the URL 
// I used the URL that is your profile pic on StackOverflow 
BufferedImage image = ImageIO 
     .read(new URL(
       "https://www.gravatar.com/avatar/3935223a285ab35a1b21f31248f1e721?s=32&d=identicon&r=PG&f=1")); 

// save the image 
ImageIO.write(image, "jpg", new File("resources/avatar.jpg")); 
+1

그건 그 사람의 문제가 아닙니다. – Qix

+0

이것은 문제를 전혀 해결하지 못합니다. 제안한 코드가 이미 가지고있는 방식대로 작동하는 경우 * 대체 솔루션 *이 아닙니다. – Qix

+0

그의 예외를 다시 보아라. 그것은 연결이나 이미지를 다운로드하는 방법과 아무 관련이 없습니다. – Qix

0

당신이 이미지 요소와 그 SRC 속성에 대한 사이트의 HTML을 근근이 살아가고있어, 당신은 URL을 여러 가지 다른 표현으로 실행하겠습니다.

예는 다음 :

  1. resource = https://google.com/images/srpr/logo9w.png
  2. resource = google.com/images/srpr/logo9w.png
  3. resource = //google.com/images/srpr/logo9w.png
  4. resource = /images/srpr/logo9w.png
  5. resource = images/srpr/logo9w.png

제 회의용 거친 다섯 번째 것, 당신은 URL의 나머지를 건축 할 필요가있을 것이다.

두 번째 것은 네 번째 및 다섯 번째와 구별하기가 더 어려울 수 있지만 해결 방법이 있습니다.URL Standard은 기술적으로 유효하다고 생각하지 않기 때문에 자주 보지 않을 것이라고 생각합니다.

세 번째 경우

은 아주 간단합니다. resource 변수가 //으로 시작하는 경우 프로토콜/스키마를 앞에 추가하기 만하면됩니다. 당신은 당신이 가지고있는 site 객체와이 작업을 수행 할 수 있습니다 네 번째와 다섯 번째 경우에

url = site.getProtocol() + ":" + resource

, 당신은 전체 사이트의 URL을 가지는 자원을 앞에 추가해야합니다.

다음은 HTML을 구문 분석 jsoup를 사용하는 샘플 응용 프로그램 및 자원 URL을 구축하는 간단한 유틸리티 메소드입니다. buildResourceUrl 방법에 관심이 있습니다. 또한 두 번째 경우는 처리하지 않습니다. 나는 너에게 맡길거야.

import java.io.*; 
import java.net.*; 
import org.jsoup.*; 
import org.jsoup.nodes.*; 
import org.jsoup.select.*; 

public class SiteScraper { 

    public static void main(String[] args) throws IOException { 
     URL site = new URL("https://google.com/"); 
     Document doc = Jsoup.connect(site.toString()).get(); 
     Elements images = doc.select("img"); 
     for (Element image : images) { 
      String src = image.attr("src"); 
      System.out.println(buildResourceUrl(site, src)); 
     } 
    } 

    static URL buildResourceUrl(URL site, String resource) 
      throws MalformedURLException { 
     if (!resource.matches("^(http|https|ftp)://.*$")) { 
      if (resource.startsWith("//")) { 
       return new URL(site.getProtocol() + ":" + resource); 
      } else { 
       return new URL(site.getProtocol() + "://" + site.getHost() + "/" 
         + resource.replaceAll("^/", "")); 
      } 
     } 
     return new URL(resource); 
    } 
} 

이 분명 모든 것을 커버하지 않습니다, 그러나 그것은 시작입니다. 사용자가 액세스하려는 URL 사이트 (즉, http://some.place/under/the/rainbow.html)의 루트의 하위 디렉토리에있을 때 당신은 문제가 실행할 수 있습니다. 당신은 정말 각각의 경우 얼마나 멀리 갈 의향에 따라 달라집니다 ... src 속성에 base64 encoded data URI's가 발생할 수 있습니다.

관련 문제