2017-08-16 1 views
1

Ich versuche, einen Preis von Amazon mit JSoup zu extrahieren, aber es gibt zwei verschiedene Elemente, wo ich es extrahieren kann. Ich kann es aus dem Aria-Label-Attribut im Element entfernen, oder ich kann es aus dem Text innerhalb des Elements abrufen. Am liebsten würde ich es immer vom aria-label-Attribut erhalten, aber manchmal existiert es nicht, also muss ich es aus der zweiten Span-Klasse extrahieren. Meine Frage ist, wie kann ich eine if-Anweisung erstellen, die das Attribut überprüft, um zu sehen, ob es irgendeinen Text hat, und wenn es das nicht tut, den Text aus der zweiten Span-Klasse zu extrahieren?JSoup - Überprüfung bestimmter Elemente, um zu sehen, ob sie Text haben und dann nur eine auswählen

Ich versuche auch, mehrere Preise von Klassen zu bekommen, die identisch benannt sind, aber wenn ich zum Beispiel doc.select("span.sx-price.sx-price-large").get(0).text() schreibe, erscheint nichts. wäre sehr dankbar, vielen Dank für Ihre Zeit

Hier ist der HTML-Code für eines der Elemente, die ich einen Artikel von

<a class="a-size-small a-link-normal a-text-normal" href="http://rads.stackoverflow.com/amzn/click/B01MZYYWUH">1</a></div> 
 
<div class="a-row a-spacing-mini"><span class="a-size-small a-color-secondary a-text-bold">Product Description</span><br><span class="a-size-small a-color-secondary">... Cards Radeon&trade; <em>RX</em> 460 Graphics Cards Radeon&trade; R9 <em>390</em> Graphics Cards ...</span></div> 
 
</div></div></div></div></div></div></li> 
 
<li id="result_2" data-asin="B00IAAU6SS" class="s-result-item celwidget "> 
 
    <div class="s-item-container"> 
 
    <div class="a-fixed-left-grid"> 
 
    <div class="a-fixed-left-grid-inner" style="padding-left:218px"> 
 
    <div class="a-fixed-left-grid-col a-col-left" style="width:218px;margin-left:-218px;_margin-left:-109px;float:left;"> 
 
     <div class="a-row"> 
 
     <div aria-hidden="true" class="a-column a-span12 a-text-center"> 
 
      <a class="a-link-normal a-text-normal" href="http://rads.stackoverflow.com/amzn/click/B00IAAU6SS"><img src="https://images-na.ssl-images-amazon.com/images/I/419c5Ci-UqL._AC_US218_.jpg" srcset="https://images-na.ssl-images-amazon.com/images/I/419c5Ci-UqL._AC_US218_.jpg 1x, https://images-na.ssl-images-amazon.com/images/I/419c5Ci-UqL._AC_US327_FMwebp_QL65_.jpg 1.5x, https://images-na.ssl-images-amazon.com/images/I/419c5Ci-UqL._AC_US436_FMwebp_QL65_.jpg 2x, https://images-na.ssl-images-amazon.com/images/I/419c5Ci-UqL._AC_US500_FMwebp_QL65_.jpg 2.2935x" width="218" height="218" alt="Product Details" class="s-access-image cfMarker" data-search-image-load></a> 
 
      <div class="a-section a-spacing-none a-text-center"></div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    <div class="a-fixed-left-grid-col a-col-right" style="padding-left:2%;*width:97.6%;float:left;"> 
 
    <div class="a-row a-spacing-small"> 
 
     <div class="a-row a-spacing-none scx-truncate-medium sx-line-clamp-3 s-list-title-long"> 
 
     <a class="a-link-normal s-access-detail-page s-color-twister-title-link a-text-normal" title="Arctic Accelero Xtreme IV 280(X) - High-End Graphics Card Cooler with Backside Cooler for Efficient RAM and VR-Cooling - DCACO-V930001-GBA01" href="http://rads.stackoverflow.com/amzn/click/B00IAAU6SS"> 
 
      <h2 data-attribute="Arctic Accelero Xtreme IV 280(X) - High-End Graphics Card Cooler with Backside Cooler for Efficient RAM and VR-Cooling - DCACO-V930001-GBA01" data-max-rows="3" class="a-size-medium s-inline s-access-title a-text-normal">Arctic Accelero Xtreme IV 280(X) - High-End Graphics Card Cooler with Backside Cooler for Efficient RAM and VR-Cooling - DCACO-V930001-GBA01</h2> 
 
     </a> 
 
     </div> 
 
     <div class="a-row a-spacing-none"><span class="a-size-small a-color-secondary">by </span><span class="a-size-small a-color-secondary">ARCTIC</span></div> 
 
    </div> 
 
    <div class="a-row"> 
 
    <div class="a-column a-span7"> 
 
    <div class="a-row a-spacing-none"><a class="a-link-normal a-text-normal" href="http://rads.stackoverflow.com/amzn/click/B00IAAU6SS"><span aria-label="$85.99" class="a-color-base sx-zero-spacing"><span class="sx-price sx-price-large"> 
 
     <sup class="sx-price-currency">$</sup> 
 
     <span class="sx-price-whole">85</span> 
 
     <sup class="sx-price-fractional">99</sup> 
 
     </span> 
 
     </span></a><span class="a-letter-space"></span><i class="a-icon a-icon-prime a-icon-small s-align-text-bottom" aria-label="Prime"><span class="a-icon-alt">Prime</span></i> 
 
    </div> 
 
    <div class="a-row a-spacing-mini"> 
 
     <div class="a-row a-spacing-none"><span class="a-size-small a-color-secondary">FREE Shipping on eligible orders</span></div> 
 
     <div class="a-row a-spacing-none"><span class="a-size-small a-color-price">Only 8 left in stock - order soon.</span></div> 
 
    </div> 
 
    <div class="a-row a-spacing-mini"> 
 
    <div class="a-row a-spacing-none"> 
 
     <div class="a-row a-spacing-mini"></div> 
 
     <span class="a-size-small a-color-secondary">More Buying Choices</span> 
 
    </div> 
 
    <div class="a-row a-spacing-none"> 
 
    <a class="a-size-small a-link-normal a-text-normal" href="http://rads.stackoverflow.com/amzn/click/B00IAAU6SS"><span class="a-color-secondary a-text-strike"></span><span class="a-size-base a-color-base">$85.99</span>

