Mein Problem ist folgendes ich versuche über Java ein Programm zu coden welches den Quelltext einer Seite ausliest um danach die urls zu filtern. Mein Problem ist aber das ich es einfach nicht hinbekommen die Urls zu filtern, den Quelltext hab ich schon einmal geschafft runterzuladen und zwar mit:
Code:
package quelltext;
import java.net.URL;
import java.util.Scanner;
public class Main {
public static void main(String[] args )throws Exception{
Scanner url = new Scanner(new URL("Url der Seite").openStream());
while(url.hasNextLine())
System.out.println(url.nextLine());
}
}
das funktioniert auch bis jetzt schön und gut nur weis ich nicht was ich benutzen muss um den Quelltext letztendlich von <a href="http://www nach "> zu filtern da sich der Inhalt der Urls ändert. Wahrscheinlich hab ich die Lösung übersehen da ich damit jetzt 10 stunden verbracht hab und 1000 mal gegoogelt bin ein totaler noob in Java aber hoffe das sich des bald ändert.
Ich hoffe ihr versteht mein Problem und könnt mir helfen im voraus schon mal danke Mr.T
aber wenn Du nur diese Urls aus den <a> tags suchen willst, dann würd ich eben erstmal nach "<a " und von dort aus nach dessen Ende "/a>" suchen. Dazwischen müsste ein "href" liegen das dann (von einem = und dann einem " gefolgt ) zu Deinem Url führt. Der geht dann wiederrum bis zum nächsten " wobei man "escapte" " (also \") auslassen sollte...wobei...die url Konvention sowas denk ich garnicht zulässt...gibts da nicht diese %irgendwas als Ersatz? Ich hoffe ich hab den Aufbau dieses tags richtig verstanden....wenn ja würd ichs so machen
(schaut lang aus...aber sind nur viele kommentare )
Code:
import java.util.Vector;
public class AhrefSuche {
public static void main(String[] args) {
String s = "kjfhdj<a href = \"http://www.google.at\" nochwas=\"juhuuu\"sdfs" +
"dfsdf>ein link</a> und dann stehn da so toole sachen wie <script ty" +
"pe=\"text/virtualaudio\"></script> und dann auch mal wieder ein" +
"<a href=\"www.lasmichinruh.dee_ehh\">und noch ein link</a>";
String[] urls = urls(s);
System.out.println("TestString: '"+s+"'");
System.out.println("urls:");
for(String u:urls){
System.out.println(u);
}
}
private static String[] urls(String htmlText){
Vector<String> urls = new Vector<String>();
// du suchst anfang und ende vom a-tag
int e = 0; // das brauchen wir um zu wissen von wo wir weitersuchen
while (true) {
int a = htmlText.indexOf("<a ", e);
if(a==-1){
// nix gefunden
break;
}
System.out.println("atag-Anfang gefunden bei Index = " + a);
e = htmlText.indexOf("/a>", a);
if(e==-1){
// nix gefunden
break;
}
// dazwischen muss ein href sein
String atag = htmlText.substring(a, e);
/*
* ich nehm noch die spaces raus, ein url kann sowas meines Wissens
* nach eh nicht haben um "href=" && "href =" zu
* finden
*/
atag = atag.replaceAll(" ", "");
// suche href in atag das \" ist im Endeffekt nur ein "
int ha = atag.toLowerCase().indexOf("href=\"".toLowerCase());
ha += "href=\"".length();
// wenn wir keinen href Anfang finden suchen wir auch kein Ende
if (ha == -1) {
System.err.println("Kein 'href' im a-tag!!");
} else {
// suche das ende von href also ein " (ich muss hier \"
// schreiben wie oben) wir suchen ab dem gefundenen href
int he = ha;
do {
he = atag.indexOf("\"", he + 1);
} while (atag.charAt(he - 1) == '\\' || he == -1);
if (he != -1) {
// und wenn ich mich nicht irre müsste das dann der url sein
urls.add(atag.substring(ha, he));
}
}
}
// wandelt den Vector noch in ein Array
return urls.toArray(new String[]{});
}
}
...und in der java api gibts auch noch ne menge zu entdecken
Diesen ganzen extreme-lowlevel-kram braucht man nicht, für solche simplen sachen gibts in der api schon genug moeglichkeiten, hier sind zwei:
Code:
Code:
//fuer den ersten ansatz:
import java.util.regex.*;
//fuer den zweiten ansatz ( externe jars jdom und jaxen erforderlich)
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.xpath.*;
import java.io.*;
import java.util.*;
class TEST{
public static String reverse(String s){
return s.equals("")?"":reverse(s.substring(1))+s.charAt(0);
}
public static void main(String[] args) throws JDOMException, IOException{
// beispiel-html code
String html=
"<html>" +
" <div>" +
" <h1>Lalalalala</h1>" +
"
blbblhabalbalabla [url='www.yahoo.com']yahoo[/url] dbajshdbjadbasdhga</p>" +
" [url='www.google.de']google[/url]" +
" </div>" +
"</html>";
System.out.println("Ansatz 1:");
/*ANSATZ 1: brutal mit regex drauf einpruegeln
* nachteile: man muss zB auf kleinigkeiten wie "" oder '' achten obwohl es in xml dasselbe bedeutet
*/
Matcher matcher=Pattern.compile("<a[^<>]*href[\t ]*=[\t ]*[\"|']([^\"']*)[\"|'][^<>]*>").matcher(html);
while(matcher.find()) System.out.println("treffer="+matcher.group(0)+" url="+matcher.group(1));
System.out.println("\nAnsatz 2:");
/*ANSATZ 2: etwa mit jdom document bauen, per xpath die a-tags raussuchen
* nachteil: die jdom-geschichte ist anfangs ein wenig unuebersichtlich
* und man muss sich mit zwei externen jars rumpruegeln
* (in javax gibts auch irgendsowas, aber ich find's nicht so intuitiv)
*/
Document doc=(new SAXBuilder()).build(new StringReader(html));
for(Element e:(Collection<Element>)XPath.selectNodes(doc, "//a")){
System.out.println("element="+e.toString()+" url="+e.getAttributeValue("href"));
}
}
}
Die erste funktioniert auf buchstaben-ebene, da lässt man den regex drauf los und holt sich die entsprechenden zeichenketten. Wenn das kein valides xml ist, ist das dem regex vollkommen egal. Wenn du das später in irgendeinen bot reinbauen willst, der auf düsteren verstümmelten seiten herumwandert, dann musst du das wohl auf diese etwa unsauberere art machen, weil es seiten gibt, die eben kein valides xml beinhalten, aber trotzdem irgendwie von browsern wohl oder übel dargestellt werden.
Die zweite möglichkeit setzt voraus, dass die seite zumindest ein gültiges xml-dokument ist. Dann wird das document geparst, und man kann sich gemütlich mit xpath die elemente aussuchen, die man grad haben will.