# HTML File Parsen / auf <option> elemente zugreifen



## mad_dark_angel (10. April 2006)

hey Leute,
hab da ein problem...
hab versucht eine HTML einzulesen... speichere die momentan in einem HTMLDocument object. ich bekomme auch wunderbar zugriff auf <a href=""> etc. aber auf inputs war am anfang kein zugriff. hab mir bissle was zurecht gebastelt und habe nun zugriff auf die inputs (also attributes etc)
allerdings bekomme ich es nirgends hin vernünftig auf die <option> elemente zuzugreifen!

den TestCase gibts unter http://nopaste.php-q.net/204304

hab dann versucht den NekoHTML Parser in verbindung mit xerces zu benutzen (ist sowieso besser geeignet da ich auch nicht-valides html bestmöglich einlesen muss)
aber mit NekoHTML komm ich überhaupt nicht klar.

vieleicht kann mir jemand helfen, entweder an meiner geposteten source, oder noch besser: beispiel mit NekoHTML für mein problem (also zugriff auf die <option> und <input>

danke im vorraus


----------



## flashray (11. April 2006)

Hallo dunkler Engel,

ich hab das mal für eines meiner Programme wie folgt implementiert. Allerdings ist das keine allgemeine Lösung welches für alle Webseiten funktioniert, sondern müsste je nach Webseite angepasst werden.

Wenn das jemand eleganter, sicherer zu lösen weiß würde ich auch gern den Ansatz hören!


```
public class ParseOptionExample {

	// So sieht ja Beispielsweise der relevante Abschnitt des Quellcodes aus 
	
//	<select name="f" onchange="if(this.options[this.selectedIndex].value != -1) {window.location.href = this.options[this.selectedIndex].value;}">
//	<option value="-1">Forum auswählen</option>
//	<option value="-1" class="h1c">&nbsp;</option>
//	<option value="-1" class="h1c">&nbsp;&nbsp;BWL</option>
//	<option value="viewforum.php?f=50" class="h1">&nbsp;&nbsp;- Absatzwirtschaft</option>
//	<option value="viewforum.php?f=49" class="h1">&nbsp;&nbsp;- Finanzwirtschaft</option>
//	<option value="viewforum.php?f=48" class="h1">&nbsp;&nbsp;- Handels- und Steuerbilanzen</option>
//	<option value="viewforum.php?f=24" class="h1">&nbsp;&nbsp;- Kosten- und Erlösrechnung</option>
//	<option value="viewforum.php?f=45" class="h1">&nbsp;&nbsp;- Produktionswirtschaft</option>
//	</select>
	
	private String[] date;

	private int h, k, l;

	public void fetch() {
		String dates = "Quellcode der Webseite als String.";
		
		// Finde den Relevanten Abschnitt und schneide den Anfang
		h = dates.indexOf("<select name=\"f\"");
		dates = dates.substring(h);
		// Finde das Ende des Select Tags und schneide den Select Tag ab
		k = dates.indexOf('>');
		dates = dates.substring(k + 1);
		// Finde das abschließende Select Tag und schneide das Ende mit dem Select Tag ab  
		l = dates.indexOf("</select>");
		dates = dates.substring(0, l);

		// Nun hast du nur noch die Options mit Anfang und EndTags
		
		// Ersetzte alle Anfangstags mit "", also lösche sie
		dates = dates.replaceAll("<option>", "");

		// Wenn irgendwelche besonderen Anfangstags vorhanden sind,
		// die von den restlichen abweichen muss man diese gesondert löschen
		dates = dates.replaceFirst("<option selected>", "");
		
		// Ersetze alle Endtags mit einem Komma ","
		dates = dates.replaceAll("</option>", ",");
		
		// Lösche das letzte Komma
		dates = dates.substring(0, dates.length() - 1);

		// Jetzt hat man nur noch die Werte der optiontags jeweils getrennt mit einem Komma
		// Splitte den String an den Kommas und speichere die Werte in ein Array
		// zur weiterverarbeitung
		date = dates.split(",");
		
		// Der Code ist aus meinem Programm, der obige Webseitenquellcodeabschnitt
		// nicht aus der Webseite die mein Programm parst.
		// D.h. die obigen parsebefehle stimmen vielleicht nicht ganz genau überein.
		// Er müsste je nach Quellcode der zu parsenden Webseite angepasst werden.
	}
}
```


Vg Erdal


----------



## mad_dark_angel (11. April 2006)

nagut okay so kann man das auch machen...
aber dann hätte ich das an deiner stelle lieber mit RegEX Pattern gemacht!

so nach dem Motto:

Pattern pPattern = Pattern.compile(sPattern);
Matcher m        = pPattern.matcher(sHTML);
while(m.find()) {
  m.group(iGroup);
}

ich bräuchte aber halt n HTMLParser was auch invalides HTML parset (NekoHTML) damit ich dann als object auf die elemente zugreifen kann...

danke @ flashray, aber ich bräuchte eher hilfe wie ich NekoHTML zum laufen bekomme bzw eher ein Beispiel für mein Problem wie ich das mit NekoHTML mache!


----------



## RedWing (11. April 2006)

Hallo,

wie waere es denn wenn du auf eine externe Bibliothek zurueckgreifst?

Tidy bietet sich da bspw an:

http://jtidy.sourceforge.net/

Ein Beispiel koennte so aussehen:


```
import org.w3c.tidy.Tidy;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import java.net.URL;
import java.util.ArrayList;

public class TidyExample{
	public static void printSelectedTags(Node parent, String ... selectedTags){
		for(int i = 0; i < selectedTags.length; i++){
			if(parent.getNodeName().equals(selectedTags[i])){
				NamedNodeMap nmap = parent.getAttributes();
				System.out.print("<" + parent.getNodeName());
				for(int j = 0; j < nmap.getLength(); j++)
					System.out.print(" " + nmap.item(j).getNodeName() + "=\"" + nmap.item(j).getNodeValue() + "\"");
				System.out.println(">");
			}
		}

		for(int i = 0; i < parent.getChildNodes().getLength(); i++)
			printSelectedTags(parent.getChildNodes().item(i), selectedTags);
	}
	
	public static void main(String[] args) throws Exception{
		Tidy t = new Tidy();
		t.setXmlTags(false);
		URL uri = new URL("http://www.abilix.de/de/kontakt/");
		Node rootElement = t.parseDOM(uri.openConnection().getInputStream(), null);
		printSelectedTags(rootElement, "option", "input");
	}
}
```

Gruß

RedWing


----------



## mad_dark_angel (12. April 2006)

ja das sieht doch schonmal gut aus...
lies auch den invaliden HTML korrekt ein.... perfekt!

danke!


----------

