How to get Dynamic Xpath of a webtable? - java

List<WebElement>table=driver.findElements(By.xpath("//*[#id=\"prodDetails\"]/div[2]/div[1]/div/div[2]/div/div/table/tbody/tr"));
JavascriptExecutor jse = (JavascriptExecutor) driver;
// jse.executeScript("arguments[0].scrollIntoView();",table);
jse.executeScript("arguments[0].style.border='3px solid red'",table);
int row= table.size();
I am unable to get the required no of row and column.The xpath i provided does not find the table on site
Link : Click here
I have to fetch the specification of the mobile.

Instead of this xpath :
//*[#id=\"prodDetails\"]/div[2]/div[1]/div/div[2]/div/div/table/tbody/tr
Use this :
//*[#id="prodDetails"]/div[2]/div[1]/div/div[2]/div/div/table/tbody/tr
Though I would not suggest you to use absolute xpath. You can go for relative xpath which is more readable and easy.
Relative Xpath :
//div[#id='prodDetails']/descendant::div[#class='pdTab'][1]/descendant::tbody/tr
In code something like :
List<WebElement>table=driver.findElements(By.xpath("//div[#id='prodDetails']/descendant::div[#class='pdTab'][1]/descendant::tbody/tr"));

Instead of absolute xpath:
//*[#id=\"prodDetails\"]/div[2]/div[1]/div/div[2]/div/div/table/tbody/tr
I would suggest to use simple relative xpath:
//*[#id='prodDetails']//table/tbody/tr
This xpath will work if there are no other tables in the page. Otherwise, make sure both the tables can be differentiated with some attribute

You can get the total no of rows using the below Xpath.
In the above link, we are having multiple section which has same class and two table also has similar locator. So, You need to get the element based on the table name as below
Note: you can achieve this without using JavascriptExecutor
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#class='section techD']//span[text()='Technical Details']/ancestor::div[#class='section techD']//table//tr")));
List<WebElement> rowElementList=driver.findElements(By.xpath("//div[#class='section techD']//span[text()='Technical Details']/ancestor::div[#class='section techD']//table//tr"));
int row= rowElementList.size();
System.out.println(row);//16
output:
16
Suppose , If you want to get an additional information table row details, you can use the above Xpath by replace the section as Additional Information
List<WebElement> additionInfoList=driver.findElements(By.xpath("//div[#class='section techD']//span[text()='Additional Information']/ancestor::div[#class='section techD']//table//tr"));
System.out.println(additionInfoList.size());//Output: 5
Output: 5
Finally, you can iterate above list and extract table content details

XPATH can be pretty hard to read, especially when you need to use it a lot.
You could try the univocity-html-parser
HtmlElement e = HtmlParser.parseTree(new UrlReaderProvider("your_url"));
List<HtmlElement> rows = e.query()
.match("div").precededBy("div").withExactText("Technical Details")
.match("tr").getElements();
for(HtmlElement row : rows){
System.out.println(row.text());
}
The above code will print out:
OS Android
RAM 2 GB
Item Weight 150 g
Product Dimensions 7.2 x 14.2 x 0.9 cm
Batteries: 1 AA batteries required. (included)
Item model number G-550FY
Wireless communication technologies Bluetooth, WiFi Hotspot
Connectivity technologies GSM, (850/900/1800/1900 MHz), 4G LTE, (2300/2100/1900/1800/850/900 MHz)
Special features Dual SIM, GPS, Music Player, Video Player, FM Radio, Accelerometer, Proximity sensor, E-mail
Other camera features 8MP primary & 5MP front
Form factor Touchscreen Phone
Weight 150 Grams
Colour Gold
Battery Power Rating 2600
Whats in the box Handset, Travel Adaptor, USB Cable and User Guide
Alternatively the following code is a bit more usable, as I believe you probably want more stuff from that page too, and getting rows with data is usually what you want to end up with:
HtmlEntityList entityList = new HtmlEntityList();
HtmlEntitySettings product = entityList.configureEntity("product");
PartialPath technicalDetailRows = product.newPath()
.match("div").precededBy("div").withExactText("Technical Details")
.match("tr");
technicalDetailRows.addField("technical_detail_field").matchFirst("td").classes("label").getText();
technicalDetailRows.addField("technical_detail_value").matchLast("td").classes("value").getText();
HtmlParserResult results = new HtmlParser(entityList).parse(new UrlReaderProvider("your_url")).get("product");
System.out.println("-- " + Arrays.toString(results.getHeaders()) + " --");
for(String[] row : results.getRows()){
System.out.println(Arrays.toString(row));
}
Now this produces:
OS = Android
RAM = 2 GB
Item Weight = 150 g
Product Dimensions = 7.2 x 14.2 x 0.9 cm
Batteries: = 1 AA batteries required. (included)
Item model number = G-550FY
Wireless communication technologies = Bluetooth, WiFi Hotspot
Connectivity technologies = GSM, (850/900/1800/1900 MHz), 4G LTE, (2300/2100/1900/1800/850/900 MHz)
Special features = Dual SIM, GPS, Music Player, Video Player, FM Radio, Accelerometer, Proximity sensor, E-mail
Other camera features = 8MP primary & 5MP front
Form factor = Touchscreen Phone
Weight = 150 Grams
Colour = Gold
Battery Power Rating = 2600
Whats in the box = Handset, Travel Adaptor, USB Cable and User Guide
Disclosure: I'm the author of this library. It's commercial closed source but it can save you a lot of development time.

