I'm trying to play around with automating an online game and I'm stuck.
What I'm trying to do: I'm trying to analyse my reports. The first step involves fetching the parent row. The second step is filtering the parent row based on whether the report is read or not, and whether the report is of today's date.
this.driver.findElements(this.reportRow).stream()
.filter(reportElement -> reportElement.findElement(this.unreadReports).isDisplayed()
&& reportElement.findElement(this.todaysReport).getText().contains(this.bountyDate))
.map(reportRow -> {
String villageName = reportRow.findElement(this.unreadReports).getText().replace("mwldjt raids ", "");
String bounty = reportRow.findElement(this.bountyElement).getText();
System.out.println("Village: " + villageName + " Bounty: " + bounty);
return new String[]{bounty, villageName};
})
.forEach(entry -> System.out.println("Entry:" + entry[0] + ", " + entry[1])
Here is the HTML that I'm trying to parse through.
<tr>
<td class="sel">
<input class="check" name="n1" type="checkbox" value="14180678">
</td>
<td class="sub newMessage">
<a href="berichte.php?id=14180678&t=1&s=0&page=1&toggleState=0">
<img alt="unread" class="messageStatus messageStatusUnread" src="img/x.gif">
</a>
<img alt="Won as attacker with losses." class="iReport iReport2 " src="img/x.gif">
<a class="reportInfoIcon" href="build.php?id=39&tt=2&bid=14180678"><img alt="16/100" class="reportInfo carry half"
src="img/x.gif"></a>
<div class="">
<a href="berichte.php?id=14180678%7C5fa6b3d7&t=1&s=1">mwldjt raids Natars 36|64</a>
</div>
<div class="clear"></div>
</td>
<td class="dat">
24/04/20, 04:08 am
</td>
</tr>
I'm trying to catch the bounty and the village name in a LinkedHashmap. I have replaced the 'put' in the foreach block with a print method for now.
The problem:
I need to perform two operations - getting data from two elements that lie within the parent row. I have been trying to understand how to do this, but now I think I need help. Thank you for taking the time.
A forEach
with a put
operation over a LinkedHashMap
can be converted to using
.collect(Collectors.toMap(<key-fn>, <value-fn>, <merge-fn>, LinkedHashMap::new)
so the code you've shard can be refactored into
LinkedHashMap<String, String> output = this.driver.findElements(this.reportRow).stream()
.filter(reportElement -> reportElement.findElement(this.unreadReports).isDisplayed()
&& reportElement.findElement(this.todaysReport).getText().contains(this.bountyDate))
.map(reportRow -> {
String villageName = reportRow.findElement(this.unreadReports).getText().replace("mwldjt raids ", "");
String bounty = reportRow.findElement(this.bountyElement).getText();
System.out.println("Village: " + villageName + " Bounty: " + bounty);
return new String[]{bounty, villageName};
})
.collect(Collectors.toMap(e -> e[0], e -> e[1], (a,b) -> b, LinkedHashMap::new);
Of course, the operations of getting a village name and bounty could have been extracted and placed directly within the toMap
Collector in a form such as:
LinkedHashMap<String, String> output = this.driver.findElements(this.reportRow).stream()
.filter(reportElement -> isValidReportElement(reportElement))
.collect(Collectors.toMap(reportElement -> getVillageName(reportElement),
reportElement -> getBounty(reportElement), (a,b) -> b, LinkedHashMap::new);