Crawler?

Hallo, haben folgenden Code bekommen:

Java:
package crawler;



import java.io.*;

import java.net.*;

public class Connector {
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            try {
                URL               u   = new URL("http://www.gamestar.de/");
                InputStream       in  = u.openStream();
                InputStreamReader isr = new InputStreamReader(in);
                BufferedReader    br  = new BufferedReader(isr);
                int               c;
                
                System.out.println (u);

                while ((c = br.read()) != -1) {
                    System.out.write(c);
                 
                }
            } catch (IOException e) {
                System.err.println(e);
            }
        }
    }

}

und eigentlich sollte der den Html-Code der Webseite auf der Console anzeigen...aber irgendwie passiert einfach garnichts...warum?
 

StrikeTom

Bekanntes Mitglied
In diesem Teil:
Java:
for (int i = 0; i < args.length; i++) ...
zählt das programm solange bis args.length zuende ist.
Allerdings hat args[] normalerweise garkeine werte.
Wenn du jetzt diesen Teil weglässt(nur das for) dann bist du schonmal einen Schritt weiter.
Mehr konnte ich noch nicht herausfinden.
 

agentone

Bekanntes Mitglied
Ich hab dein Programm mal ein bisschen umgeschrieben:

Java:
package crawler;

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

public class Connector {
    public static void main(String[] args){
            try {
                URL url=new URL("http://www.gamestar.de/");
                InputStreamReader reader = new InputStreamReader(url.openStream());
                int c;

                System.out.println(url);

                while ((c = reader.read()) != -1) {
                    System.out.write(c);

                }
            } catch (Exception e) {
                System.err.println(e);
            }
    }
}

So funktioniert es ohne Probleme. Da ist nur die Frage, was die for-Schleife
Code:
for (int i = 0; i < args.length; i++)
bringen sollte?? Das heißt nämlich, dass nach Anzahl der übergebenen Parameter das Programm entsprechend oft ausgeführt wird. Irgendwie sinnlos.... :)
 

AlexSpritze

Bekanntes Mitglied
wie bekomme ich das hin das er mir nur die Links die auf der Webseite sind auf der Console ausspuckt?

Die HTML-Seite parsen.

Über die while-Schleife liest du ja den Inhalt der Seite linear ein. Sobald du auf eine Zeichenfolge "<a " triffst, weißt du, dass es sich potentiell um einen Link handeln kann. Das heißt in dem Tag müsste noch irgendwo ein "target=" auftauchen, hinter dem = dann der Link. Und den gibst du dann aus. Wenn der HTML-Code nicht perfekt/sauber ist, wird die Sache schwieriger.
 

AlexSpritze

Bekanntes Mitglied
kannst du mir vllt ein kleines Beispiel geben wie das aussehen muss?:oops:

Das hier ist recht low-level, und auch ungetestet. Zur Not etwas mit den substring-Indices rumspielen ;)

Java:
import java.io.*;
import java.net.*;

class Connector {

  public static void main( String[] args ) {
    try {
      URL url = new URL("http://www.gamestar.de/");
      InputStreamReader reader = new InputStreamReader(url.openStream());
      int c;
      StringBuilder sb = new StringBuilder();
      boolean outputLink = false; // sind wir innerhalb eines links?

      System.out.println(url);

      while ((c = reader.read()) != -1) {

        if ( outputLink && sb.substring(sb.length() - 3, sb.length()).equalsIgnoreCase("<a ") ) {
          System.out.print(sb.substring(sb.length() - 3, sb.length()));
          outputLink = true;
        } else if ( sb.substring(sb.length() - 4, sb.length()).equalsIgnoreCase("</a>") ) {
          System.out.println(sb.substring(sb.length() - 4, sb.length()));
          outputLink = false;
        }
                sb.append((char) c);
        if ( outputLink ) {
          System.out.write(c);
        }
      }
    } catch (Exception e) {
      System.err.println(e);
    }
  }
}

Das findet auch HTML-Tags der Form <a name="anchor">Anker</a>, was ja keine Links sind.
 
also bei mir schmeißt er das hier raus:

java.lang.StringIndexOutOfBoundsException: String index out of range: -4

Verdammt ich will das echt verstehen aber irgendwie komme ich nicht weiter...könntest du vllt ein paar Kommentare machen damit ich das besser nachvollziehen kann?

Vielen Dank!
 
S

SlaterB

Gast
WAS verstehst du daran nicht?
das sind doch alles einfache Befehle, length(), substring() usw.,
wenn man sie nicht eh schon kennt, wie es sein sollte, dann kann man sie nachschlagen mit ausführlicher Erklärung