Hilfe extrahieren möchten!

Antwort

0

Gegeben durch Ihr Beispiel - wählen wir span. Überprüfen Sie danach, ob Ihr "ausgewähltes" Element NULL ist, wenn es NICHTNULL ist, dann wählen Sie den Text aus den Unterbereichen aus.

Versuchen Sie dies (es wurde von mir nicht getestet - nur durch den Speicher geschrieben (natürlich müssen Sie zunächst ein Dokument holen, die ich nehme an, Sie haben bereits)):

try{ 
Element span = doc.select("span.a-color-base.sx-zero-spacing").first(); 

if(span != null) { 
    System.out.println(span.attr("aria-label")); 
} else { 
    Element beforeSep = doc.select("span.sx-price-whole").first(); 
    Element afterSep = doc.select("sup.sx-price-fractional").first(); 

    System.out.println(beforeSep.text() + "." + afterSep.text()); 
} 
} catch (Exception ex){ 
    // exception handler 
} 
+0

Das funktioniert nicht, denn selbst wenn der obige HTML-Code kein Aria-Label enthält, wird sicherlich ein anderes Element einen haben, so dass Aria-Label nie Null sein wird – coolyfrost

0

Ich würde vorschlagen Element Auswahl mit Klasse .sx-price, da sein Name es enthält einen Preis enthält. Dann können Sie das übergeordnete Element auswählen, wobei aria-label Attribut erwartet wird, überprüfen Sie, ob es Preis enthält, mit einfachen regulären Ausdruck - wenn wahr, nehmen Preis direkt von diesem Attribut, andernfalls sammeln Daten aus verschachtelten untergeordneten Bereichen.

Unten finden Sie einen Code, mit dem ich herumspielen, funktioniert ziemlich gut.

final Document doc = Jsoup.parse(html); 

final Elements prices = doc.select(".sx-price"); 

final Pattern pattern = Pattern.compile("^\\$?([0-9]+)\\.([0-9]{2})$"); 

for (Element el : prices) { 
    String price = ""; 
    if (el.parent().hasAttr("aria-label") && pattern.matcher(el.parent().attr("aria-label")).find()) { 
     System.out.println("Extracting price from aria-label..."); 
     price = el.parent().attr("aria-label"); 

    } else { 
     System.out.println("Extracting price from span body..."); 
     String currency = el.select(".sx-price-currency").text(); 
     String whole = el.select(".sx-price-whole").text(); 
     String fractional = el.select(".sx-price-fractional").text(); 

     price = String.format("%s%s.%s", currency, !whole.isEmpty() ? whole : "00", !fractional.isEmpty() ? fractional : "00"); 
    } 

    System.out.println(price); 
} 

Ich hoffe, es hilft.

Verwandte Themen