0

I try to set up a handler to manage a price slider bar for scraping. However it isn't so easy if you have 2 bars on the same line, cause in my case, when I move one of them a second bar runs too.

So there are 2 main questions:

  1. How to code it? Extremely important is fixed one bar when you moving other. There is the major aim is defining different price ranges.

  2. Actually, it isn't handy to use pixels to moving bars. Anyone know how to translate pixel from the slider to simply prices. In order to define a price range in money (not in pixels).

Here's a url to the site that I try to crack (look at the left side "Price Range").

Furthermore, fragment of html script in part of the slider bar is bellow:

<div class="rangeSlider__slider--DaZc5">
 <div class="rc-slider">
 <div class="rc-slider-rail"></div>
 <div class="rc-slider-track rc-slider-track-1" style="background-color: rgb(137, 24, 38); left: 23.088%; width: 26.912%;"></div>
 <div class="rc-slider-step"></div>
 <div tabindex="0" class="rc-slider-handle rc-slider-handle-1" role="slider" aria-valuemin="0" aria-valuemax="12500" aria-valuenow="2886" aria-disabled="false" style="background-color: rgb(137, 24, 38); border: 16px solid rgb(137, 24, 38); top: -4px; transform: translate(-8px, 0px); left: 23.088%;"></div>
 <div tabindex="0" class="rc-slider-handle rc-slider-handle-2" role="slider" aria-valuemin="0" aria-valuemax="12500" aria-valuenow="6250" aria-disabled="false" style="background-color: rgb(137, 24, 38); border: 16px solid rgb(137, 24, 38); top: -4px; transform: translate(-8px, 0px); left: 50%;"></div>
 <div class="rc-slider-mark"></div>
 </div>
</div>

I already tried to use selenium find all by Xpath to find the bars and than executed selenium dragAndDropBy, but is was suitable in cases with one bar and definitely isn't tailored for the 2 bars slider.

asked Sep 8, 2019 at 12:19
1
  • 1
    show your code trials and errors Commented Sep 8, 2019 at 12:56

2 Answers 2

1

Here is another solution (faster and better in my opinion) that uses their private api. Api's are more reliable and faster. All you need to do is make a get request to their api with the appropriate parameters and the website gives you a json response. You can change the price max and min in the parameters. Luckily for you, their api is loaded with information about the wines, their origen, and reviews. Here is the code to read from one page (you can loop through and change the page parameter each time) Also, The requests module is needed for this solution: pip install requests

Code

import requests
params = {
 'country_code': 'US',
 'currency_code': 'USD',
 'grape_filter': 'varietal',
 'merchant_id': '',
 'min_rating': '3.5',
 'order_by': '',
 'order': 'desc',
 'page': '1',
 'price_range_max': '40',
 'price_range_min': '10',
 'wine_type_ids[]': '1',
 'wine_type_ids[]': '2',
}
url = 'https://www.vivino.com/api/explore/explore'
r = requests.get(url, params=params, headers={
 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'})
json_data = r.json()
print(r.url)
print(r.text)
for wine in json_data['explore_vintage']['matches']:
 print('\n' + wine['vintage']['name'])
 try:
 print(wine['price']['amount'])
 except TypeError:
 print('None')

Ok I'll try to help with the search parameters. You won't have to change the country_code, currency_code, grape_filter, order, and merchant_id parameters (from what I can tell). Changing the min_rating parameter will set the Vivino user rating value. Changing the order_by will set the sort. Changing the page will display more results (the json data only loads a certain amount of results at a time). Changing the price_range_max and price_range_min set the price range (this is the question you had in the beginning).

There are certain parameters you can add. For example, if you add more wine_type_ids[], this will select multiple wine types. You can find the value of certain wine types by actually clicking the wine type on the website and see the id in the request in the network tab. You can add a parameter called grape_ids[] which allow you to select different grapes (find the grape ids the same way as before). region_ids[] and country_codes[] can be used to select countries and regions for the search. wine_style_ids[] and food_ids[] for wine styles and food pairings. For each parameter that ends in [], you need to add a different one for each id. I know it's complicated, but I got all of this information from selecting specific stuff for a search and then looking at the network tab (and scroll down to the Query String Parameters section.

answered Sep 9, 2019 at 0:02

6 Comments

It's awesome! I never knew that they have API and their website hasn't any information about that. How did you find that and do is it has any documentation?
Through the developer tools in the Network tab, you can see requests made from your client to the server api (XHR filter I believe). This is an undocumented (private) api, the browser makes requests to it to retrieve information (search results). You can experiment with different searches and see what changes in the parameters. Then, you can make these custom get requests through python.
I definitely like your approach, but not clearly understand how you defined params for your query in the script above. I tried to find something similar attributes through the Chrome Network tab, but received only list of bottles that were uploaded
I edited my post to include more information about the api. Whenever you change something about the search, look in the network tab and filter this by XHR. Look for a request called "explore?...." Click on this and scroll down to the bottom, all of the parameters are here.
Oh, I cracked it :) Thanks so much for the explanation is so helpful and I have to mention that your approach is easier
|
0

This works:

driver.execute_script("document.querySelector('.rc-slider-handle-1').style.left = '0%'")
driver.execute_script("document.querySelector('.rc-slider-handle-2').style.left = '100%'")
driver.find_element_by_css_selector('.rc-slider-handle-1').click()
driver.find_element_by_css_selector('.rc-slider-handle-2').click()

To convert prices to percentages you just have to make that conversion yourself.

answered Sep 9, 2019 at 1:57

4 Comments

thank you, but actually, I tried this way and met another issue: this perfect works when you move the slider-1 to 0% and the slider-2 to 50%, but every time crashes when you move, say, the slider-1 to 50% and the slider-2 to 70% on the same driver. I don't know why that occurs.
Because you're moving slider-1 past slider-2. You probably have to do slider-2 first in that case.
it's would be too easy and naive. I have checked both of them and output is the same
I'm truly don't understand how it works well for you because whenever I moving slider-1 catch the wrong measure, but the same time have to mention that slider-2 works perfectly.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.