Related

How to fetch all the details of the object using Jsoup library and save it to the bean?

Here I'm Scraping the site https://hamrobazaar.com/c6-apparels-and-accessories and i want to store all the sub-categories details in a bean and print them. If i got the details of object accordingly than this also would be much help.
Example:
I want to Scrape Name of the Mask as Kn95 Mask (fda Certified), description as We are Seller..., seller name as Birodh Pokhrel, Address as Damak-5,Damak, price as 210, date, and type as Brand New
If you are good at Jsoup, and Xpath. Please help me to obtain this. Thank You
For the XPath part (jsoup doesn't support it, so maybe you can try with xsoup) :
Some selectors to grab the details from the ads, including the one with yellow background which stays the same for each page. (article title, description, seller, address, price, item condition) :
//font[#style]/b
//b[.="Seller:"]/preceding-sibling::text()[normalize-space()]
//b[.="Seller:"]/following-sibling::a
//b[.="Seller:"]/following-sibling::font
//b[starts-with(.,"Rs.")]
//b[starts-with(.,"Rs.")]/following-sibling::font
Number of elements for each detail : 21
Some selectors to grab the details from the ads, excluding the one with yellow background which stays the same for each page. (article title, description, seller, address, price, item condition) :
//font[#style][not(ancestor::table[#id])]/b
//b[.="Seller:"][not(ancestor::table[#id])]/preceding-sibling::text()[normalize-space()]
//b[.="Seller:"][not(ancestor::table[#id])]/following-sibling::a
//b[.="Seller:"][not(ancestor::table[#id])]/following-sibling::font
//b[not(ancestor::table[#id])][starts-with(.,"Rs.")]
//b[not(ancestor::table[#id])][starts-with(.,"Rs.")]/following-sibling::font
Number of elements for each detail : 20
Side note : be careful with item condition. Some ads are missing this field. So, the number of elements could be lower than 20 or 21.

JSoup selecting radiobuttons

Good time of day ,
I have a question about using jsoup.
Working with one web site I met problem that before gathering information from list of products at first I need to select radio buttons and send required data about two parameters of products : "type" and "categories".
This web site if so:
http://h17007.www1.hpe.com/us/en/networking/products/eos/index.aspx#.WzYf4NIzY2z
Because if not to do it search will give list which have only one product from unknown category .
This:
HP VCX V7205 Platform with DL 360 G6
I'm using such method at the begining.
Response response = Jsoup.connect("http://h17007.www1.hpe.com/us/en/networking/products/eos/index.aspx#.WzSdxdIzY2z")
.userAgent("Mozilla/5.0")
.timeout(10 * 1000)
.method(Method.POST)
.data("type","2")
.data("category","4")
.followRedirects(true)
.execute();
And then parse it.
Document document = response.parse();
But unfortunatly either I didn't understand how to send it correctly or I should choose another way of ,maybe , selecting correct list of products .As you may understand I try to choose second type and fouth category.
Could somebody advise how to do it ? Or advise example which could be useful for may case ?
Thank you for your attention

Computing preference values in Apache Mahout

I am trying to learn Apache mahout, very new to this topic. I want to implement user-based recommender. For this, after exploring on the internet I have found some samples like below,
public static void main(String[] args) {
try {
int userId = 2;
DataModel model = new FileDataModel(new File("data/mydataset.csv"), ";");
UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, model);
UserBasedRecommender recommender = new GenericUserBasedRecommender(model, neighborhood, similarity);
List<RecommendedItem> recommendations = recommender.recommend(userId, 3);
for (RecommendedItem recommendation : recommendations) {
logger.log(Level.INFO, "Item Id recommended : " + recommendation.getItemID() + " Ratings : "
+ recommendation.getValue() + " For UserId : " + userId);
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception in main() ::", e);
}
I am using following dataset which contains userid, itemid, preference value respectively,
1,10,1.0
1,11,2.0
1,12,5.0
1,13,5.0
1,14,5.0
1,15,4.0
1,16,5.0
1,17,1.0
1,18,5.0
2,10,1.0
2,11,2.0
2,15,5.0
2,16,4.5
2,17,1.0
2,18,5.0
3,11,2.5
3,12,4.5
3,13,4.0
3,14,3.0
3,15,3.5
3,16,4.5
3,17,4.0
3,18,5.0
4,10,5.0
4,11,5.0
4,12,5.0
4,13,0.0
4,14,2.0
4,15,3.0
4,16,1.0
4,17,4.0
4,18,1.0
In this case, it works fine, but my main question is I have the different set of data which don't have preference values, which contains some data based on that I am thinking to compute preference values. Following is my new dataset,
userid itemid likes shares comments
1 4 1 20 3
2 6 18 20 12
3 12 10 2 20
4 7 0 20 13
5 9 0 2 1
6 5 5 3 2
7 3 9 7 0
8 1 15 0 0
My question is how can I compute preference value for a particular record based on some other columns such as likes, shares, comments etc. Is there anyway to compute this in mahout?
Yes- I think your snippet is from an older version of Mahout, but what you want to use is the Correlated Co Occurrence recommender. The CCO Recommender is multi-modal (allows user to have various inputs).
There are CLI Drivers, but I'm guessing you want to code, there is a Scala tutorial here
In the tutorial I think it recommends 'friends' based on genres tagged and artists 'liked', as well as your current friends.
As #rawkintrevo says, Mahout has moved on from the older "taste" recommenders and they will be deprecated from Mahout soon.
You can build you own system from the CCO algorithm in Mahout here. It allows you to use data from different user behavior like "likes, shares, comments". So we call it multi-modal.
Or in another project we have created a full featured recommendation server based on Mahout, called the Universal Recommender. It is build on Apache PredicitonIO where the UR is a plugin called a Template. Together they deliver a nearly turnkey server that takes input and responds to queries. To get started easily try the AWS AMI that has the whole system working. Some other methods to install are shown here.
This is all Apache licensed OSS, but Mahout no longer can really provide a production ready environment, Mahout does algorithms but you need a system around it. Build your own or try the PredictionIO based one. Since everything is OSS you can tweak things if needed.

JavaPlot timestamps not working

I have a file like
1429520881 15.0
1429520882 3.0
1429520883 340.0
and I try to use it in JavaPlot
JavaPlot plot=new JavaPlot();
GenericDataSet dataset=new GenericDataSet();
filling dataset with data
...
plot.set("xdata","time");
plot.set("timefmt","'%s'");
plot.set("format x","'%H:%M:%S'");
plot.plot();
in result gnuplot's window don't appear but If I try this file directly in gnuplot with the same data and options it shows me a time on xAxis; If in JavaPlot I delete last settings(xdata, timefmt,format) it works but it shows me only numbers
I also tried to create manualy dataset with data in program but the same result.
I also implement new DataSet with date as String but it seems that xdata,time option doesn't work
It took forever to figure this one out. I found that if you have a DataSetPlot object you can set the 'using' option:
DataSetPlot dataSet = new DataSetPlot( values );
dataSet.set( "using", "1:2" );
This will then make use of the 'using' option for the plot command, eg:
plot '-' using 1:2 title 'Success' with lines linetype rgb 'green'
You have to have the 'using' option when making use of time for the x axis, otherwise you will see this error:
Need full using spec for x time data
It generates temp script file with data inside in weird order because of ParametersHolder inherits HashMap and there should be "using" keyword after '-'
for example:
I wrote LinkedParams extends GNUPlotParameters class with inner LinkedMap and overrided methods to use inner structure;
set ... ...(xrange,yrange etc)
set xdata time
set timefmt '%s'
set format x '%H:%M:%S'
plot '-' using 1:2 title 'ololo' with linesploints lineType 2 lineWidth 3
1429520881 15.0
1429520882 3.0
1429520883 340.0
e
quit
but it was
set xdata time
set ... ...(xrange,yrange etc)
set format x '%H:%M:%S'
set timefmt '%s'
plot '-' title 'ololo' with linesploints lineType 2 lineWidth 3
1429520881 15.0
1429520882 3.0
1429520883 340.0
e
quit

Create real-time report using ZoomData (visualization problems)

I'm trying to create simple real-time report using ZoomData.
I create DataSource (Upload API) in ZoomData admin interface & add visualization to it (vertical bars).
Also I disable else visualizations for this DS.
My DS has 2 fields:
timestamp - ATTRIBUTE
count - INTEGER AVG
In visualization
group by: timestamp
group by sort: count
y axis: count avg
colors: count avg
Every second i send post request to zoomdata server to add info in DS.
I do it from java (also trying to send from postman).
My problem is: data came from post and added to DS but visualization properties become to default
group by sort: volume
y axis: volume
colors: volume
but group by stay timestamp
I can't understand why visualization properties always change after data came in POST request.

Categories