was da mit dem boolean true/ false passiert ist sicher etwas komplizierter, aber einfach ablaufen lassen und nebenbei beobachten was passiert
(nur das Endergebnis anschauen hilft natürlich nicht, Zwischenergebnisse pro Schleifendurchlauf ausgeben!, welches if schlägt wann zu)

der Fehler ist hier sicherlich am Anfang, bevor nicht 4 Zeichen da sind kann man keine rückwirkenden substrings() ausschneiden
 
T

Tomate_Salat

Gast
wie wäre es mit Regex?
Java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Main
{
	public static void main(String[] args)
	{
		try
		{
			URL 			url	= new URL("http://www.gamestar.de/");
	        BufferedReader	br	= new BufferedReader(new InputStreamReader( url.openStream() ));
	        String 			read= "";
	        
	        while( br.ready() )
	        	read	+= br.readLine();
	        
	        Pattern 		p	= Pattern.compile("<a.*?href=\"([^\"]+)\".*?>([\\w]+?)</a>");
	        Matcher			m	= p.matcher( read );
	        
	        while( m.find() )
	        {
	        	System.out.println( m.group(2) + " => " + m.group(1) );
	        }
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}
}

Ausgabe:
Code:
Hardware => /hardware/
Community => /community/
Konsolen => http://www.gamepro.de/
GameStar => /
Home => javascript:document.headersearch.submit();
News => /
Videos => /news/
Tests => /index.cfm?pid=1587
Previews => /tests/
Specials => /previews/
Spieletipps => /specials/
Downloads => /spieletipps/
Screenshots => /downloads/
Charts => /charts/
Releaseliste => /releaseliste/wochenkalender/
Wallpaper => /wallpaper/
Spiele => /spieledatenbank/
Babes => /babes/
Heftarchiv => /heftarchiv/
Newsletter => /newsletter/
GameStar => /shop
GameStar => /preview/action/3rdpersonshooter/2314916/dead_space_2.html
Cheats => #top
Stichworte => /stichwortverzeichnis/
Impressum => /lesertests/
Kontakt => /kontakt/
Mediadaten => /mediadaten/
Datenschutz => /datenschutz/
Premium => /index.cfm?pid=133
Jobsuche => http://www.computerwoche.de/stellenmarkt/
Intellitxt => /intellitxt
Archiv => /archiv/2010/
Sitemap => /sitemap/
Spiele => /spiele/
GamePro => http://www.gamepro.de
TecChannel => http://www.makinggames.de
Macwelt => http://www.macwelt.de
Computerwoche => http://www.digital-world.de
CIO => http://www.cio.de
ChannelPartner => http://www.central-it.de

MFG

Tomate_Salat
 
Zuletzt bearbeitet von einem Moderator:
T

Tomate_Salat

Gast
zeig mal deinen code

Anmerkung
Der Filter lässt auch Bilder-Beschreibungen im Ergebnis zu:
Java:
Pattern 		p	= Pattern.compile("<a.*?href=\"([^\"]+)\".*?>(.+?)</a>");

Aber im Prinzip sollten dir auch nur die Hyperlinks reichen, die könntest du so bekommmen:

Java:
Pattern 		p	= Pattern.compile("<a.*?href=\"([^\"]+)\".*?>.+?</a>");
Matcher			m	= p.matcher( read );
	        
while( m.find() )
{
     	System.out.println( m.group(1) );
}
 
Java:
package crawler;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) {
        try {
            URL url = new URL("http://www.gamestar.de/");
            BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
            String read = "";

            while (br.ready()) {
                read += br.readLine();
            }

            Pattern p = Pattern.compile("<a.*?href=\"([^\"]+)\".*?>([\\w]+?)</a>");
            Matcher m = p.matcher(read);

            while (m.find()) {
                System.out.println(m.group(1));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

passiert einfach nichts...
 
Ok, es funktioniert nicht mit allen Seiten...komisch!

Naja bei z.B w w w.heise.de funktioniert es.
will jetzt alles in eine textdatei schreiben was auf der Console steht:

Veranstaltungen Kostenlose Kleinanzeigen aufgeben und finden im heise-marktplatz Deutschland
Newsletter heise-online.mobi/
Downloads heise Software-Verzeichnis
OpenOffice Gelungene iPhone-Apps, Themen-Special im heise Software-Verzeichnis
Firefox Futter für Firefox 3, Themen-Special im heise Software-Verzeichnis
Bestbewertet Spielen im Browser, Themen-Special im heise Software-Verzeichnis
doPDF DBF Viewer, Download bei heise
Zettelkasten µTorrent, Download bei heise
H2testw Neue Software für Windows, Mac, Linux und Smartphones, Download bei heise
TrueCrypt WSUS Offline Update (ehemals c't Offline Update), Download bei heise
PuTTY PuTTY, Download bei heise
IrfanView IrfanView, Download bei heise
Firefox Firefox, Download bei heise
Hardware Bestbewertete Software für Windows, Mac, Linux und Smartphones, Download bei heise
CPUs heise online-Preisvergleich: CPUs / Deutschland
Mobiltelefone heise online-Preisvergleich: CPUs/AMD Sockel AM3 / Deutschland
Hardware heise online-Preisvergleich: Mobiltelefone/UMTS ohne Vertrag / Deutschland
CPUs heise online-Preisvergleich: CPUs / Deutschland
Hardware heise online-Preisvergleich: CPUs/AMD Sockel AM3 / Deutschland
Grafikkarten heise online-Preisvergleich: Grafikkarten / Deutschland
PCIe heise online-Preisvergleich: Grafikkarten/PCIe / Deutschland
Hardware heise online-Preisvergleich: Intel X25-M G2 Postville 80GB, 2.5", SATA II (SSDSA2MH080G2C1/SSDSA2MH080G201) / Deutschland
Festplatten heise online-Preisvergleich: Festplatten / Deutschland
Hardware heise online-Preisvergleich: Festplatten/Solid State Drives (SSD) / Deutschland
Festplatten heise online-Preisvergleich: Festplatten / Deutschland
Hardware heise online-Preisvergleich: Festplatten/SATA 3.5" / Deutschland
Grafikkarten heise online-Preisvergleich: Grafikkarten / Deutschland
PCIe heise online-Preisvergleich: Grafikkarten/PCIe / Deutschland
Hardware AVM Fritz!Box Fon WLAN 7390 ab 229.60 &euro; | heise online-Preisvergleich
Hardware heise online-Preisvergleich: Netzwerk WLAN/Funk / Deutschland
Festplatten heise online-Preisvergleich: Festplatten / Deutschland
Hardware heise online-Preisvergleich: Festplatten/SATA 3.5" / Deutschland
Grafikkarten heise online-Preisvergleich: Grafikkarten / Deutschland
PCIe heise online-Preisvergleich: Grafikkarten/PCIe / Deutschland
Telepolis Download des Tages
Veranstaltungen Kostenlose Kleinanzeigen aufgeben und finden im heise-marktplatz Deutschland
Datenschutzhinweis The H: Security news and Open source developments

und ich Probiere das mit der FileWriter Methode:

Java:
package crawler;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) {
        try {
            URL url = new URL("http://www.heise.de");
            BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
            String read = "";

            while (br.ready()) {
                read += br.readLine();
            }

            Pattern p = Pattern.compile("<a.*?href=\"http://([^\"]+)\".*?>([\\w]+?)</a>");
            
            Matcher m = p.matcher(read);

            while (m.find()) {
                System.out.println(m.group(2)+"    "+m.group(1));

                File datei = new File("test.txt");
                FileWriter schreiber = new FileWriter(datei);
                schreiber.write(m.group(2)+"    "+m.group(1));
                schreiber.close();

            }
        } catch (IOException e) {
            e.printStackTrace();
            
            
        }
    }
}

Die Datei wird dann auch erstellt, aber in ihr steht nur:

Datenschutzhinweis w w w.h-online.com/

warum nicht alles?
 
S

SlaterB

Gast
von mir wieder einfache Vorschläge, mehr Weg als Ziel ;) :
klappt überhaupt die Eingabe, was enthält read nach der Schleife in Zeile 20?
ersetze sowieso dieses aufwendige Einlesen testweise durch ein simples

String read = "test <a sowieso test .. ";
geht darauf das Pattern?
teste einfachere Pattern wie
Pattern.compile("<a");
gehen die?

edit: ok, hatte sich erledigt,

zum neuen Problem:
die Datei nur EINMAL VOR der Schleife erstellen, sonst überschreibst du jedes mal,
oder Parameter append verwenden
 
T

Tomate_Salat

Gast
äh ach ja, was mir grad so im drüberlesen auffällgt: man sollte auch die lese-zugriffe wieder freigeben:
Java:
reader.close();

@SlaterB: Ja natürlich klappt das einlesen nach zeile 20 ;-)
 
