RegEx mit HTML Parser für Java möglich?

Pharadox

Mitglied
Hi,

ich habe aktuelle ein Problem und finde keine Lösung.

Ich möchte folgendes realisieren:

1. Es gibt eine Webseite im Netz (HTML) auf der sich ein immer wiederkehrendes HTML-Konstrukt befindet, so:

<html>
...
<div id="1"><p>Schwefel</p><a href="#abc1">Link</a></div>
<div id="2"><p>Gold</p><a href="#ihl2">Link</a></div>
...
<div id="50"><p>Eisen</p><a href="#efd50">Link</a></div>
...
</html>

2. Jedes Konstrukt möchte ich auf einen gewissen Wert - den ich vorher angebe - prüfen.
Also wenn ich vorher sage, ich möchte nach Gold suchen, soll jedes Konstrukt durchsucht werden nach Gold und die Position zurückgegeben werden.
Im Beispiel wäre Gold an der 50. Stelle gefunden worden.


Das Problem ist, auch einen Browser (User Agent) zu simulieren.

Mit PHP würde ich mit cURL die Seite auslesen und mit einer RegluarExpression überprüfen.

Aber wie löse ich das mit Java?
Kann ich sowas mit einem HTML Parser durchführen?
Jericho
HTML Parser


Ich hoffe Ihr könnt mir näheres dazu sagen, vllt. hat der ein oder andere schonmal so etwas gemacht?


Besten Dank und einen schönen Tag.
Grüße
 

XHelp

Top Contributor
Geht es einfach nur um die Position im Text? Da brauchst du weder einen Parser, noch RegEx: [japi]String#indexOf(java.lang.String)[/japi]
 

Pharadox

Mitglied
Hi,

ne, leider nicht so einfach.

Im Idealfall (vllt geht es auch einfacher) habe ich alle sich wiederholenden HTML-Strukturelemente in einem/r Array/Hashmap, also so in etwa:
Java:
...
     [1]=>{"p-Tag"="Schwefel", "a-Tag"="Link"},
     [2]=>{"p-Tag"="Gold", "a-Tag"="Link"},
     ....
     [50]=>{"p-Tag"="Eisen", "a-Tag"="Link"},
     ....
...

Dann gehe ich den/die Array/Hashmap durch und schau wann der gesuchte Begriff auftaucht:
(Pseudocode)
Java:
String suchbegriff = "gold";
Int i = 0;
for( i <= elements.length ){
   if( suchbegriff.equals( elements[i]['p-Tag'] ) ){
        break;
   }else
        continue;
}
Position der Fundstelle ist 2.

Ich hoffe das ist verständlicher!?

Beste Grüße
 

XHelp

Top Contributor
Naja, verständlich ist es nur mit der Hintergedanken, dass im 1. Post nicht Gold an der 50. Stelle zu finden sei, sondern Eisen.

HTML-Parser ist schon die richtige Richtung. Falls der HTML-Code wirklich so aussieht wie es oben steht, dann kannst du es auch als normales XML parsen, Beispiele gibt es im Netz wie Sand am Meer.
 

freez

Top Contributor
Wenn die Seite nicht zu kompliziert ist, und sich eindeutige Suchstrings finden lassen, hat man mit String.indexOf und String.substring ziemlich gute Chancen. Ich habe selbst schon erfolgreich so gearbeitet:
Zuerst den Anfang (ggfs. das Ende auch) wegschneiden, und dann einen Suchstring definieren, mit dem du ein Element eindeutig finden kannst (dieses kann auch noch Müll enthalten). Somit hast du eine Liste mit deinen Daten und ggfs. Code drin. Dann gehst du noch mal über die Liste und schneidest den unnötigen Code noch weg.

das Ganze funktioniert natürlich nur so lange, wie sich der Teil der Seite nicht ändert, welche du versuchst mit deinem Suchstring zu finden. Also immer statische Elemente suchen, damit du auf die dynamischen Daten zugreifen kannst.
 

Marco13

Top Contributor
Eine subjektive Erfahrung: HTML mit String.indexOf und Co auseinanderzupflücken geht zu einem gewissen Grad, aber es wird schnell ein Krampf. Da kommt dann mal irgendwann die Zeile
<div id="2"><p>Katzen-Gold</p><a href="#ihl2">Link</a></div>
vor, oder es ist anders formatiert oder irgendwelche div-classes angegeben oder sonstwas, und dann wird's schrecklich unübersichtlich. Ich mußte (wollte) auch mal HTML in so ähnlicher Form zerpflücken und analysieren, und habe einige HTML-Parser/Verarbeiter angeschaut und ausprobiert. Von denen, die ich ausprobiert hatte, fand ich den schon verlinkten Jericho HTML Parser für solche Sachen mit Abstand am besten: Er ist sehr robust, leicht zu verwenden, gut dokumentiert, und anhand der Beispiele kann man sich sehr schnell eigene Funktionen basteln.
 

Guardi

Bekanntes Mitglied
Man kann dafür die WebDrier API von Selenium auch ganz gut "missbrauchen". Hängt davon ab ob Geschwindigkeit ein Kriterium ist.
Ist zwar ein Test-Framework, aber du kommst da ohne Weiteres über z.B. XPath oder einfach die ID an die gewünschten Elemente und die Anwendung ist wirklich kinderleicht. Du nimmst dann am Besten den HTMLUnit-Driver.

Selenium 2.0 and WebDriver &mdash; Selenium Documentation
 

Pharadox

Mitglied
Hi,

erstmal vielen Dank für eure vielen Antworten.

Ich hab da was feines für euch:

Java:
package to.specular.elementposition;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

import net.htmlparser.jericho.*;
import java.net.*;
import java.io.*;
import java.util.*;

public class init extends JFrame {
	
	private JLabel lblKeyword;
	private JTextField keyword;
	private JButton exec;
	private JScrollPane sp;
	private JTextArea output;
	
	public init(){
		this.setTitle("HTML Element Position");
		this.setResizable(true);
		this.setLayout(new GridBagLayout());
		GridBagConstraints gbc;
		
		this.lblKeyword = new JLabel("Search for:");
		gbc=makeGBC(0, 0, 1, 1);
		gbc.anchor = GridBagConstraints.WEST;
		this.add(this.lblKeyword,gbc);
		this.keyword = new JTextField();
		this.keyword.setText("test");
		gbc=makeGBC(0, 1, 1, 1);
		gbc.fill=GridBagConstraints.HORIZONTAL;
		this.add(this.keyword, gbc);
		this.exec = new JButton("Execute");
		gbc=makeGBC(0, 2, 0, 1);
		gbc.anchor = GridBagConstraints.EAST;
		gbc.fill=GridBagConstraints.BOTH;
		gbc.weightx=1.0;
		gbc.weighty=0.1;
		this.add(this.exec, gbc);
		this.output = new JTextArea();
		gbc=makeGBC(0, 3, 1, 2);
		gbc.fill=GridBagConstraints.BOTH;
		gbc.weightx=1.0;
		gbc.weighty=1.0;
		this.add(this.output, gbc);
		this.sp = new JScrollPane(this.output);
        this.sp.setPreferredSize(new Dimension(500,100));
		gbc = makeGBC(0, 3, 1, 1);
		gbc.fill=GridBagConstraints.BOTH;
		gbc.weightx=1.0;
		gbc.weighty=1.0;
		this.add(this.sp, gbc);
		
		this.exec.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					String pos = getPosition();
					System.out.println("Position: "+pos);
					output.setText( pos );
				}
		});
		
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		this.setPreferredSize(new Dimension(700,600));
		this.pack();
		this.setLocation
		(
				(Toolkit.getDefaultToolkit().getScreenSize().width-this.getWidth())/2,
				(Toolkit.getDefaultToolkit().getScreenSize().height-this.getHeight())/2
		);
		this.setVisible(true);
	}
	
	private String getPosition()
	{
		String urlString = "";
		String result="";
		if( !this.keyword.getText().isEmpty() )
		{
			URL url;
			URLConnection uc;
			StringBuilder parsedContentFromUrl = new StringBuilder();
			
			//File is UTF-8 and HTML charset UTF-8
			//urlString = "http://devcon.pcriot.com/cube/javahtmlparsing/file-utf8_html-utf8.html";
			
			//File is ANSI and HTML charset windows-1250
			//urlString = "http://devcon.pcriot.com/cube/javahtmlparsing/file-ansi_html-windows1250.html";
			
			//File is ISO 8859-2 and HTML charset ISO 8859-1
			urlString = "http://devcon.pcriot.com/cube/javahtmlparsing/file-iso88592_html-iso88591.html";
			
			//
			MicrosoftConditionalCommentTagTypes.register();
			PHPTagTypes.register();
			PHPTagTypes.PHP_SHORT.deregister();
			MasonTagTypes.register();
			
			try{
				url = new URL( urlString );
				uc = url.openConnection();
		        uc.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0");
		        uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		        uc.connect();
		        uc.getInputStream();
		        BufferedInputStream in = new BufferedInputStream(uc.getInputStream());
		        int ch;
		        while ((ch = in.read()) != -1) {
		            parsedContentFromUrl.append((char) ch);
		        }
		        
				Source source = new Source( parsedContentFromUrl );
				
				//result = source.getRenderer().toString();
				result = source.toString();
			}
			catch (Exception e) {
				result = e.toString();
			}
			//
			
			return result;
		}else{
			return "No keyword given";
		}
	}
	
	private GridBagConstraints makeGBC(int gx, int gy, int gw, int gh)
	{
		GridBagConstraints gbc=new GridBagConstraints();
		gbc.gridx=gx;
		gbc.gridy=gy;
		gbc.gridwidth=gw;
		gbc.gridheight=gh;
		gbc.fill=GridBagConstraints.NONE;
		gbc.weightx=0;
		gbc.weighty=0;
		gbc.anchor=GridBagConstraints.CENTER;
		gbc.insets=new Insets(2,2,2,2);
		return gbc;
	}
	
	public static void main(String[] args) {
		try {
		    for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
		        if ("Nimbus".equals(laf.getName())) {
		            UIManager.setLookAndFeel(laf.getClassName());
		            break;
		        }
		    }
		} catch (Exception e) {
		    // If Nimbus is not available, you can set the GUI to another look and feel.
		}
		new init();
	}
}

