Web Scraping

Diskutiere Web Scraping im Java Basics - Anfänger-Themen Bereich.
N

Nexuz89

Hallo zusammen

Ich bin ein blutiger Anfänger im Programmieren, und komme leicht an meine Grenzen : /.
Da ich eine coole App Idee habe, und sie umsetzen möchte.
Brauche ich Daten von einigen Shops (Name der Produkte, Preis usw.).
Ich habe mich im Internet erkundigt und habe das Web Scraping entdeckt.
Ich habe versucht eine Seite auszulesen, leider gibt es einige Probleme, die ich habe, dabei bräuchte ich Tipps und evtl. Lösung Vorschläge.
Im beigefügten Bild ist schon zuerkennen dass ich eine Seite ausgelesen habe, leider ist der Button weitere Artikel anzeigen vorhanden.
Mein Programm Stoppt an dieser stelle und liest die Seite nicht weiter aus.
Kann mir jemand bei diesem Problem behilflich sein?

Vielen Dank schon mal im Voraus.
 

Anhänge

N

Nexuz89

Der Code zum Programm :

public static void main (String [] args) throws Exception{

final String tab = "grill";




final HttpResponse<String> response = Unirest.get("https://www.coop.ch/de/search/?tab=product")
.queryString("text",tab)
.queryString("TAB",tab)
.asString();

final Document htmlSnippet = Jsoup.parseBodyFragment(response.getBody());

for (Element prduktesuche : htmlSnippet.select("div.productTile__wrapper"))


{
System.out.println(prduktesuche.child(0).text());

}


}
}
 
L

LimDul

Du dürftest da schnell an die Grenzen kommen. Ohne eine funktionierende Browser-Implementierung dürfte das Scraping sehr sehr schnell nicht mehr weiterführen. Du bekommst so nur den statischen Teil der Webseite. Da läuft aber noch viel Java-Script/AJAX Kommunikation. Und ohne die, fehlen dir die relevanten Informationen.

Das ist also eine Mammut-Aufgabe, da brauchst so was wie einen Webdriver: https://chromedriver.chromium.org/getting-started

Keine Ahnung ob das damit geht, hab ich mich selber damit nicht beschäftigt.
 
J

JustNobody

Webseiten nach so Daten auswerten halte ich für den falschen Weg, denn
a) ist es überkompliziert.
b) ist es sehr zerbrechlich - fast jede Änderung an der Seite führt zu einer nicht Funktionalität.

Den Shop den du ansprechen willst, kenne ich nicht, aber evtl. hat er ja auch eine api über z.B. WebServices? Dann würdest du eine dafür vorgesehene Schnittstelle nutzen.

Amazon, eBay und Co haben diese Schnittstellen z.B. und am Beispiel Amazon kann man gewisse Probleme aufzeigen:
So Bots, die Seiten abgreifen, sind unerwünscht, d.h. mit einfachen http Requests fliegst du oft direkt auf die Nase.
Selbst wenn da ein UserAgent simuliert wird, sind 503er regelmäßig vorhanden. Und je mehr Zugriffe von dir kommen, desto mehr 503er bekommst du....
Wenn du Pech hast bis hin zur Blacklist!

Also offizielle APIs verwenden und Dokumentation gut lesen. Gerade die Großen haben throttle Einstellungen, d.h. gewisse Aufrufe darf man nur eine bestimmte Anzahl mal in einer Zeiteinheit machen. Bei Amazon ist das oft 1x pro Sekunde ... aber Produktsuchen um ASINs zu kriegen z.B. nur alle 5 Sekunden (so ich mich richtig erinnere).
Und das sind dann Schnitttstellen, die für Kunden (Gruppen) sind .... bei Amazon z.B. die Gruppe, die ein Pro Verkäuferkonto haben ....

Danach würde ich etwas schauen. Denn das andere dürfte in eine Frikelei ausarten und coole App-Idee ist schnell etwas anderes, wenn dann 1* Beurteilungen hageln, weil etwas nicht mehr geht ....
 
MoxxiManagarm

MoxxiManagarm