habe die Datei jetzt vor der Schleife erstellt aber irgendwie funktioniert das trotzdem nicht.

Java:
package crawler;

//~--- JDK imports ------------------------------------------------------------

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;

import java.net.URL;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) throws IOException {
        try {
            URL            url  = new URL("http://www.heise.de");
            BufferedReader br   = new BufferedReader(new InputStreamReader(url.openStream()));
            String         read = "";
            Writer         fw   = null;
            fw = new FileWriter("fileWriter.txt");

            while (br.ready()) {
                read += br.readLine();
            }

            Pattern p = Pattern.compile("<a.*?href=\"http://([^\"]+)\".*?>([\\w]+?)</a>");
            Matcher m = p.matcher(read);

            while (m.find()) {
                System.out.println(m.group(2) + "    " + m.group(1));

                try {
                   
                    fw.write(m.group(2) + "    " + m.group(1));

                } catch (IOException e) {
                    System.err.println("Konnte Datei nicht erstellen");
                } finally {
                    if (fw != null) {
                        try {
                            fw.close();
                        } catch (IOException e) {}
                    }
                }

                br.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
T

Tomate_Salat

Gast
den lesezugriff würde ich direkt vorm [c]Pattern[/c] schließen.

Seltsam, bekommst du überhaupt was angezeigt bei
Java:
System.out.println("--- TEST-AUSGABE ---");
?
 
hab es jetzt anders hinbekommen...hab ich im Netz gefunden.
Jetzt wird direkt alles aus der Console in eine Datei geschrieben.
Ist warscheinlich nicht die schönste Methode aber naja.
Trotzdem wir noch auf der Console:
Code:
run:
Registrieren  >>> www.pcgames.de/
ERSTELLEN ERFOLGREICH (Gesamtzeit: 0 Minuten 5 Sekunden)

rausgeschmissen...warum? und wie bekomme ich es hin das es in eine Datei geschrieben wird und es aber trotzdem auf der Console ausgegeben wird?

hier mein Code:
Java:
package crawler;



import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Writer;

import java.net.URL;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) throws IOException {
        try {
            URL            url  = new URL("http://www.pcgames.de");
            BufferedReader br   = new BufferedReader(new InputStreamReader(url.openStream()));
            String         read = "";

            while (br.ready()) {
                read += br.readLine();
            }

            br.close();

            Pattern p = Pattern.compile("<a.*?href=\"http://([^\"]+)\".*?>([\\w]+?)</a>");
            Matcher m = p.matcher(read);

            while (m.find()) {
                System.out.println(m.group(2) + "  >>> " + m.group(1));
               

                File file = new File("ok.txt");

                try {
                    System.setOut(new PrintStream(new FileOutputStream(file,true)));
                    System.out.print(System.currentTimeMillis());
                } catch (FileNotFoundException e) {
                    e.printStackTrace();

                } 
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
T

Tomate_Salat

Gast
Java:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        try {
            URL            url  = new URL("http://www.pcgames.de");
            BufferedReader br   = new BufferedReader(new InputStreamReader(url.openStream()));
            String         read = "";
 
            while (br.ready()) {
                read += br.readLine();
            }
 
            br.close();
 
            Pattern p = Pattern.compile("<a.*?href=\"http://([^\"]+)\".*?>([\\w]+?)</a>");
            Matcher m = p.matcher(read);
            
            
            File file				= new File("ok.txt");
            FileOutputStream fout	= new FileOutputStream( file );            
            
            while (m.find()) {
                String write		= m.group(2) + "  >>> " + m.group(1) + "\r\n";
                fout.write( write.getBytes() );
            }
            
            fout.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Ich fange mal an zu erklären, was an deinem Code alles nicht so toll ist:

1.) Du deklarierst immer und immer wieder [c]file[/c] mit dem gleichen Wert. Soetwas packt man nicht in eine Schleife! Initalisier die Variable ganz einfach einmal vor der Schleife
2.) Im Prinzip das gleiche: du setzt immer und immer wieder einen neuen outputstream! Abgesehen davon, dass das hier absolut nicht notwendig ist, würde man soetwas auch einmal außerhalb der schleife erledigen.
3.) Entweder du setzt ein Try-Catch für die IOException oder du schmeist sie aus der Methode (throws...) aber beides zusammen macht keinen Sinn

Wenn du nicht weist, wie man einen String an einen Outputstream weitergibt, der nur mit [c]bytes[/c] umgehen kann, einfach gezielt fragen ;-) oder einfach gleich [c]BufferedWriter[/c] nehmen, der kennt eine Methode um Strings zu schreiben.

MFG

Tomate_Salat
 

Ähnliche Java Themen


Oben