The data is loaded dynamically via JavaScript. You can use requests module to simulate it.
For example:
import json
import requests
search_parameters = {
'shapes': "Round",
'cuts': "Fair,Good,Very Good,Ideal,Super Ideal",
'colors': "J,I,H,G,F,E,D",
'clarities': "SI2,SI1,VS2,VS1,VVS2,VVS1,IF,FL",
'polishes': "Good,Very Good,Excellent",
'symmetries': "Good,Very Good,Excellent",
'fluorescences': "Very Strong,Strong,Medium,Faint,None",
'min_carat': "0.25",
'max_carat': "11.58",
'min_table': "50.00",
'max_table': "86.00",
'min_depth': "46.20",
'max_depth': "629.00",
'min_price': "420",
'max_price': "1258930",
'stock_number': "",
'row': "0",
'page': "1",
'requestedDataSize': "200",
'order_by': "price",
'order_method': "asc",
'currency': "$",
'has_v360_video': "",
'dedicated': "",
'sid': "",
'min_ratio': "1.00",
'max_ratio': "2.75",
'shipping_day': "",
'MIN_PRICE': "420",
'MAX_PRICE': "1258930",
'MIN_CARAT': "0.25",
'MAX_CARAT': "11.58",
'MIN_TABLE': "45",
'MAX_TABLE': "86",
'MIN_DEPTH': "46.2",
'MAX_DEPTH': "629"
}
data = requests.get('https://www.brilliantearth.com/loose-diamonds/list/', params=search_parameters).json()
# uncomment this to print all data:
# print(json.dumps(data, indent=4))
for d in data['diamonds']:
print('{:<30} {:<15} {}'.format(d['title'], d['cut'], d['price']))
Prints:
0.30 Carat Round Diamond Very Good 420
0.30 Carat Round Diamond Very Good 420
0.30 Carat Round Diamond Ideal 430
0.30 Carat Round Diamond Ideal 430
0.30 Carat Round Diamond Good 430
0.30 Carat Round Diamond Ideal 430
0.30 Carat Round Diamond Very Good 430
0.25 Carat Round Diamond Super Ideal 430
0.30 Carat Round Diamond Very Good 430
0.32 Carat Round Diamond Ideal 430
... and so on.