# Bing Picture of the Day Downloader



## MrOctron (24. Aug 2011)

Hallo zusammen,

ich benutze zwar für die Internetsuche überwiegend google, aber ich liebe die Bilder des Tages auf Bing.

Dies und die Lust am Programmieren in Java hat mich dazu beflügelt ein Programm zum Downloaden der Bilder zu schreiben.
Leider komme ich bei der Hauptfunktion des Programms nicht weiter. Mit der Hauptfunktion meine ich das Downloaden der Bilder bei Bing nicht weiter. Ich habe hier: Bing Image Download - CodeProject einen Programmcode in C# gefunden, mit dem sich die Bilder downloaden lassen gefunden. Aufgrund meiner sehr mageren Programmierkenntnissen schaffe ich leider nicht den Code in Java zu portieren und in meinen Code einzufügen.


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.JFileChooser;
import java.net.URL;
import java.io.*;

public class BingPictureDownloader extends JFrame {

  // Anfang Attribute
  private JButton jButton_download = new JButton();
  private JButton jButton_cancel = new JButton();
  private JLabel jLabel_target = new JLabel();
  private JTextField jTextField_target = new JTextField();
  private JButton jButton_browse = new JButton();
  
  // private final String bing_url = "http://www.bing.com";
  // private final String image_url = "http://www.bing.com/HPImageArchive" +
  //                               ".aspx?format=xml&idx=0&n={0}&mkt={1}";
  // private static String[] markets = new String[] {
  //  "en-US", "zh-CN",
  //  "ja-JP", "en-AU", "en-UK",
  //  "de-DE", "en-NZ", "en-CA"
  // };
  // private final int number_of_images = 1;
  // Ende Attribute

  public BingPictureDownloader (String title) {
    super (title);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    int frameWidth = 319; 
    int frameHeight = 138;
    setSize(frameWidth, frameHeight);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);
    Container cp = getContentPane();
    cp.setLayout(null);
    // Anfang Komponenten
    jButton_download.setBounds(8, 72, 131, 25);
    jButton_download.setText("Download");
    jButton_download.setMargin(new Insets(2, 2, 2, 2));
    jButton_download.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jButton_download_ActionPerformed(evt);
      }
    });
    cp.add(jButton_download);
    jButton_cancel.setBounds(176, 72, 131, 25);
    jButton_cancel.setText("Beenden");
    jButton_cancel.setMargin(new Insets(2, 2, 2, 2));
    jButton_cancel.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jButton_cancel_ActionPerformed(evt);
      }
    });
    cp.add(jButton_cancel);
    jLabel_target.setBounds(8, 8, 219, 20);
    jLabel_target.setText("Speicherort wählen");
    cp.add(jLabel_target);
    jTextField_target.setBounds(8, 32, 190, 25);
    cp.add(jTextField_target);
    jButton_browse.setBounds(208, 32, 99, 25);
    jButton_browse.setText("Durchsuchen");
    jButton_browse.setMargin(new Insets(2, 2, 2, 2));
    jButton_browse.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jButton_browse_ActionPerformed(evt);
      }
    });
    cp.add(jButton_browse);
    setTitle("Bing Picture Downloader");
    setUndecorated(false);
    Image icon = new ImageIcon("bing.png").getImage();
    setIconImage(icon);
    // Ende Komponenten
    setResizable(false);
    setVisible(true);
  }

  // Anfang Methoden
  public void jButton_download_ActionPerformed(ActionEvent evt) {
    // TODO hier Quelltext einfügen
  }

  public void jButton_cancel_ActionPerformed(ActionEvent evt) {
    //Programm beenden
    System.exit(0);
  }

  public void jButton_browse_ActionPerformed(ActionEvent evt) {
    // JFileChooser-Objekt erstellen
    JFileChooser fc = new JFileChooser();
    // Bezeichnung Fenster
    fc.setDialogTitle("Ordner zum Speichern wählen");
    // Nur Ordnerauswahl
    fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    // Speicherort
    int returnVal = fc.showOpenDialog(this);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
       String fpath = new String(fc.getSelectedFile().getPath());
       jTextField_target.setText(fpath);
    }
  }
  
  //Anfang Methode
  public static void main(String[] args) {
    new BingPictureDownloader("Bing Picture Downloader");
  }
}

  // Ende Methoden