Das ist also eine Mammut-Aufgabe, da brauchst so was wie einen Webdriver: https://chromedriver.chromium.org/getting-started
Absolut richtig. Der Chromedriver alleine reicht aber nicht, du brauchst einen Rahmen drumherum. Solche Rahmen sind z.B. Selenium (eigentlich ein Testtool, du könntest aber es missbrauchen, gibt es auch für Java) oder z.B. auch Electron (basiert auf NodeJs, hat mit Java nichts mehr zu tun). Mit diesen Tools kannst du einfach auf die Seite navigieren und dann JS-Code ausführen, u.a. JQuery um bestimmte Tags auszulesen
 
N

Nexuz89

Vielen dank für Ihre Antworten.
Ich benötige nur einmal die ganzen daten aus den Shops. Die ich dann abspeichere auf ein Datensever.
Meine potenzialen User Nutzer werden die Preise usw. aktualisieren.
Da ich die daten nur einmal benötige ist es nicht bisschen unkomplizierter ?
 
J

JustNobody

Wenn es einmalige Aktionen sind, dann ist das durchaus handhabbar. Viel Arbeit, aber da sind gewisse Risiken nicht gegeben, die ich erwähnt habe.
 
N

Nexuz89

haben sie evtl, ein tipp wie ich den Button (mehr anzeigen) in dem code (Programm) antippen kann ?
 
mihe7

mihe7

Wenn das einmalig ist, würde ich einen ganz anderen Ansatz wählen und unmittelbar über den Browser gehen. Dort mittels JavaScript das Zeug rausfiltern und einen Request gegen einen Server absetzen, der den Spaß aufzeichnet.
 
MoxxiManagarm

MoxxiManagarm

Beispiel:

HTML:
<a href="/mitglied/moxximanagarm.57275/" class="username " dir="auto" data-user-id="57275" data-xf-init="member-tooltip" itemprop="name" id="js-XFUniqueId53">MoxxiManagarm</a>
Das ist der HTML Code für mein Profil-Link unter meinem Avatar hier in diesem Beitrag (habe ich rauskopiert). Dieser lässt sich mittels JQuery selektieren, ich nehme dafür jetzt mal data-user-id für die Selektion.

Code:
$('a[data-user-id="57275"]:first')
Den Code kannst du auch in der Browser Console eingeben jetzt und hier, du bekommst meinen Profillink als Ergebnis. Nun kannst du darauf einfach click ausführen

Code:
$('a[data-user-id="57275"]:first').click()
Dann öffnet sich das kleine Popup als würdest du manuell darauf klicken




Das sieht dann etwa so aus zum Nachvollziehen
1593691393770.png

Und genau das geht auch mit der oben von mir beschriebenen Weise mit electron oder auch Selenium, bei JavaFX WebView vielleicht auch, bin mir nicht sicher.
 
mihe7

mihe7

Wenn man auf der Seite ein Kategorie auswählt und dann in die Konsole
Javascript:
function productObject(e) {
    const result = {};
    result.title = e.querySelector('h2').innerText.trim()
    result.price = e.querySelector('dd[data-product-price]').innerText
    return result
}
const products = Array.prototype.map.call(document.querySelectorAll("div.productTile-details"), e => e)
JSON.stringify(products.map(productObject))
schreibt, bekommt man z. B.

JSON:
"[{"title":"Aargauer Traum","price":"6.00"},{"title":"Bio Demeter Bûche","price":"4.70"},{"title":"Bio Demeter Ur-Buur","price":"7.35"},{"title":"Brebiou","price":"5.30"},{"title":"Brebiou Tradition","price":"5.15"},{"title":"Brie de Meaux","price":"4.50"},{"title":"Cambozola","price":"4.20"},{"title":"Cathedral City Cheddar","price":"6.25"},{"title":"Chaumes","price":"5.15"},{"title":"Crémoulin","price":"6.30"},{"title":"Der scharfe Maxx","price":"6.75"},{"title":"Der scharfe Maxx 365","price":"7.75"},{"title":"Emmi Luzerner Rahmkäse","price":"7.25"},{"title":"Emmi Luzerner Rahmkäse rustico","price":"7.50"},{"title":"Emmi Sennen Mutschli","price":"6.10"},{"title":"Fine Food Le Gruyère","price":"8.10"},{"title":"Fine Food Manchego Gran Riserva","price":"9.25"},{"title":"Fine Food Stilton DOP","price":"8.10"},{"title":"Fol Epi","price":"7.85"},{"title":"Fondue Hausmischung","price":"6.85"}]"
ausgegeben.
 