Das ist mein Test-Programm zum rumspielen. (Benötigt Jericho HTMLParser

Jetzt hab ich zwei Probleme:

1. Encoding:
Ich hab von Zeile 105 - 112 verschiedene HTML Dateien mit unterschiedlichen Codierungen angelegt.
In den Dateien befinden sich auch Sonderzeichen / Umlaute.
Die Umlaute werden nur bei der ISO-8859-1 Datei angezeigt, wieso ist das so?
Ich dachte Java nutzt automatisch UTF-8?

2. In den Dateien habe ich zwischen den <body> Tag ein sich wiederholenden HTML-Block eingebaut, insgesamt 3 Blöcke und jeden möchte ich mit dem Jericho Parser einlesen.
Die Samples und Docs sind gut, aber ich komm nicht drauf wie ich das am geschicktesten machen könnte.

Ihr wisst bestimmt mehr?!
 

Marco13

Top Contributor
Zum Encoding: Das wird offenbar schon falsch gelesen. Es wird ja eine Folge von bytes gelesen, die "bedingungslos" als "chars" angesehen werden. Ein char besteht aber aus 2 bytes, die getrennt betrachtet keinen Sinn ergeben, und nur zusammengenommen das richtige Zeichen bilden.

Wenn man sich den "parsedContentFromUrl" mal ausgibt, sieht man, dass schon DER falsch ist. Mit
Java:
                BufferedInputStream in = new BufferedInputStream(uc.getInputStream());
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int ch;
                while ((ch = in.read()) != -1) {
                    baos.write((byte)ch);
                }
                baos.close();
                String st = new String(baos.toByteArray(), "UTF-8")
kommt schonmal (für UTF-8!) der richtige String raus. Zugegeben, ein bißchen beißt sich da die Katze in den Schwanz: Man muss sagen, wie man die bytes decodieren will, um rauszufinden, dass dort irgendwo zwischendrin dieses [c]...content="text/html; charset=utf-8"[/c] steht :autsch: Aber vielleicht hilft's als Ansatz....


Meinst du mit den drei Blöcken die drei
<li class="g w0" style="margin-bottom:16px;">
Blöcke? Sollten die nicht in einem <ul>-Tag stehen, oder macht das nichts?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Regex HTML Tag und Inhalt löschen Allgemeine Java-Themen 4
M id aus HTML (Regex) Allgemeine Java-Themen 7
faetzminator Regex zur Suche von "value-losen" Attributen in HTML Tags Allgemeine Java-Themen 7
Daniel_L RegEx: UBB in HTML konvertieren, Problem Verschachtelung Allgemeine Java-Themen 3
G HTML Code aus String mittels REGEX entfernen Allgemeine Java-Themen 2
A HTML String und regex Allgemeine Java-Themen 12
O Regex Texte zwischen html code Allgemeine Java-Themen 4
H Frage regex greater than less than Allgemeine Java-Themen 7
N Regex schlägt nicht an Allgemeine Java-Themen 10
W Variable Initialisierung mit dem Ergebnis einer Regex Allgemeine Java-Themen 1
T regex case insensitive trimmed Allgemeine Java-Themen 6
S Zeichen | in regex Allgemeine Java-Themen 8
X Regex mit mehreren Bedingungen machen Allgemeine Java-Themen 5
N Hilfe bei RegEx benötigt Allgemeine Java-Themen 3
C Java17 und Regex Allgemeine Java-Themen 13
OnDemand RegEx /compilebekomme nicht die erwarteten Werte Allgemeine Java-Themen 9
N Gierigen Regex in nicht-gierigen umwandeln Allgemeine Java-Themen 4
N E-Mail Validator (ohne Regex!) Allgemeine Java-Themen 7
OnDemand Regex von bis Allgemeine Java-Themen 6
W Versionsnummer auslesen - Regex ist zickig Allgemeine Java-Themen 2
L RegEx für Teile einer Berechnung Allgemeine Java-Themen 14
G Regex Allgemeine Java-Themen 2
L regex ganzer string? Allgemeine Java-Themen 2
MiMa Geldbetrag mit regex ermitteln. Allgemeine Java-Themen 14
W RegEx Stringliteral finden - Jflex Allgemeine Java-Themen 5
D Regex Probleme Allgemeine Java-Themen 2
Kirby.exe Regex charakter ignorieren Allgemeine Java-Themen 12
S Java SAT (Haltbarkeitsproblem) mit Regex Allgemeine Java-Themen 6
S [Regex] Nur diese Zeichen beachten Allgemeine Java-Themen 1
M Bitte Hilfe mit REGEX (Negieren) Allgemeine Java-Themen 4
J Compilerfehler bis in java.util.regex.Pattern... Allgemeine Java-Themen 2
C PDFBox: Nach RegEx ganze Zeile Allgemeine Java-Themen 4
S Regex mit UND-Verknüpfung Allgemeine Java-Themen 1
P RegEx für Zeiten Allgemeine Java-Themen 7
D Regex: Komplettes Wort bekommen Allgemeine Java-Themen 3
Neumi5694 Operatoren regEx für das Erstellen eines Strings verwenden Allgemeine Java-Themen 3
P RegEx Allgemeine Java-Themen 3
W String Parsen und auf eigenes Muster anwenden (kein Regex) Allgemeine Java-Themen 11
Y regex | n-faches Vorkommen oder gar keins Allgemeine Java-Themen 6
turmaline Regex gegen Regex prüfen Allgemeine Java-Themen 4
HarleyDavidson Regex - Optimierung Allgemeine Java-Themen 4
M Regex für Zahleneingabe in JavaFX Textfield Allgemeine Java-Themen 18
T Best Practice Wortregeln RegEx Allgemeine Java-Themen 11
A ALTER TABLE mit Hilfe von RegEx zerlegen, splitten Allgemeine Java-Themen 5
H Interpreter-Fehler Regex kompiliert nicht Allgemeine Java-Themen 5
M RegEx alle Matches ausgeben Allgemeine Java-Themen 5
Iron Monkey Mit Regex nach Beträge suchen Allgemeine Java-Themen 4
T REGEX Erklaerung Allgemeine Java-Themen 14
T Nur innerhalb des regex-Match ersetzen Allgemeine Java-Themen 9
H Pic Download / Regex Problem Allgemeine Java-Themen 7
F Frage zu Regex möglich Allgemeine Java-Themen 4
M Regex... mal wieder Allgemeine Java-Themen 3
H RegEx - Ersetze alles bis Leerzeichen Allgemeine Java-Themen 5
S regex verbrät CPU Allgemeine Java-Themen 6
V Regex Bereichs Filter Allgemeine Java-Themen 4
127.0.0.1 RegEx _ und 0-9 Allgemeine Java-Themen 45
S Entfernen von allen Nicht-Buchstaben chars aus einem String ohne Regex..? Allgemeine Java-Themen 10
P Java String Regex Allgemeine Java-Themen 2
AyKay Regex XPath Allgemeine Java-Themen 4
C Regex (Case insensitive und Umlaute) Allgemeine Java-Themen 4
D Regex Raute erkennen Allgemeine Java-Themen 2
nrg Zweistelligen Zahlenbereich mit RegEx Allgemeine Java-Themen 8
GilbertGrape Regex-Problem Allgemeine Java-Themen 2
W Denkblockade RegEx Allgemeine Java-Themen 2
S eigene regEx schreiben Allgemeine Java-Themen 4
C Regex expandieren Allgemeine Java-Themen 6
C Regex Überschniedung von Ausdrücken Allgemeine Java-Themen 16
reibi RegEX - Teilstring Allgemeine Java-Themen 6
R Java-RegEx terminiert nicht Allgemeine Java-Themen 3
M Regex: Ich stehe auf dem Schlauch Allgemeine Java-Themen 2
V Kleines Regex-Problem Allgemeine Java-Themen 3
B Regex "Problem" Allgemeine Java-Themen 4
B RegEx: (Um-)formulieren eines Pattern zur Identifizierung komplexer URLs Allgemeine Java-Themen 7
J Regex: Fertige URLS aus Javascript Allgemeine Java-Themen 3
N Java regex Allgemeine Java-Themen 5
K Regex JSON Allgemeine Java-Themen 3
J RegEx Ausdruck Allgemeine Java-Themen 2
J Regex: URLS aus CSS Allgemeine Java-Themen 2
G RegEx- Ausdruck Allgemeine Java-Themen 4
G RegEx kein Unterstrich Allgemeine Java-Themen 2
A Text via RegEx durchsuchen und teile ersetzten Allgemeine Java-Themen 5
C Regex: Zahl ohne führende Null Allgemeine Java-Themen 13
W RegEx Zeile parsen Medium Allgemeine Java-Themen 8
X Java String Regex - Sonderzeichen Filtern Allgemeine Java-Themen 5
S Dateiname mit Regex parsen Allgemeine Java-Themen 3
Loyd Noch ne Regex-Frage: Verschachtelte Ausdrücke Allgemeine Java-Themen 4
R Java Regex Frage Allgemeine Java-Themen 17
Daniel_L RegEx-Frage: Ersetzen in UBB ausschließen Allgemeine Java-Themen 2
M Große Datei mit Regex durchsuchen Allgemeine Java-Themen 4
S regex für einen Link Allgemeine Java-Themen 3
E Regex alles nach ? löschen Allgemeine Java-Themen 4
M RegEx-Frage Allgemeine Java-Themen 2
R Regex Tokenizer Allgemeine Java-Themen 11
H RegEX und eMail Allgemeine Java-Themen 4
L-ectron-X Regex zum Entfernen von mehrzeiligen Kommentaren Allgemeine Java-Themen 2
martin82 Regex - JTable - Filter Allgemeine Java-Themen 10
nrg Kleine Hilfe mit RegEx Allgemeine Java-Themen 2
B Regex-Fehler nach lib-Update Allgemeine Java-Themen 2
K Contrains oder Regex Allgemeine Java-Themen 3
J replaceAll , "[", "]" & regex Allgemeine Java-Themen 12

Ähnliche Java Themen

Neue Themen


Oben