```

Wer kann mir dabei helfen den Code so umzuwandeln, dass der Code beim Klicken auf den Downloadbutton die Bilder runterlädt.

Da ich ein Programmiereinsteiger bin, bin ich für jegliche konstruktive Kritik an meinem Code dankbar.


----------



## Final_Striker (24. Aug 2011)

Im Quelltext von Bing-Startseite nach 
	
	
	
	





```
/fd/hpk2/*.jpg
```
 suchen und dann das Bild von 
	
	
	
	





```
www.bing.com/fd/hpk2/name_des_bildes.jpg
```
 laden und speichern.


```
Da ich ein Programmiereinsteiger bin, bin ich für jegliche konstruktive Kritik an meinem Code dankbar.
```

Lass die GUI weg und mach das zuerst auf der Konsole. Von deinen 118 Zeile Code haben lediglich 10 (auskommentierte) was mit dem eigentlichem Problem zu tun.


----------



## MrOctron (24. Aug 2011)

Final_Striker hat gesagt.:


> Im Quelltext von Bing-Startseite nach
> 
> 
> 
> ...



Habe jetzt gegooglet und mir einige Codebeispiele angeschaut und auch ausprobiert. Dazu wollte ich folgendes Bild http://www.bing.de/fd/hpk2/HappisburghUK_DE-DE2045857620.jpg downloaden. Leider hatte ich da kein Erfolg. Habe es auch ohne GUI oder jeglichen SchnickSchnack versucht. 

Kann mir jemand ein Codebeispiel geben um z.B. das oben genannte Bild zu downloaden?


----------



## Final_Striker (24. Aug 2011)

http://www.java-forum.org/java-basics-anfaenger-themen/116821-java-jpg-url-adesse-speichern.html

Schau dir die 
	
	
	
	





```
CoverDownloader
```
 Klasse von darekkay an.


----------



## MrOctron (24. Aug 2011)

Danke für den Link. Habe den Code angepasst und das downloaden klappt jetzt, jedoch nicht auf C:\. Der Zugriff wird verweigert.


```
import java.io.*;
import java.net.*;

public class Downloader {

	public static void main(String[] args) throws IOException  {
		URL url = new URL("http://www.bing.com/fd/hpk2/HappisburghUK_DE-DE2045857620.jpg");

		InputStream is = url.openStream();
		OutputStream os = new FileOutputStream("F:\\Bing.jpg");

		byte[] buffer = new byte[1024];
		int byteReaded = is.read(buffer);
		while(byteReaded != -1)
		{
			os.write(buffer,0,byteReaded);
			byteReaded = is.read(buffer);
		}

		os.close();
	}
}
```

Die nächste Herausforderung ist jetzt den Quelltext von Bing.de nach dem Bildnamen zu durchsuchen.


----------



## Gast2 (25. Aug 2011)

Das div dass du suchst hat ne id, danach kannst du suchen.
Entweder nimmst du dafür nen fertigen parser (ist vllt etwas zu viel) oder du suchst per hand danach, z.b. mit den String Methoden oder einer passenden Regex.


----------



## JohannisderKaeufer (25. Aug 2011)

MrOctron hat gesagt.:


> jedoch nicht auf C:\. Der Zugriff wird verweigert.



Du sollst ja auch nichts in C:\ speichern! 
Sondern in "Eigene Dateien" bzw. C:\Users\dein_username\...


----------



## MrOctron (25. Aug 2011)

EikeB hat gesagt.:


> Das div dass du suchst hat ne id, danach kannst du suchen.
> Entweder nimmst du dafür nen fertigen parser (ist vllt etwas zu viel) oder du suchst per hand danach, z.b. mit den String Methoden oder einer passenden Regex.


Danke für den Tipp.
Habe einen passenden Code hier im Forum gefunden. Verstehe den leider nicht ganz. Muss mal den komplett auseinanderpflücken. 


```
import java.awt.*;
import java.io.*;
import java.util.regex.*;
import java.net.*;


public class SucheString{
  public static void sucheStringZwischen(String text, String anfang, String ende) {
  //Bei Ausdrücken (text) mit mehreren Klammern muss noch eine Einschränkung bei .* getroffen werden
    Pattern p = Pattern.compile("(?<="+anfang+").*(?="+ende+")");
    Matcher m = p.matcher(text);
    while(m.find()) {
      System.out.println(m.group());
    }
  }

  public static void main(String[] args) {
    sucheStringZwischen("2+(3-4)","\\(","\\)");
  }
}
```




> Du sollst ja auch nichts in C:\ speichern!
> Sondern in "Eigene Dateien" bzw. C:\Users\dein_username\...


@JohannisderKaeufer
Ich habe auch nicht vor unter C:\ zu speichern, aber mich wundert es trotzdem, wieso es nicht funktioniert.


----------



## MrOctron (25. Aug 2011)

Habe jetzt versucht nach dem Bildnamen auf der Bing HP zu suchen. Habe jedoch kein Erfolg mit dem folgenden Code.


```
import java.awt.*;
import java.io.*;
import java.util.regex.*;
import java.net.*;
import java.lang.*;

public class SucheImQuelltext{
  public static void main(String[] args) throws IOException {
    URL url = new URL("http://www.bing.com");
    InputStream in = url.openStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    // Zwischen "fd/hpk2/" und ".jpg" befindet sich der Name des Bildes
    // Hier ist wahrscheinlich schon der erste Fehler
    Pattern p = Pattern.compile("fd/hpk2/",".*?",".jpg");
    // Ist an dieser Stelle der "reader" richtig?
    Matcher m = p.matcher(reader);
    while(m.find()) {
      System.out.println(m.group());
    }
  }
}
```

Was mache ich falsch?


----------



## Final_Striker (26. Aug 2011)

MrOctron hat gesagt.:


> Was mache ich falsch?



Versuche mal den Quelltext der Seite einfach in der Konsole auszugeben, dann wirst du es sehen.

Außerdem schau nach was die Methode matcher der Klasse Pattern als Parameter bekommt und was du ihr übergibst.
Pattern (Java Platform SE 6)


----------



## Gast2 (26. Aug 2011)

Java sagt dir doch schon was da falsch ist.
- compile erwartet nur einen Parameter, warum übergibst du drei?
(- der Punkt bei .jpg muss noch escaped werden)
- matcher erwartet eine CharSequence, also einen String. Warum übergibst du einen BufferedReader?
=> Zuerst den gesamten Quellcode laden, den übergibst du dann.


----------



## JohannisderKaeufer (26. Aug 2011)

> @JohannisderKaeufer
> Ich habe auch nicht vor unter C:\ zu speichern, aber mich wundert es trotzdem, wieso es nicht funktioniert.



Das nennt sich Security. Ab bestimmten Versionen von Windows darf man als normaler user nichts mehr direkt in C speichern.

Zu deinem Programm


```
import java.awt.*;
import java.io.*;
import java.util.regex.*;
import java.net.*;
import java.lang.*;
 
public class SucheImQuelltext{
  public static void main(String[] args) throws IOException {
    URL url = new URL("http://www.bing.com");
    InputStream in = url.openStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    //Compile erwartet entweder einen oder zwei parameter du hattest drei
    Pattern p = Pattern.compile("fd/hpk2/(.*?).jpg");
    // Matcher braucht keinen Reader sondern eine CharSequence
    // Mit reader.readLine() bekommt man jede Zeile als String
    while(reader.ready()){
      Matcher m = p.matcher(reader.readLine());
      while(m.find()) {
        System.out.println(m.group());
        System.out.println(m.group(1));//nur der Teil in der ersten Klammer
      }
    }
  }
}
```

Siehe Kommentare.


----------



## JohannisderKaeufer (26. Aug 2011)

EikeB hat gesagt.:


> (- der Punkt bei .jpg muss noch escaped werden)



Muss er? 

Muss er nicht! Die Wahrscheinlichkeit das ein anderes Zeichen als . vor jpg kommt ist relativ gering.

Und der . steht für ein (1) beliebiges Zeichen. Also auch für (.).


----------



## MrOctron (29. Aug 2011)

JohannisderKaeufer hat gesagt.:


> Das nennt sich Security. Ab bestimmten Versionen von Windows darf man als normaler user nichts mehr direkt in C speichern.
> 
> Zu deinem Programm
> 
> ...



Kann mir einer sagen, wie ich den Matcher in einen String umwandeln kann? 
	
	
	
	





```
System.out.println(m.group(1));
```
  Möchte den String gerne in den folgenden Code bei "imgname" einfügen. 
	
	
	
	





```
URL imgurl = new URL("http://www.bing.com/fd/hpk2/"+imgname+".jpg");
```


----------



## Gast2 (29. Aug 2011)

JohannisderKaeufer hat gesagt.:


> Muss er?
> 
> Muss er nicht! Die Wahrscheinlichkeit das ein anderes Zeichen als . vor jpg kommt ist relativ gering.
> 
> Und der . steht für ein (1) beliebiges Zeichen. Also auch für (.).


Ja muss er.
Es mag (hier) zwar trotzdem funktionieren, aber trotzdem ist es falsch und entspricht nicht dem was der user erwartet...



> Kann mir einer sagen, wie ich den Matcher in einen String umwandeln kann?




```
String imgname = m.group(1);
```


----------



## MrOctron (29. Aug 2011)

Hatte ich gemacht. Kriege jedoch ständig diese Fehlermeldung: 
cannot find symbol
Symbol: variable imgname


----------



## Gast2 (29. Aug 2011)

Dann hast du die variable sehr wahrscheinlich falsch deklariert. Zeig mal den Code.


----------



## MrOctron (29. Aug 2011)

Bitte nicht steinigen wenn der Code komplett falsch ist  Habe mich auch schon zu einem Java-Kurs für Anfänger im Oktober angemeldet. Bis dahin muss ich wohl so solche Fragen stellen 


```
import java.awt.*;
import java.io.*;
import java.util.regex.*;
import java.net.*;
import java.lang.*;

public class DownloadPicture{

  public static void main(String[] args) throws IOException {
    URL imgurl = new URL("http://www.bing.com/fd/hpk2/"+imgname+".jpg");
    InputStream is = imgurl.openStream();
    OutputStream os = new FileOutputStream("F:\\"+imgname+".jpg");
    byte[] buffer = new byte[1024];
    int byteReaded = is.read(buffer);
    while(byteReaded != -1){
      os.write(buffer,0,byteReaded);
      byteReaded = is.read(buffer);
    }
    os.close();
  }
  public static String imgname() {
    URL bing = new URL("http://www.bing.com");
    InputStream in = bing.openStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    Pattern p = Pattern.compile("fd/hpk2/(.*?).jpg");
    while(reader.ready()){
      Matcher m = p.matcher(reader.readLine());
      while(m.find()) {
        //System.out.println(m.group());
        //System.out.println(m.group(1));
        String imgname = m.group(1);
      }
    }
    return imgname;
  }
}
```


----------



## Gast2 (29. Aug 2011)

Variablen sind immer nur in dem Block gültig in dem sie deklariert wurden. Deine Variable imgname ist also nur innerhalb der while schleife sichtbar.
=> Leg imgname vor der Schleife an (initialisieren nicht vergessen) und weiße ihr später in der Schleife den richtigen Wert zu.

EDIT:
Der ganze Rest ist natürlich auch mehr oder weniger quatsch. Du rufst die Methode imgname nirgends auf.
Les dir am besten erstmal nen paar basics durch.

EDIT2:
Nachdem du die basics dann durch hast kannst du dich dem mal widmen:

```
public class DownloadPicture {

	public static void main(String[] args) throws IOException {
		String imageName = readImageName();
		
		System.out.println(imageName);
	}

	public static String readImageName() throws IOException {
		URL bing = new URL("http://www.bing.com");
		InputStream in = bing.openStream();
		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		
		StringBuilder content = new StringBuilder();
		String line = "";
		while ((line = reader.readLine()) != null) {
			content.append(line);
		}
		
		Pattern p = Pattern.compile("fd/hpk2/(.*?).jpg");
		Matcher m = p.matcher(content.toString());
		String imgname = "";
		if (m.find()) {
			imgname = m.group(1);
		}
		return imgname;
	}
}
```


----------



## MrOctron (30. Aug 2011)

EikeB hat gesagt.:


> Variablen sind immer nur in dem Block gültig in dem sie deklariert wurden. Deine Variable imgname ist also nur innerhalb der while schleife sichtbar.
> => Leg imgname vor der Schleife an (initialisieren nicht vergessen) und weiße ihr später in der Schleife den richtigen Wert zu.
> 
> EDIT:
> ...



Hab mich zwar noch nicht mit den Basics auseinandergesetzt, aber muss das nich in Zeile 4 und 6 imgname heißen?!


----------



## Gast2 (30. Aug 2011)

MrOctron hat gesagt.:


> Hab mich zwar noch nicht mit den Basics auseinandergesetzt, aber [...]?


Dann tu das bitte, die Frage beantwortet sich dann (hoffentlich) von selbst


----------