N

Nexuz89

Wenn man auf der Seite ein Kategorie auswählt und dann in die Konsole
Javascript:
function productObject(e) {
    const result = {};
    result.title = e.querySelector('h2').innerText.trim()
    result.price = e.querySelector('dd[data-product-price]').innerText
    return result
}
const products = Array.prototype.map.call(document.querySelectorAll("div.productTile-details"), e => e)
JSON.stringify(products.map(productObject))
schreibt, bekommt man z. B.

JSON:
"[{"title":"Aargauer Traum","price":"6.00"},{"title":"Bio Demeter Bûche","price":"4.70"},{"title":"Bio Demeter Ur-Buur","price":"7.35"},{"title":"Brebiou","price":"5.30"},{"title":"Brebiou Tradition","price":"5.15"},{"title":"Brie de Meaux","price":"4.50"},{"title":"Cambozola","price":"4.20"},{"title":"Cathedral City Cheddar","price":"6.25"},{"title":"Chaumes","price":"5.15"},{"title":"Crémoulin","price":"6.30"},{"title":"Der scharfe Maxx","price":"6.75"},{"title":"Der scharfe Maxx 365","price":"7.75"},{"title":"Emmi Luzerner Rahmkäse","price":"7.25"},{"title":"Emmi Luzerner Rahmkäse rustico","price":"7.50"},{"title":"Emmi Sennen Mutschli","price":"6.10"},{"title":"Fine Food Le Gruyère","price":"8.10"},{"title":"Fine Food Manchego Gran Riserva","price":"9.25"},{"title":"Fine Food Stilton DOP","price":"8.10"},{"title":"Fol Epi","price":"7.85"},{"title":"Fondue Hausmischung","price":"6.85"}]"
ausgegeben.
Kann ich mir auch die URL auspuckenlassen von den einzelnen Produkte ?
 
mihe7

mihe7

OK, da muss man ein klein wenig ändern:
Javascript:
function productObject(e) {
    const result = {};
    result.title = e.querySelector('h2').innerText.trim()
    result.price = e.querySelector('dd[data-product-price]').innerText
    result.url = e.querySelector('a').href
    return result
}
const products = Array.prototype.map.call(document.querySelectorAll("div[data-producttile-wrapper]"), e => e)
JSON.stringify(products.map(productObject))
 
N

Nexuz89

OK, da muss man ein klein wenig ändern:
Javascript:
function productObject(e) {
    const result = {};
    result.title = e.querySelector('h2').innerText.trim()
    result.price = e.querySelector('dd[data-product-price]').innerText
    result.url = e.querySelector('a').href
    return result
}
const products = Array.prototype.map.call(document.querySelectorAll("div[data-producttile-wrapper]"), e => e)
JSON.stringify(products.map(productObject))
Vielen vielen dank , eine frage noch wie kann ich jeden link getrennt anzeigen z.b so

{"title":"Emmi Couronne",
"price":"4.35",
"url":"https://www.coop.ch/de/kaese-laender/schweiz/emmi-couronne/p/3080407?context=category"},

{"title":"Emmi Winzerkäse",
"price":"7.35",
"url":"https://www.coop.ch/de/kaese-laender/schweiz/emmi-winzerkaese/p/3080207?context=category"}]"
 
mihe7

mihe7

Die letzte Zeile stellt den Spaß einfach als JSON-String dar. Du kannst es darstellen, wie Du möchtest. Zum Beispiel kannst Du products.map(productObject).map(p => '"' + p.title + '",' + p.price + ',"' + p.url + '"').join('\n') schreiben, dann bekommst Du eine CSV-like-Ausgabe.
 
Thema: 

Web Scraping

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben