Forgive me for the beginner question. I'm trying to build a web scraper . I made a helper class Selectors
to store CSS selectors of different type and the class has a getter method that returns a optional field value:
public Optional<String> getName() {
return Optional.ofNullable(this.name);
}
In my main Scraper
class I have a method to extract the name from the HTML using the Selectors
object like this:
public String extractName(Element building) {
if (this.selectors.getName().isPresent()) {
String cssSelector = this.selectors.getName().get();
Elements buildingNameElement = building.select(cssSelector);
return buildingNameElement.text();
}
return "N/A";
}
As much as I've read this isn't a very nice way to use the Optional
class. But I'm struggling to come up with a better solution. My first thought was to use the ifPresent
method but it does not work in this manner:
public String extractName(Element building) {
this.selectors.getName().ifPresent(() -> {
String cssSelector = this.selectors.getName().get();
Elements buildingNameElement = building.select(cssSelector);
return buildingNameElement.text();
});
return "N/A";
}
I'd like that the Elements.select()
would execute only if there's a name field present in the Selectors
object. Could anyone help me make the code a bit more functional?
Thanks!
public String extractName(Element building) {
return this.selectors
.getName()
.map(cssSelector -> {
Elements buildingNameElement = building.select(cssSelector);
return buildingNameElement.text();
})
.orElse("N/A");
}
This is what Optional.map
is for. When you do return
inside a lambda, you are only returning from the lambda, not from the outer method. So the above uses the text of the building name element if getName
returned a name/selector. And returns N/A
if not.
If you’re fine with a more condensed syntax and fewer named variables, you may go with the following:
return this.selectors
.getName()
.map(cssSelector -> building.select(cssSelector).text())
.orElse("N/A");
Disclaimer: I haven’t got JSoup on my computer, so I haven’t tested. Please forgive if there’s a typo, and report back.