├── README.md ├── data ├── custom_message.xlsx ├── history.xlsx ├── list_publish.xlsx ├── publish_on.xlsx ├── search_product.xlsx ├── search_result.xlsx ├── setting.xlsx ├── short_url.xlsx └── support_dev.xlsx ├── main.py ├── publish.py ├── requirements.txt └── search_products.py /README.md: -------------------------------------------------------------------------------- 1 |

Amacapy

2 |

Amacapy is a program that focuses on web scraping amazon.com, amazon.es and amazon.it. The data extracted are the price, title and URL of the products searched, then with the help of a Telegram bot created with Bot Father, these are published in a certain time.

3 | 4 |

Download the new version here.

5 | 6 | 7 | 8 |

Old version

9 |

Libraries and technologies used:

10 |
  • Python 3.10.1.
  • 11 |
  • Beautifulsoup4 v4.11.1 and Requests v2.28.1 (For the web scraping)
  • 12 |
  • Flet v0.3.2. (For the graphical interface)
  • 13 |
  • Pandas v1.5.2. (For saving and manipulating information from xlsx files)
  • 14 |
  • Pyshorteners v1.0.1. (To shorten the links of the publications)
  • 15 | 16 | 17 |

    How to use Amacapy?

    18 |
  • 1. Create a bot with BotFather.
  • 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
  • 2. Install the necessary libraries. You can do it in the following way:
  • 27 | 28 | 29 | 30 | 31 |
  • 3. Open the "main.py" file containing the main program.
  • 32 | 33 |
  • 4. Add your data (amazon id, telegram token, chat id) in the configuration.
  • 34 | 35 | 36 | 37 |

    Example:

    38 | 39 | 40 |
  • 5. Search products.
  • 41 | 42 | 43 | 44 | 45 |

    Example:

    46 | 47 | 48 |
  • 6. Search results.
  • 49 | 50 | 51 | 52 |

    Example:

    53 | 54 | 55 |
  • 7. Publication list.
  • 56 | 57 | 58 | 59 |

    Example:

    60 | 61 | 62 |
  • 7. History of published products.
  • 63 | 64 |

    Example:

    65 | 66 | 67 |
  • 8. Modify the text displayed in the Telegram post (Optional).
  • 68 | 69 |

    Example:

    70 | 71 | 72 | 73 |
  • 9.Add link shortener (Optional).
  • 74 | 75 | 76 |

    Example:

    77 | 78 | 79 |
  • 10. Supporting the developer.
  • 80 | 81 |

    Example:

    82 | 83 | 84 | 85 |

    Where are the data stored? (Do not manually delete or modify these files)

    86 |
  • 1. The configuration is stored in the file: setting.xlsx.
  • 87 |
  • 2. The search_product.xlsx file stores the data entered in the search screen (product keyword and Amazon region).
  • 88 |
  • 3. The search result is stored in the file: search_result.xlsx.
  • 89 |
  • 4. Products added to the publication list are stored in: list_publish.xlsx.
  • 90 |
  • 5. The publish_on.xlsx file stores the products that are being published.
  • 91 |
  • 6. The history.xlsx file stores the products that have been published, including their publication date.
  • 92 |
  • 7. The custom Telegram post message is stored in the file custom_message.xlsx.
  • 93 |
  • 8. The link shortener data is stored in the file: short_url.xlsx.
  • 94 |
  • 9. The support_dev.xlsx file stores whether or not the developer will be supported by the affiliate link.
  • 95 | 96 | 97 |

    Thank you for using the program, you can support me through Paypal.

    98 |

    You can contact me on Telegram.

    99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /data/custom_message.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/custom_message.xlsx -------------------------------------------------------------------------------- /data/history.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/history.xlsx -------------------------------------------------------------------------------- /data/list_publish.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/list_publish.xlsx -------------------------------------------------------------------------------- /data/publish_on.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/publish_on.xlsx -------------------------------------------------------------------------------- /data/search_product.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/search_product.xlsx -------------------------------------------------------------------------------- /data/search_result.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/search_result.xlsx -------------------------------------------------------------------------------- /data/setting.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/setting.xlsx -------------------------------------------------------------------------------- /data/short_url.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/short_url.xlsx -------------------------------------------------------------------------------- /data/support_dev.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulasoft/Amacapy-Bot-Telegram-Amazon-Affiliates/59044c2d107df836161a073215e959e60664486f/data/support_dev.xlsx -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import flet as ft 2 | from flet import Page, Text, Row, TextField, ElevatedButton, Checkbox, Column, Container, IconButton, Theme 3 | import time 4 | from time import sleep 5 | import requests 6 | import io 7 | from io import open 8 | import webbrowser 9 | import pandas as pd 10 | from pandas import ExcelWriter 11 | from datetime import datetime 12 | from multiprocessing import Process 13 | import search_products 14 | import publish 15 | from os import remove 16 | 17 | 18 | # Starting the scripts that will search for products on Amazon and post on Telegram. 19 | def script_search_products(): 20 | search_products.enable(True) 21 | 22 | def script_publish(): 23 | publish.enable(True) 24 | 25 | 26 | 27 | if __name__ == '__main__': 28 | 29 | processes_search_product = [] 30 | processes_publish_product = [] 31 | for i in range(0, 500): 32 | processes_search_product.append(Process(target=script_search_products)) 33 | processes_publish_product.append(Process(target=script_publish)) 34 | 35 | # thread_search_product = Process(target=script_search_products) 36 | # thread_publish_product = Process(target=script_publish) 37 | 38 | def main(page: ft.Page): 39 | 40 | # Defining the program title and design 41 | page.window_maximizable = True 42 | page.title = "Amacapy 2.0" 43 | page.vertical_alignment = "center" 44 | page.horizontal_alignment = "center" 45 | page.window_width = 720 46 | page.window_height = 680 47 | page.window_resizable = True 48 | page.theme_mode = ft.ThemeMode.DARK 49 | 50 | 51 | 52 | 53 | title_amacapy = Text( 54 | value="Amacapy", 55 | size=30, 56 | color="white", 57 | weight="bold", 58 | italic=True, 59 | ) 60 | page.add(title_amacapy) 61 | 62 | def main_interface(): 63 | 64 | # This function will display the screen with the list of products that will be ready to be published. 65 | def page_publish(self): 66 | try: 67 | # We read the file where the product data is stored 68 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 69 | 70 | except: 71 | sleep(2) 72 | try: 73 | # We read the file where the product data is stored 74 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 75 | except: 76 | remove('data/list_publish.xlsx') 77 | update_list_publish_data = pd.DataFrame(columns = ['title', 'price', 'currency', 'url']) 78 | with ExcelWriter('data/list_publish.xlsx') as writer: 79 | update_list_publish_data.to_excel(writer, 'Sheet', index=False) 80 | 81 | title_list_publish = verify_list_publish['title'].values 82 | price_list_publish = verify_list_publish['price'].values 83 | currency_list_publish = verify_list_publish['currency'].values 84 | url_list_publish = verify_list_publish['url'].values 85 | 86 | # Title that will appear in the publish products view. 87 | title_head_list_publish = Text( 88 | value="Products to Publish", 89 | size=20, 90 | color="white", 91 | weight="bold", 92 | italic=True, 93 | ) 94 | 95 | all_results = ft.Column(scroll="always", expand=True) 96 | 97 | # The file is checked for stored data to be able to display it on the screen. 98 | if len(verify_list_publish) > 0: 99 | currency = f"({currency_list_publish[0]})" 100 | 101 | for i in range(len(verify_list_publish)): 102 | 103 | all_results.controls.append( 104 | ft.Row(spacing=28, run_spacing=5, controls=[ 105 | Text(f"{i+1}. "), 106 | ft.IconButton(on_click=view_url_list_publish, data = i, icon="remove_red_eye_rounded", icon_size=20), 107 | ft.TextField(value=title_list_publish[i], label = i, on_blur=change_title_publish, text_align="start", keyboard_type = "text", width=250, height = 50, text_size=12, content_padding = 10), 108 | ft.TextField(value=price_list_publish[i], label = i, on_blur=change_price_publish, text_align="start", keyboard_type = "number", width=70, height = 50, text_size=12, content_padding = 10), 109 | ft.IconButton(on_click=delete_product_button, data = i, icon="delete_forever_rounded", icon_size=20), 110 | ], alignment="center", vertical_alignment = "center") 111 | 112 | ) 113 | 114 | # If the file has no data, then a message that there are no products is displayed. 115 | else: 116 | currency = '' 117 | all_results.controls.append( 118 | ft.Row(spacing=40, run_spacing=10, controls=[ 119 | Text("You have not yet added articles for publication") 120 | ], alignment="center", vertical_alignment = "center") 121 | 122 | ) 123 | 124 | page.clean() # We clean the screen before adding a new one. 125 | page.add( 126 | ft.Container(height = 50, content= title_head_list_publish, alignment=ft.alignment.center), 127 | ft.Divider(height=1, color="black"), 128 | ft.Row(spacing=1, controls=[ 129 | Text('N°', color="white", width=55, text_align="center"), 130 | Text('View', color="white", width=60, text_align="center"), 131 | Text('Product Title', color="white", width=290, text_align="center"), 132 | Text(f'Price {currency}', color="white", width=80, text_align="center"), 133 | Text('Del',width=80, text_align="center", color="white"), 134 | ], 135 | alignment="center", vertical_alignment = "center"), 136 | ft.Divider(height=1, color="black"), 137 | ft.Container(width= 650, height= 348, content=all_results), 138 | ft.Container(width= 650, height= 40, content=ft.Row(controls=[ 139 | ft.ElevatedButton("Delete All", icon="delete_rounded", on_click=delete_all_products_publish) 140 | ], 141 | alignment="end", vertical_alignment = "start") 142 | ), 143 | ft.Row(controls=[ 144 | Text('Publish every', width=90, text_align="start",color="white"), 145 | minutes_publish, 146 | Text('on', width=20, text_align="start", color="white"), 147 | ft.ElevatedButton('Telegram' ,icon="telegram_rounded", on_click=publish_on_telegram), 148 | ], 149 | alignment="center", vertical_alignment = "center"), 150 | ft.Container(content= ft.Row(controls=list_all_button_menu, 151 | alignment="center", vertical_alignment = "end"), 152 | height = 50 153 | ) 154 | ) 155 | 156 | # The same process is repeated as in the page_publish function 157 | # But in this case to see the history of published products. 158 | def page_history(self): 159 | # The file that stores the history of published products is read. 160 | verify_history = pd.read_excel('data/history.xlsx', header = 0) 161 | 162 | date_history = verify_history['date'].values 163 | title_history = verify_history['title'].values 164 | price_history = verify_history['price'].values 165 | url_history = verify_history['url'].values 166 | platform_history = verify_history['platform'].values 167 | 168 | # Title that will appear in the history view. 169 | title_list_history = Text( 170 | value="History of published products", 171 | size=20, 172 | color="white", 173 | weight="bold", 174 | italic=True, 175 | ) 176 | 177 | all_results = ft.Column(scroll="always", expand=True) 178 | 179 | # The file is checked for stored data to be able to display it on the screen. 180 | if len(verify_history) > 0: 181 | 182 | for i in range(len(verify_history)): 183 | new_date = date_history[i] 184 | new_date = pd.to_datetime(new_date) 185 | new_date = datetime.strftime(new_date, '%Y-%m-%d') 186 | 187 | all_results.controls.append( 188 | ft.Row(spacing=28, run_spacing=5, controls=[ 189 | Text(f"{i+1}. "), 190 | ft.IconButton(on_click=view_url_history, data = i, icon="remove_red_eye_rounded", icon_size=20), 191 | ft.TextField(value=title_history[i], read_only = True, text_align="start", keyboard_type = "text", width=250, height = 50, text_size=12, content_padding = 10), 192 | ft.Text(color="white", value=price_history[i], width=80, text_align="center"), 193 | ft.Text(color="white", value=platform_history[i]), 194 | ft.Text(color="white", value=new_date) 195 | ], alignment="center", vertical_alignment = "center") 196 | 197 | ) 198 | # If the file has no data, then a message that there are no products is displayed. 199 | else: 200 | currency = '' 201 | all_results.controls.append( 202 | ft.Row(spacing=40, run_spacing=10, controls=[ 203 | Text("You have not yet added articles for publication", color="white") 204 | ], alignment="center", vertical_alignment = "center") 205 | 206 | ) 207 | # The view is cleaned before adding another one. 208 | page.clean() 209 | page.add( 210 | ft.Container(height = 50, content= title_list_history, alignment=ft.alignment.center), 211 | ft.Divider(height=1, color="black"), 212 | ft.Row(spacing=10, controls=[ 213 | Text('N°', width=20, text_align="center", color="white"), 214 | Text('View', width=80, text_align="center", color="white"), 215 | Text('Product Title', width=270, text_align="center", color="white"), 216 | Text(f'Price', width=95, text_align="center", color="white"), 217 | Text(f'Platform', width=65, text_align="center",color="white"), 218 | Text(f'Date', width=100, text_align="center", color="white") 219 | ], 220 | alignment="center", vertical_alignment = "center"), 221 | ft.Divider(height=1, color="black"), 222 | ft.Container(width= 710, height= 408, content=all_results), 223 | ft.Container(width= 710, height= 40, content=ft.Row(controls=[ 224 | ft.ElevatedButton("Delete All", icon="delete_rounded", on_click=delete_all_history) 225 | ], 226 | alignment="end", vertical_alignment = "start") 227 | ), 228 | ft.Container(content= ft.Row(controls=list_all_button_menu, 229 | alignment="center", vertical_alignment = "end"), 230 | height = 50 231 | ) 232 | ) 233 | 234 | # Function to stop the publication of products 235 | def stop_publish_on(e): 236 | 237 | # To read the data contained in the file that stores the products to be published. 238 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0) 239 | 240 | # To remove the data from the file of the products to be published. 241 | update_publish_on = pd.DataFrame(columns = ['title', 'price', 'url', 'min', 'telegram']) 242 | 243 | # This loop will check if the file still has data. If it has data, it will proceed to delete it. 244 | while len(verify_publish_on) !=0: 245 | try: 246 | with ExcelWriter('data/publish_on.xlsx') as writer: 247 | update_publish_on.to_excel(writer, 'Sheet', index=False) 248 | 249 | processes_publish_product[0].kill() 250 | processes_publish_product.pop(0) 251 | 252 | except Exception as e: 253 | print('Error: ' + str(e)) 254 | sleep(1) 255 | with ExcelWriter('data/publish_on.xlsx') as writer: 256 | update_publish_on.to_excel(writer, 'Sheet', index=False) 257 | 258 | processes_publish_product[0].kill() 259 | processes_publish_product.pop(0) 260 | 261 | 262 | # The file is rechecked to see if it still has data. 263 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0) 264 | sleep(1) 265 | 266 | # The function that displays the products to be published is called 267 | page_publish(1) 268 | 269 | # This function will show when products are being published. 270 | def page_publish_on(e): 271 | 272 | # To read the data contained in the file that stores the products to be published. 273 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0) 274 | 275 | if len(verify_publish_on) == 0: 276 | pass 277 | else: 278 | processes_publish_product[0].start() 279 | page.clean() 280 | 281 | # Text that will display the message "Publishing products..." 282 | publish_text = Text( 283 | value=f"Publishing products...", 284 | size=15, 285 | color="white", 286 | italic=False, 287 | ) 288 | 289 | # Text with the number of products still to be released 290 | yet_publish_text = Text( 291 | value=f"{len(verify_publish_on)} to publish", 292 | size=15, 293 | color="white", 294 | italic=False, 295 | ) 296 | page.add( 297 | ft.Container(content= ft.Column(controls=[ 298 | ft.Row(alignment="center", controls=[publish_text]), 299 | yet_publish_text, 300 | press_button_publish_on_stop 301 | ], horizontal_alignment = "center", alignment="center"), 302 | height= 520 303 | 304 | 305 | ), 306 | ft.Container(content= ft.Row(controls=list_all_button_menu, 307 | alignment="center", vertical_alignment = "end"), 308 | height = 100 309 | ) 310 | ) 311 | 312 | 313 | # As long as there are products to be published, the screen will be updated. 314 | while len(verify_publish_on) !=0 and processes_publish_product[0].is_alive(): 315 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0) 316 | publish_text = Text( 317 | value=f"Publishing products...", 318 | size=15, 319 | color="white", 320 | italic=False, 321 | ) 322 | yet_publish_text = Text( 323 | value=f"{len(verify_publish_on)} to publish", 324 | size=15, 325 | color="white", 326 | italic=False, 327 | ) 328 | page.clean() 329 | page.add( 330 | ft.Container(content= ft.Column(controls=[ 331 | ft.Row(alignment="center", controls=[publish_text]), 332 | yet_publish_text, 333 | press_button_publish_on_stop 334 | ], horizontal_alignment = "center", alignment="center"), 335 | height= 520 336 | 337 | 338 | ), 339 | ft.Container(content= ft.Row(controls=list_all_button_menu, 340 | alignment="center", vertical_alignment = "end"), 341 | height = 100 342 | ) 343 | ) 344 | sleep(5) 345 | verify_publish_on = pd.read_excel('data/publish_on.xlsx', header = 0) 346 | 347 | # When there are no more products to be published, it will call the function that displays the products to be published. 348 | else: 349 | if processes_publish_product[0].is_alive(): 350 | processes_publish_product[0].kill() 351 | processes_publish_product.pop(0) 352 | page_publish(1) 353 | 354 | # Function that adds the products to the file that will store the products that will be published. 355 | def publish_on_telegram(e): 356 | # To check the list of products to be published 357 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 358 | title_publish = verify_list_publish['title'].values 359 | price_publish = verify_list_publish['price'].values 360 | url_publish = verify_list_publish['url'].values 361 | 362 | # To obtain how often the products will be published. 363 | minutes = minutes_publish.value 364 | 365 | # They will be used to save the data stored in list_publish.xlsx and add them to publish_on.xlsx 366 | # (this file stores the products that will be published). 367 | title_publish_on = [] 368 | price_publish_on = [] 369 | url_publish_on = [] 370 | minutes_publish_on = [] 371 | telegram_publish_on = [] 372 | 373 | for i in range(len(verify_list_publish)): 374 | title_publish_on.append(title_publish[i]) 375 | price_publish_on.append(price_publish[i]) 376 | url_publish_on.append(url_publish[i]) 377 | minutes_publish_on.append(minutes) 378 | telegram_publish_on.append('yes') 379 | 380 | 381 | add_history = {'title': title_publish_on, 'price': price_publish_on, 'url': url_publish_on, 'min': minutes_publish_on,'telegram':telegram_publish_on} 382 | 383 | update_publish_on = pd.DataFrame(add_history, columns = ['title', 'price', 'url', 'min', 'telegram']) 384 | 385 | with ExcelWriter('data/publish_on.xlsx') as writer: 386 | update_publish_on.to_excel(writer, 'Sheet', index=False) 387 | 388 | page_publish_on(1) 389 | 390 | # Function to change the message that will be displayed in Telegram posts. 391 | def change_custom_message(e): 392 | verify_custom_message = pd.read_excel('data/custom_message.xlsx', header = 0) 393 | before_title_message = verify_custom_message['before_title'].values 394 | original_price_message = verify_custom_message['original_price'].values 395 | sale_price_message = verify_custom_message['sale_price'].values 396 | currency_message = verify_custom_message['currency'].values 397 | url_message = verify_custom_message['url'].values 398 | 399 | label_message = e.control.label 400 | add_custom_message = {} 401 | 402 | if 'Before' in label_message: 403 | before_title_message = [form_before_title_message.value] 404 | 405 | elif 'Sale' in label_message: 406 | sale_price_message = [form_sale_price_message.value] 407 | 408 | elif 'Original' in label_message: 409 | original_price_message = [form_original_price_message.value] 410 | 411 | elif 'Currency' in label_message: 412 | currency_message = [form_currency_message.value] 413 | 414 | elif 'URL' in label_message: 415 | url_message = [form_url_message.value] 416 | 417 | else: 418 | pass 419 | 420 | add_custom_message['before_title'] = before_title_message 421 | add_custom_message['original_price'] = original_price_message 422 | add_custom_message['sale_price'] = sale_price_message 423 | add_custom_message['currency'] = currency_message 424 | add_custom_message['url'] = url_message 425 | 426 | update_custom_message = pd.DataFrame(add_custom_message, columns = ['before_title', 'original_price', 'sale_price', 'currency', 'url']) 427 | with ExcelWriter('data/custom_message.xlsx') as writer: 428 | update_custom_message.to_excel(writer, 'Sheet', index=False) 429 | 430 | # Function that will show the screen where the message of the products published in Telegram can be modified. 431 | def custom_message(e): 432 | verify_custom_message = pd.read_excel('data/custom_message.xlsx', header = 0) 433 | before_title_message = verify_custom_message['before_title'].values 434 | original_price_message = verify_custom_message['original_price'].values 435 | sale_price_message = verify_custom_message['sale_price'].values 436 | currency_message = verify_custom_message['currency'].values 437 | url_message = verify_custom_message['url'].values 438 | 439 | if len(verify_custom_message) != 0: 440 | form_before_title_message.value = before_title_message[0] 441 | form_sale_price_message.value = sale_price_message[0] 442 | form_original_price_message.value = original_price_message[0] 443 | form_currency_message.value = currency_message[0] 444 | form_url_message.value = url_message[0] 445 | 446 | title_custom_message = Text( 447 | value="Modify the publication message", 448 | size=20, 449 | color="white", 450 | weight="bold", 451 | italic=True, 452 | ) 453 | 454 | page.clean() 455 | page.add( 456 | ft.Container(height = 50, content= title_custom_message, alignment=ft.alignment.center), 457 | ft.Divider(height=1, color="black"), 458 | ft.Container(height= 449, content=ft.Column(controls=[ 459 | form_before_title_message, 460 | form_sale_price_message, 461 | form_original_price_message, 462 | form_currency_message, 463 | form_url_message 464 | ], 465 | alignment="center")), 466 | 467 | ft.Container(content= ft.Row(controls=list_all_button_menu, 468 | alignment="center", vertical_alignment = "end"), 469 | height = 100 470 | ) 471 | ) 472 | 473 | # Function to delete product in the list of products to be published. 474 | def delete_product_button(e): 475 | id_number = e.control.data 476 | 477 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 478 | 479 | title_publish = verify_list_publish['title'].values 480 | price_publish = verify_list_publish['price'].values 481 | currency_publish = verify_list_publish['currency'].values 482 | url_publish = verify_list_publish['url'].values 483 | 484 | new_title_publish = [] 485 | new_price_publish = [] 486 | new_currency_publish = [] 487 | new_url_publish = [] 488 | 489 | for i in range(len(verify_list_publish)): 490 | if i == id_number: 491 | pass 492 | else: 493 | new_title_publish.append(title_publish[i]) 494 | new_price_publish.append(price_publish[i]) 495 | new_currency_publish.append(currency_publish[i]) 496 | new_url_publish.append(url_publish[i]) 497 | 498 | list_publish_data = {} 499 | 500 | list_publish_data['title'] = new_title_publish 501 | list_publish_data['price'] = new_price_publish 502 | list_publish_data['currency'] = new_currency_publish 503 | list_publish_data['url'] = new_url_publish 504 | 505 | list_publish_data = pd.DataFrame(list_publish_data, columns = ['title', 'price', 'currency', 'url']) 506 | 507 | with ExcelWriter('data/list_publish.xlsx') as writer: 508 | list_publish_data.to_excel(writer, 'Sheet', index=False) 509 | page_publish(0) 510 | 511 | # Function to change Amazon ID 512 | def change_amazon_id(e): 513 | new_amazon_id = e.control.value 514 | 515 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0) 516 | amazon_id = verify_setting['amazon_id'].values 517 | telegram_token = verify_setting['telegram_token'].values 518 | chat_id = verify_setting['chat_id'].values 519 | 520 | if len(verify_setting) > 0: 521 | amazon_id = new_amazon_id 522 | 523 | if pd.isnull(telegram_token[0]): 524 | telegram_token = '' 525 | else: 526 | telegram_token = telegram_token[0] 527 | 528 | if pd.isnull(chat_id[0]): 529 | chat_id = '' 530 | else: 531 | chat_id = chat_id[0] 532 | 533 | else: 534 | amazon_id = new_amazon_id 535 | telegram_token = '' 536 | chat_id = '' 537 | 538 | setting_data = {} 539 | setting_data['amazon_id'] = [amazon_id] 540 | setting_data['telegram_token'] = [telegram_token] 541 | setting_data['chat_id'] = [chat_id] 542 | 543 | setting_data = pd.DataFrame(setting_data, columns = ['amazon_id', 'telegram_token', 'chat_id']) 544 | with ExcelWriter('data/setting.xlsx') as writer: 545 | setting_data.to_excel(writer, 'Sheet', index=False) 546 | 547 | # Function to change telegram token 548 | def change_telegram_token(e): 549 | new_telegram_token = e.control.value 550 | 551 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0) 552 | amazon_id = verify_setting['amazon_id'].values 553 | telegram_token = verify_setting['telegram_token'].values 554 | chat_id = verify_setting['chat_id'].values 555 | 556 | if len(verify_setting) > 0: 557 | telegram_token = new_telegram_token 558 | 559 | if pd.isnull(amazon_id[0]): 560 | amazon_id = '' 561 | else: 562 | amazon_id = amazon_id[0] 563 | 564 | if pd.isnull(chat_id[0]): 565 | chat_id = '' 566 | else: 567 | chat_id = chat_id[0] 568 | 569 | else: 570 | amazon_id = '' 571 | telegram_token = new_telegram_token 572 | chat_id = '' 573 | 574 | setting_data = {} 575 | setting_data['amazon_id'] = [amazon_id] 576 | setting_data['telegram_token'] = [telegram_token] 577 | setting_data['chat_id'] = [chat_id] 578 | 579 | setting_data = pd.DataFrame(setting_data, columns = ['amazon_id', 'telegram_token', 'chat_id']) 580 | with ExcelWriter('data/setting.xlsx') as writer: 581 | setting_data.to_excel(writer, 'Sheet', index=False) 582 | 583 | # Function to change chat ID 584 | def change_chat_id(e): 585 | new_chat_id = e.control.value 586 | 587 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0) 588 | amazon_id = verify_setting['amazon_id'].values 589 | telegram_token = verify_setting['telegram_token'].values 590 | chat_id = verify_setting['chat_id'].values 591 | 592 | if len(verify_setting) > 0: 593 | chat_id = new_chat_id 594 | 595 | if pd.isnull(amazon_id[0]): 596 | amazon_id = '' 597 | else: 598 | amazon_id = amazon_id[0] 599 | 600 | if pd.isnull(telegram_token[0]): 601 | telegram_token = '' 602 | else: 603 | telegram_token = telegram_token[0] 604 | 605 | else: 606 | amazon_id = '' 607 | telegram_token = '' 608 | chat_id = new_chat_id 609 | 610 | setting_data = {} 611 | setting_data['amazon_id'] = [amazon_id] 612 | setting_data['telegram_token'] = [telegram_token] 613 | setting_data['chat_id'] = [chat_id] 614 | 615 | setting_data = pd.DataFrame(setting_data, columns = ['amazon_id', 'telegram_token', 'chat_id']) 616 | with ExcelWriter('data/setting.xlsx') as writer: 617 | setting_data.to_excel(writer, 'Sheet', index=False) 618 | 619 | # Function to change the title of the products that appear in the list of products to be published. 620 | def change_title_publish(e): 621 | new_title = e.control.value # Stores the text of the form that is being modified. 622 | id_number = e.control.label # Stores the label number of the text field being modified so that it can be identified. 623 | 624 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 625 | 626 | title_publish = verify_list_publish['title'].values 627 | price_publish = verify_list_publish['price'].values 628 | currency_publish = verify_list_publish['currency'].values 629 | url_publish = verify_list_publish['url'].values 630 | 631 | title_publish[id_number] = new_title 632 | 633 | list_publish_data = {} 634 | 635 | list_publish_data['title'] = title_publish 636 | list_publish_data['price'] = price_publish 637 | list_publish_data['currency'] = currency_publish 638 | list_publish_data['url'] = url_publish 639 | 640 | list_publish_data = pd.DataFrame(list_publish_data, columns = ['title', 'price', 'currency', 'url']) 641 | 642 | try: 643 | with ExcelWriter('data/list_publish.xlsx') as writer: 644 | list_publish_data.to_excel(writer, 'Sheet', index=False) 645 | except: 646 | sleep(1) 647 | with ExcelWriter('data/list_publish.xlsx') as writer: 648 | list_publish_data.to_excel(writer, 'Sheet', index=False) 649 | 650 | 651 | # Function to change the price of the products that appear in the list of products to be published. 652 | def change_price_publish(e): 653 | new_price = e.control.value # Stores the text of the form that is being modified. 654 | id_number = e.control.label # Stores the label number of the text field being modified so that it can be identified. 655 | 656 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 657 | 658 | title_publish = verify_list_publish['title'].values 659 | price_publish = verify_list_publish['price'].values 660 | currency_publish = verify_list_publish['currency'].values 661 | url_publish = verify_list_publish['url'].values 662 | 663 | price_publish[id_number] = new_price 664 | 665 | list_publish_data = {} 666 | 667 | list_publish_data['title'] = title_publish 668 | list_publish_data['price'] = price_publish 669 | list_publish_data['currency'] = currency_publish 670 | list_publish_data['url'] = url_publish 671 | 672 | list_publish_data = pd.DataFrame(list_publish_data, columns = ['title', 'price', 'currency', 'url']) 673 | 674 | try: 675 | with ExcelWriter('data/list_publish.xlsx') as writer: 676 | list_publish_data.to_excel(writer, 'Sheet', index=False) 677 | except: 678 | sleep(1) 679 | with ExcelWriter('data/list_publish.xlsx') as writer: 680 | list_publish_data.to_excel(writer, 'Sheet', index=False) 681 | 682 | # Function to change the title of the products that appear in the list of found products. 683 | def change_title_result(e): 684 | new_title = e.control.value # Stores the text of the form that is being modified. 685 | id_number = e.control.label # Stores the label number of the text field being modified so that it can be identified. 686 | 687 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0) 688 | 689 | title_result = verify_search_result['title'].values 690 | price_result = verify_search_result['price'].values 691 | currency_result = verify_search_result['currency'].values 692 | check_result = verify_search_result['check'].values 693 | url_result = verify_search_result['url'].values 694 | 695 | title_result[id_number] = new_title 696 | 697 | search_result_data = {} 698 | 699 | search_result_data['title'] = title_result 700 | search_result_data['price'] = price_result 701 | search_result_data['currency'] = currency_result 702 | search_result_data['check'] = check_result 703 | search_result_data['url'] = url_result 704 | 705 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url']) 706 | 707 | try: 708 | with ExcelWriter('data/search_result.xlsx') as writer: 709 | search_result_data.to_excel(writer, 'Sheet', index=False) 710 | except: 711 | sleep(1) 712 | with ExcelWriter('data/search_result.xlsx') as writer: 713 | search_result_data.to_excel(writer, 'Sheet', index=False) 714 | 715 | # Function to change the price of the products that appear in the list of found products. 716 | def change_price_result(e): 717 | new_price = e.control.value # Stores the text of the form that is being modified. 718 | id_number = e.control.label # Stores the label number of the text field being modified so that it can be identified. 719 | 720 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0) 721 | title_result = verify_search_result['title'].values 722 | price_result = verify_search_result['price'].values 723 | currency_result = verify_search_result['currency'].values 724 | check_result = verify_search_result['check'].values 725 | url_result = verify_search_result['url'].values 726 | 727 | price_result[id_number] = new_price 728 | 729 | search_result_data = {} 730 | 731 | search_result_data['title'] = title_result 732 | search_result_data['price'] = price_result 733 | search_result_data['currency'] = currency_result 734 | search_result_data['check'] = check_result 735 | search_result_data['url'] = url_result 736 | 737 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url']) 738 | 739 | try: 740 | with ExcelWriter('data/search_result.xlsx') as writer: 741 | search_result_data.to_excel(writer, 'Sheet', index=False) 742 | except: 743 | sleep(1) 744 | with ExcelWriter('data/search_result.xlsx') as writer: 745 | search_result_data.to_excel(writer, 'Sheet', index=False) 746 | 747 | # Function that enables and disables application development support 748 | def support_development(e): 749 | verify_status_support = pd.read_excel('data/support_dev.xlsx', header = 0) 750 | status = e.control.value 751 | support_data = {} 752 | 753 | if status: 754 | switch_supp_dev.label = 'Supporting Development On 😊' 755 | support_data['sup_tag'] = ['amla02-20'] 756 | support_data['sup_dev'] = ['yes'] 757 | 758 | else: 759 | switch_supp_dev.label = 'Supporting Development Off 😢' 760 | support_data['sup_tag'] = ['amla02-20'] 761 | support_data['sup_dev'] = ['no'] 762 | 763 | update_status_support = pd.DataFrame(support_data, columns = ['sup_tag', 'sup_dev']) 764 | 765 | with ExcelWriter('data/support_dev.xlsx') as writer: 766 | update_status_support.to_excel(writer, 'Sheet', index=False) 767 | 768 | page.update() 769 | 770 | # Function that will add the products to the list of products to be published. 771 | def add_to_publish(self): 772 | 773 | # The data stored in the searched products is checked. 774 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0) 775 | # To be stored in the following variables: 776 | title_result = verify_search_result['title'].values 777 | price_result = verify_search_result['price'].values 778 | currency_result = verify_search_result['currency'].values 779 | check_result = verify_search_result['check'].values 780 | url_result = verify_search_result['url'].values 781 | 782 | # The data stored in the list of products to be published are checked. 783 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 784 | # It will be stored in the following variables: 785 | title_publish = verify_list_publish['title'].values 786 | price_publish = verify_list_publish['price'].values 787 | currency_publish = verify_list_publish['currency'].values 788 | url_publish = verify_list_publish['url'].values 789 | 790 | count = 0 # Counter to be used to identify each item stored in the lists obtained from the Excel files. 791 | 792 | # The new variables will store the existing data in the list of products to be published and products found, 793 | # and will also store the new data to be added. 794 | new_title_result = [] 795 | new_price_result = [] 796 | new_currency_result = [] 797 | new_check_result = [] 798 | new_url_result = [] 799 | 800 | new_title_publish = [] 801 | new_price_publish = [] 802 | new_currency_publish = [] 803 | new_url_publish = [] 804 | 805 | # It is verified that the file with the data of the products to be published has information. 806 | if len(verify_list_publish) > 0: 807 | # By means of a loop, the current information of the products to be published is stored in the new variables. 808 | for i in range(len(verify_list_publish)): 809 | new_title_publish.append(title_publish[i]) 810 | new_price_publish.append(price_publish[i]) 811 | new_currency_publish.append(currency_publish[i]) 812 | new_url_publish.append(url_publish[i]) 813 | 814 | # It is verified that the file with the data of the products to be published has information. 815 | if len(verify_search_result) > 0: 816 | # Through this loop we can check the products that have been selected to be published. 817 | # This information is stored in search_result.xlsx 818 | for check_status in check_result: 819 | # Products stored in the search_result.xlsx document that contain 820 | # the value "no" in the check field will be stored in the new found products variables. 821 | if check_status == 'no': 822 | new_title_result.append(title_result[count]) 823 | new_price_result.append(price_result[count]) 824 | new_currency_result.append(currency_result[count]) 825 | new_check_result.append(check_result[count]) 826 | new_url_result.append(url_result[count]) 827 | # On the other hand, if they have the value "yes", they will be stored in the variables 828 | # that will be used to store the information in the list_publish.xlsx document. 829 | else: 830 | new_title_publish.append(title_result[count]) 831 | new_price_publish.append(price_result[count]) 832 | new_currency_publish.append(currency_result[count]) 833 | new_url_publish.append(url_result[count]) 834 | 835 | count+=1 836 | 837 | list_publish_data = {} 838 | list_publish_data['title'] = new_title_publish 839 | list_publish_data['price'] = new_price_publish 840 | list_publish_data['currency'] = new_currency_publish 841 | list_publish_data['url'] = new_url_publish 842 | 843 | list_publish_data = pd.DataFrame(list_publish_data, columns = ['title', 'price', 'currency', 'url']) 844 | 845 | with ExcelWriter('data/list_publish.xlsx') as writer: 846 | list_publish_data.to_excel(writer, 'Sheet', index=False) 847 | 848 | search_result_data = {} 849 | 850 | search_result_data['title'] = new_title_result 851 | search_result_data['price'] = new_price_result 852 | search_result_data['currency'] = new_currency_result 853 | search_result_data['check'] = new_check_result 854 | search_result_data['url'] = new_url_result 855 | 856 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url']) 857 | 858 | with ExcelWriter('data/search_result.xlsx') as writer: 859 | search_result_data.to_excel(writer, 'Sheet', index=False) 860 | 861 | page_search_result(0) 862 | else: 863 | pass 864 | 865 | # Function to delete the products added in the search result. 866 | def select_all_search_result(e): 867 | # The data stored in the searched products is checked. 868 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0) 869 | 870 | # To be stored in the following variables: 871 | title_result = verify_search_result['title'].values 872 | price_result = verify_search_result['price'].values 873 | currency_result = verify_search_result['currency'].values 874 | check_result = verify_search_result['check'].values 875 | url_result = verify_search_result['url'].values 876 | 877 | status_select = e.control.text 878 | 879 | # For all products to be selected, "yes" must be placed in the "check" column. 880 | new_check_values = [] 881 | for i in range(len(verify_search_result)): 882 | if 'Unselect' in status_select: 883 | new_check_values.append('no') 884 | else: 885 | new_check_values.append('yes') 886 | 887 | update_data = {} 888 | update_data['title'] = title_result 889 | update_data['price'] = price_result 890 | update_data['currency'] = currency_result 891 | update_data['check'] = new_check_values 892 | update_data['url'] = url_result 893 | 894 | search_result_data = pd.DataFrame(update_data, columns = ['title', 'price', 'currency', 'check', 'url']) 895 | 896 | with ExcelWriter('data/search_result.xlsx') as writer: 897 | search_result_data.to_excel(writer, 'Sheet', index=False) 898 | sleep(1) 899 | page_search_result(1) 900 | 901 | 902 | # Function to delete the products added in the history. 903 | def delete_all_history(self): 904 | history_data = pd.DataFrame(columns = ['date', 'title', 'price', 'url', 'platform']) 905 | 906 | with ExcelWriter('data/history.xlsx') as writer: 907 | history_data.to_excel(writer, 'Sheet', index=False) 908 | sleep(1) 909 | page_history(1) 910 | 911 | # Function to delete the products added in the search result. 912 | def delete_all_search_result(self): 913 | search_result_data = pd.DataFrame(columns = ['title', 'price', 'currency', 'check', 'url']) 914 | 915 | with ExcelWriter('data/search_result.xlsx') as writer: 916 | search_result_data.to_excel(writer, 'Sheet', index=False) 917 | sleep(1) 918 | page_search_result(1) 919 | 920 | # Function to delete the products added to the list of products to be published. 921 | def delete_all_products_publish(self): 922 | list_publish_data = pd.DataFrame(columns = ['title', 'price', 'currency', 'url']) 923 | 924 | with ExcelWriter('data/list_publish.xlsx') as writer: 925 | list_publish_data.to_excel(writer, 'Sheet', index=False) 926 | sleep(1) 927 | page_publish(1) 928 | 929 | # Function to select the products shown in the search result that will be added to the list of products to be published. 930 | def check_button(e): 931 | e.control.selected = not e.control.selected 932 | e.control.update() 933 | 934 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0) 935 | title_result = verify_search_result['title'].values 936 | price_result = verify_search_result['price'].values 937 | currency_result = verify_search_result['currency'].values 938 | check_result = verify_search_result['check'].values 939 | url_result = verify_search_result['url'].values 940 | 941 | if e.control.selected == False: 942 | pass 943 | else: 944 | check_result[e.control.data] = 'yes' 945 | 946 | if e.control.selected == True: 947 | pass 948 | else: 949 | check_result[e.control.data] = 'no' 950 | 951 | search_result_data = {} 952 | search_result_data['title'] = title_result 953 | search_result_data['price'] = price_result 954 | search_result_data['currency'] = currency_result 955 | search_result_data['check'] = check_result 956 | search_result_data['url'] = url_result 957 | 958 | 959 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url']) 960 | try: 961 | with ExcelWriter('data/search_result.xlsx') as writer: 962 | search_result_data.to_excel(writer, 'Sheet', index=False) 963 | except: 964 | sleep(1) 965 | with ExcelWriter('data/search_result.xlsx') as writer: 966 | search_result_data.to_excel(writer, 'Sheet', index=False) 967 | 968 | 969 | # Function to open the URL of the products added in the list of products to be published. 970 | def view_url_list_publish(e): 971 | try: 972 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 973 | title_publish = verify_list_publish['title'].values 974 | url_publish = verify_list_publish['url'].values 975 | except: 976 | sleep(1) 977 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 978 | title_publish = verify_list_publish['title'].values 979 | url_publish = verify_list_publish['url'].values 980 | 981 | webbrowser.open(url_publish[e.control.data]) 982 | 983 | # Function to open the URL of the products added in the history of published products. 984 | def view_url_history(e): 985 | try: 986 | verify_history = pd.read_excel('data/history.xlsx', header = 0) 987 | url_history = verify_history['url'].values 988 | 989 | except: 990 | sleep(1) 991 | verify_history = pd.read_excel('data/history.xlsx', header = 0) 992 | url_history = verify_history['url'].values 993 | 994 | webbrowser.open(url_history[e.control.data]) 995 | 996 | # Function to open the URL of the products added in the search result. 997 | def view_url_search_result(e): 998 | try: 999 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0) 1000 | title_result = verify_search_result['title'].values 1001 | url_result = verify_search_result['url'].values 1002 | except: 1003 | sleep(1) 1004 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0) 1005 | title_result = verify_search_result['title'].values 1006 | url_result = verify_search_result['url'].values 1007 | 1008 | webbrowser.open(url_result[e.control.data]) 1009 | 1010 | # Function that displays the search result page. 1011 | def page_search_result(self): 1012 | 1013 | verify_search_result = pd.read_excel('data/search_result.xlsx', header = 0) 1014 | 1015 | title_result = verify_search_result['title'].values 1016 | price_result = verify_search_result['price'].values 1017 | currency_result = verify_search_result['currency'].values 1018 | check_result = verify_search_result['check'].values 1019 | url_result = verify_search_result['url'].values 1020 | 1021 | all_results = ft.Column(scroll="always", expand=True) 1022 | 1023 | show_price_0 = switch_show_price_0.value 1024 | 1025 | if 'no' in check_result: 1026 | select_products = ft.ElevatedButton(text = "Select All", icon="check_box_outlined", on_click=select_all_search_result) 1027 | else: 1028 | select_products = ft.ElevatedButton(text = "Unselect All", icon="check_box_outline_blank_rounded", on_click=select_all_search_result) 1029 | 1030 | check = [] 1031 | 1032 | if show_price_0: 1033 | switch_show_price_0.label = 'Showing all products found' 1034 | if len(verify_search_result) > 0: 1035 | currency = f"({currency_result[0]})" 1036 | for c in check_result: 1037 | if c == 'yes': 1038 | check.append(True) 1039 | else: 1040 | check.append(False) 1041 | 1042 | for i in range(len(check_result)): 1043 | 1044 | all_results.controls.append( 1045 | ft.Row(spacing=28, run_spacing=5, controls=[ 1046 | Text(f"{i+1}. "), 1047 | ft.IconButton(on_click=view_url_search_result, data = i, icon="remove_red_eye_rounded", icon_size=20), 1048 | ft.TextField(value=title_result[i], label = i, on_blur=change_title_result, text_align="start", keyboard_type = "text", width=250, height = 50, text_size=12, content_padding = 10), 1049 | ft.TextField(value=price_result[i], label = i, on_blur=change_price_result, text_align="start", keyboard_type = "number", width=70, height = 50, text_size=12, content_padding = 10), 1050 | ft.IconButton(on_click=check_button, data = i, icon="check_box_outline_blank_rounded", selected=check[i], selected_icon="check_box_rounded", icon_size=20), 1051 | ], alignment="center", vertical_alignment = "center") 1052 | ) 1053 | 1054 | 1055 | else: 1056 | currency = '' 1057 | all_results.controls.append( 1058 | ft.Row(spacing=40, run_spacing=10, controls=[ 1059 | Text("You have not yet searched for products") 1060 | ], alignment="center", vertical_alignment = "center") 1061 | ) 1062 | 1063 | else: 1064 | switch_show_price_0.label = 'Hiding unpriced products' 1065 | if len(verify_search_result) > 0: 1066 | currency = f"({currency_result[0]})" 1067 | for i in range(len(verify_search_result)): 1068 | if check_result[i] == 'yes': 1069 | check.append(True) 1070 | else: 1071 | check.append(False) 1072 | 1073 | if price_result[i] == 0: 1074 | pass 1075 | else: 1076 | all_results.controls.append( 1077 | ft.Row(spacing=28, run_spacing=5, controls=[ 1078 | Text(f"{i+1}. "), 1079 | ft.IconButton(on_click=view_url_search_result, data = i, icon="remove_red_eye_rounded", icon_size=20), 1080 | ft.TextField(value=title_result[i], label = i, on_blur=change_title_result, text_align="start", keyboard_type = "text", width=250, height = 50, text_size=12, content_padding = 10), 1081 | ft.TextField(value=price_result[i], label = i, on_blur=change_price_result, text_align="start", keyboard_type = "number", width=70, height = 50, text_size=12, content_padding = 10), 1082 | ft.IconButton(on_click=check_button, data = i, icon="check_box_outline_blank_rounded", selected=check[i], selected_icon="check_box_rounded", icon_size=20), 1083 | ], alignment="center", vertical_alignment = "center") 1084 | ) 1085 | else: 1086 | currency = '' 1087 | all_results.controls.append( 1088 | ft.Row(spacing=40, run_spacing=10, controls=[ 1089 | Text("You have not yet searched for products") 1090 | ], alignment="center", vertical_alignment = "center") 1091 | ) 1092 | 1093 | 1094 | page.clean() 1095 | title_search_result = Text( 1096 | value="Search Result", 1097 | size=20, 1098 | color="white", 1099 | weight="bold", 1100 | italic=True, 1101 | ) 1102 | 1103 | page.add( 1104 | ft.Container(height = 50, content= title_search_result, alignment=ft.alignment.center), 1105 | ft.Divider(height=1, color="black"), 1106 | ft.Row(spacing=1, controls=[ 1107 | Text('N°', width=55, text_align="center"), 1108 | Text('View', width=60, text_align="center"), 1109 | Text('Product Title', width=290, text_align="center"), 1110 | Text(f'Price {currency}', width=80, text_align="center"), 1111 | Text('Check',width=80, text_align="center"), 1112 | ], 1113 | alignment="center", vertical_alignment = "center"), 1114 | ft.Divider(height=1, color="black"), 1115 | ft.Container(height= 358, content=all_results), 1116 | ft.Row(controls=[ 1117 | ft.ElevatedButton("Add to Publish", icon="add_circle_outline_rounded", on_click=add_to_publish), 1118 | ft.ElevatedButton("Delete All", icon="delete_rounded", on_click=delete_all_search_result), 1119 | select_products 1120 | ], 1121 | alignment="center", vertical_alignment = "start"), 1122 | ft.Row(controls=[switch_show_price_0], alignment="center", vertical_alignment = "start"), 1123 | ft.Container(content= ft.Row(controls=list_all_button_menu, 1124 | alignment="center", vertical_alignment = "end"), 1125 | height = 50 1126 | ) 1127 | ) 1128 | 1129 | def stop_search_product(e): 1130 | processes_search_product[0].kill() 1131 | 1132 | processes_search_product.pop(0) 1133 | # To read the data contained in the file that stores the products to be searched. 1134 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0) 1135 | 1136 | # The data in the file that stores the search requests is deleted so that it does not continue searching. 1137 | delete_product_data = pd.DataFrame(columns = ['title', 'region', 'pub']) 1138 | 1139 | # This loop will check if the file still has data. If it has data, it will proceed to delete it. 1140 | while len(verify_search_product) !=0: 1141 | try: 1142 | with ExcelWriter('data/search_product.xlsx') as writer: 1143 | delete_product_data.to_excel(writer, 'Sheet', index=False) 1144 | except: 1145 | sleep(1) 1146 | with ExcelWriter('data/search_product.xlsx') as writer: 1147 | delete_product_data.to_excel(writer, 'Sheet', index=False) 1148 | 1149 | # The file is rechecked to see if it still has data. 1150 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0) 1151 | sleep(1) 1152 | 1153 | # The function that displays the main is called 1154 | page_main(1) 1155 | 1156 | 1157 | # Function to change the data of the products to be searched. 1158 | def change_search_product(e): 1159 | search_text = search_form.value # Stores the data entered in the product search field. 1160 | region = select_region.value # Stores the selected Amazon region. 1161 | quick_search = switch_quick_search.value 1162 | 1163 | if quick_search: 1164 | quick_search = 'yes' 1165 | else: 1166 | quick_search = 'no' 1167 | 1168 | search_product_data = {} 1169 | 1170 | search_product_data['title'] = [search_text] 1171 | search_product_data['region'] = [region] 1172 | search_product_data['pub'] = ['no'] # It is saved as 'no', to identify that the product has not been selected for publication. 1173 | search_product_data['quick'] = [quick_search] 1174 | 1175 | search_product_data = pd.DataFrame(search_product_data, columns = ['title', 'region', 'pub', 'quick']) 1176 | 1177 | verify_status_support = pd.read_excel('data/support_dev.xlsx', header = 0) 1178 | sup_tag = verify_status_support['sup_tag'].values 1179 | sup_dev = verify_status_support['sup_dev'].values 1180 | 1181 | support_data = {} 1182 | 1183 | if 'com' in region: 1184 | sup_tag = 'amla02-20' 1185 | else: 1186 | sup_tag = 'amla07-21' 1187 | 1188 | support_data['sup_tag'] = [sup_tag] 1189 | support_data['sup_dev'] = sup_dev 1190 | 1191 | update_status_support = pd.DataFrame(support_data, columns = ['sup_tag', 'sup_dev']) 1192 | try: 1193 | with ExcelWriter('data/support_dev.xlsx') as writer: 1194 | update_status_support.to_excel(writer, 'Sheet', index=False) 1195 | except: 1196 | sleep(1) 1197 | with ExcelWriter('data/support_dev.xlsx') as writer: 1198 | update_status_support.to_excel(writer, 'Sheet', index=False) 1199 | 1200 | try: 1201 | with ExcelWriter('data/search_product.xlsx') as writer: 1202 | search_product_data.to_excel(writer, 'Sheet', index=False) 1203 | except: 1204 | sleep(1) 1205 | with ExcelWriter('data/search_product.xlsx') as writer: 1206 | search_product_data.to_excel(writer, 'Sheet', index=False) 1207 | 1208 | 1209 | def search_products(e): 1210 | change_search_product(e) 1211 | sleep(1) 1212 | try: 1213 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0) 1214 | except: 1215 | sleep(2) 1216 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0) 1217 | count_progress = 0 1218 | 1219 | if len(verify_search_product) == 0: 1220 | pass 1221 | else: 1222 | processes_search_product[0].start() 1223 | 1224 | page.clean() 1225 | searching_text = Text( 1226 | value="Searching...", 1227 | size=15, 1228 | color="white", 1229 | italic=False, 1230 | ) 1231 | progress_bar = ft.ProgressBar(width=400) 1232 | page.add( 1233 | ft.Container(content= ft.Column(controls=[ 1234 | title_amacapy, 1235 | ft.Row(alignment="center", controls=[searching_text]), 1236 | progress_bar, 1237 | press_button_search_stop 1238 | ], horizontal_alignment = "center", alignment="center"), 1239 | height= 520 1240 | 1241 | 1242 | ), 1243 | ft.Container(content= ft.Row(controls=list_all_button_menu, 1244 | alignment="center", vertical_alignment = "end"), 1245 | height = 100 1246 | ) 1247 | ) 1248 | 1249 | 1250 | 1251 | while len(verify_search_product) !=0: # and processes_search_product[0].is_alive(): 1252 | try: 1253 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0) 1254 | except: 1255 | sleep(2) 1256 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0) 1257 | sleep(0.5) 1258 | progress_bar.value = count_progress * 0.01 1259 | count_progress+=1 1260 | page.clean() 1261 | page.add( 1262 | ft.Container(content= ft.Column(controls=[ 1263 | title_amacapy, 1264 | ft.Row(alignment="center", controls=[searching_text]), 1265 | progress_bar, 1266 | press_button_search_stop 1267 | ], horizontal_alignment = "center", alignment="center"), 1268 | height= 520 1269 | 1270 | 1271 | ), 1272 | ft.Container(content= ft.Row(controls=list_all_button_menu, 1273 | alignment="center", vertical_alignment = "end"), 1274 | height = 100 1275 | ) 1276 | ) 1277 | 1278 | else: 1279 | if processes_search_product[0].is_alive(): 1280 | processes_search_product[0].kill() 1281 | processes_search_product.pop(0) 1282 | 1283 | search_form.value = '' 1284 | page_search_result(1) 1285 | 1286 | # Function that displays the main page. 1287 | def page_main(e): 1288 | page.clean() 1289 | button_search = IconButton(on_click=search_products, icon="search_rounded") 1290 | page.add( 1291 | ft.Container(content= ft.Column(controls=[ 1292 | title_amacapy, 1293 | ft.Row(alignment="center", controls=[search_form, 1294 | button_search]), 1295 | select_region, 1296 | ft.Row(alignment="center", controls=[switch_quick_search]) 1297 | ], horizontal_alignment = "center", alignment="center"), 1298 | height= 520 1299 | 1300 | 1301 | ), 1302 | ft.Container(content= ft.Row(controls=list_all_button_menu, 1303 | alignment="center", vertical_alignment = "end"), 1304 | height = 100 1305 | ) 1306 | ) 1307 | 1308 | # Function that displays the setting page. 1309 | def page_settings(self): 1310 | self.page.clean() 1311 | self.title_settings = Text( 1312 | value="Settings", 1313 | size=20, 1314 | color="white", 1315 | weight="bold", 1316 | italic=True, 1317 | ) 1318 | verify_status_support = pd.read_excel('data/support_dev.xlsx', header = 0) 1319 | sup_dev = verify_status_support['sup_dev'].values 1320 | 1321 | if sup_dev[0] == 'yes': 1322 | switch_supp_dev.value = True 1323 | switch_supp_dev.label = 'Supporting Development On 😊' 1324 | elif sup_dev[0] == 'no': 1325 | switch_supp_dev.value = False 1326 | switch_supp_dev.label = 'Supporting Development Off 😢' 1327 | else: 1328 | support_data = {} 1329 | support_data['sup_tag'] = ['dsuaz'] 1330 | support_data['sup_dev'] = ['yes'] 1331 | update_status_support = pd.DataFrame(support_data, columns = ['sup_tag', 'sup_dev']) 1332 | switch_supp_dev.value = True 1333 | switch_supp_dev.label = 'Supporting Development On 😊' 1334 | 1335 | with ExcelWriter('data/support_dev.xlsx') as writer: 1336 | update_status_support.to_excel(writer, 'Sheet', index=False) 1337 | 1338 | 1339 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0) 1340 | amazon_id = verify_setting['amazon_id'].values 1341 | telegram_token = verify_setting['telegram_token'].values 1342 | chat_id = verify_setting['chat_id'].values 1343 | 1344 | if len(verify_setting) > 0: 1345 | if pd.isnull(amazon_id[0]): 1346 | form_amazon_id.value = '' 1347 | else: 1348 | form_amazon_id.value = amazon_id[0] 1349 | 1350 | if pd.isnull(telegram_token[0]): 1351 | form_telegram_token.value = '' 1352 | else: 1353 | form_telegram_token.value = telegram_token[0] 1354 | 1355 | if pd.isnull(chat_id[0]): 1356 | form_chat_id.value = '' 1357 | else: 1358 | form_chat_id.value = chat_id[0] 1359 | 1360 | else: 1361 | form_amazon_id.value = '' 1362 | form_telegram_token.value = '' 1363 | form_chat_id.value = '' 1364 | 1365 | self.page.add( 1366 | ft.Container(height = 50, content= self.title_settings, alignment=ft.alignment.center), 1367 | ft.Divider(height=1, color="black"), 1368 | ft.Container(content= ft.Column(alignment="center", controls=[ 1369 | ft.Text(value="Add your Amazon ID"), 1370 | form_amazon_id, 1371 | ft.Divider(height=30, color="transparent"), 1372 | ft.Text(value="Add your Telegram data"), 1373 | form_telegram_token, 1374 | form_chat_id, 1375 | ft.Divider(height=30, color="transparent"), 1376 | ft.Text(value="Other options"), 1377 | press_button_custom_message, 1378 | button_select_short_url], 1379 | horizontal_alignment = "center"), 1380 | height= 449 1381 | ), 1382 | ft.Container(content= ft.Row(controls=list_all_button_menu, 1383 | alignment="center", vertical_alignment = "end"), 1384 | height = 100 1385 | ) 1386 | ) 1387 | 1388 | def select_short_url(e): 1389 | short_url_label = e.control.label 1390 | short_url_value = e.control.value 1391 | 1392 | if 'Tinyurl' in short_url_label: 1393 | if short_url_value == True: 1394 | short_url = 'tinyurl' 1395 | else: 1396 | short_url = 'no' 1397 | elif 'Is.gd' in short_url_label: 1398 | if short_url_value == True: 1399 | short_url = 'isgd' 1400 | else: 1401 | short_url = 'no' 1402 | elif 'Da.gd' in short_url_label: 1403 | if short_url_value == True: 1404 | short_url = 'dagd' 1405 | else: 1406 | short_url = 'no' 1407 | else: 1408 | short_url = 'no' 1409 | 1410 | short_url_data = [short_url] 1411 | update_short_url = pd.DataFrame(short_url_data, columns = ['short_url']) 1412 | with ExcelWriter('data/short_url.xlsx') as writer: 1413 | update_short_url.to_excel(writer, 'Sheet', index=False) 1414 | 1415 | page_short_url(1) 1416 | 1417 | # Function to display the menu with the short url. 1418 | def page_short_url(e): 1419 | verify_short_url = pd.read_excel('data/short_url.xlsx', header = 0) 1420 | short_url = verify_short_url['short_url'].values 1421 | 1422 | if short_url[0] == 'tinyurl': 1423 | switch_tinyurl_short_url.value = True 1424 | switch_isgd_short_url.value = False 1425 | switch_dagd_short_url.value = False 1426 | elif short_url[0] == 'isgd': 1427 | switch_tinyurl_short_url.value = False 1428 | switch_isgd_short_url.value = True 1429 | switch_dagd_short_url.value = False 1430 | elif short_url[0] == 'dagd': 1431 | switch_tinyurl_short_url.value = False 1432 | switch_isgd_short_url.value = False 1433 | switch_dagd_short_url.value = True 1434 | else: 1435 | switch_tinyurl_short_url.value = False 1436 | switch_isgd_short_url.value = False 1437 | switch_dagd_short_url.value = False 1438 | 1439 | title_settings = Text( 1440 | value="Settings", 1441 | size=20, 1442 | color="white", 1443 | weight="bold", 1444 | italic=True, 1445 | ) 1446 | 1447 | page.clean() 1448 | 1449 | page.add( 1450 | ft.Container(height = 50, content= title_settings, alignment=ft.alignment.center), 1451 | ft.Divider(height=1, color="black"), 1452 | ft.Container(content= ft.Column(alignment="center", 1453 | controls=[ft.Row(controls=[Text(value='Select Short URL', size=16)], alignment="center"), 1454 | ft.Row(controls=[switch_tinyurl_short_url, 1455 | switch_isgd_short_url, 1456 | switch_dagd_short_url 1457 | ], alignment="center") 1458 | ], 1459 | horizontal_alignment = "center"), 1460 | width=400, height= 449 1461 | ), 1462 | ft.Container(content= ft.Row(controls=list_all_button_menu, 1463 | alignment="center", vertical_alignment = "end"), 1464 | height = 100 1465 | ) 1466 | ) 1467 | 1468 | def urls_support(e): 1469 | url = e.control.text 1470 | 1471 | if 'Paypal' in url: 1472 | url = 'https://paypal.me/davidsulbaran' 1473 | elif 'GitHub' in url: 1474 | url = 'https://github.com/sulasoft' 1475 | elif 'sulasoft' in url: 1476 | url = 'https://sulasoft.com' 1477 | elif 'Telegram' in url: 1478 | url = 'https://t.me/+xzxygFLwEmI1NzVh' 1479 | else: 1480 | url = 'https://www.linkedin.com/in/david-sulbarán-azócar-180768244/' 1481 | 1482 | webbrowser.open(url) 1483 | 1484 | def page_support(e): 1485 | page.clean() 1486 | title_support = Text( 1487 | value="Support", 1488 | size=20, 1489 | color="white", 1490 | weight="bold", 1491 | italic=True, 1492 | ) 1493 | verify_status_support = pd.read_excel('data/support_dev.xlsx', header = 0) 1494 | sup_dev = verify_status_support['sup_dev'].values 1495 | 1496 | if sup_dev[0] == 'yes': 1497 | switch_supp_dev.value = True 1498 | switch_supp_dev.label = 'Supporting Development On 😊' 1499 | elif sup_dev[0] == 'no': 1500 | switch_supp_dev.value = False 1501 | switch_supp_dev.label = 'Supporting Development Off 😢' 1502 | else: 1503 | support_data = {} 1504 | support_data['sup_tag'] = ['dsuaz'] 1505 | support_data['sup_dev'] = ['yes'] 1506 | update_status_support = pd.DataFrame(support_data, columns = ['sup_tag', 'sup_dev']) 1507 | switch_supp_dev.value = True 1508 | switch_supp_dev.label = 'Supporting Development On 😊' 1509 | 1510 | with ExcelWriter('data/support_dev.xlsx') as writer: 1511 | update_status_support.to_excel(writer, 'Sheet', index=False) 1512 | 1513 | page.add( 1514 | ft.Container(height = 50, content= title_support, alignment=ft.alignment.center), 1515 | ft.Divider(height=1, color="black"), 1516 | ft.Container(width=650, height = 449, content= ft.Column(alignment="center", controls=[ 1517 | ft.Row(controls=[ 1518 | ft.Text(value= "You can support the development by sharing a link to the developer's affiliate tag.") 1519 | ], alignment="center", vertical_alignment = "center"), 1520 | ft.Row(controls=[ 1521 | switch_supp_dev, button_info_supp 1522 | ], alignment="center", vertical_alignment = "center"), 1523 | ft.Divider(height=60, color="transparent"), 1524 | ft.Row(controls=[ 1525 | ft.Text(value="You can also contribute monetarily \n I would be very grateful ❤️", text_align ='center') 1526 | ], alignment="center", vertical_alignment = "center"), 1527 | ft.Row(controls=[ 1528 | ft.Text(value = "USDT \n Address", text_align ='center', size = 12, weight='bold'), 1529 | usdt_address, 1530 | ft.Text(value = "Tron (TRC20) \n Network", size = 10) 1531 | ], alignment="center", vertical_alignment = "center"), 1532 | ft.Row(controls=[ 1533 | paypal_button 1534 | ], alignment="center", vertical_alignment = "center"), 1535 | ft.Divider(height=60, color="transparent"), 1536 | ft.Row(controls=[ 1537 | ft.Text(value="My contact networks", text_align ='center') 1538 | ], alignment="center", vertical_alignment = "center"), 1539 | ft.Row(controls=[ 1540 | github_button, linkedin_button, sulasoftcom_button, telegram_channel_button 1541 | ], alignment="center", vertical_alignment = "center"), 1542 | ft.Row(controls=[ 1543 | ft.Text(value="Thank you! 😊", text_align ='center') 1544 | ], alignment="center", vertical_alignment = "center")]) 1545 | ), 1546 | ft.Container(content= ft.Row(controls=list_all_button_menu, 1547 | alignment="center", vertical_alignment = "end"), 1548 | height = 100 1549 | ) 1550 | ) 1551 | 1552 | switch_quick_search = ft.Switch(label = 'Quick search', value=True) 1553 | search_form = TextField(label="Search...", width=400, height = 50, on_submit=search_products, text_align="start", keyboard_type = "text", text_size=12, content_padding = 10) 1554 | select_region = ft.RadioGroup(content=ft.Row(alignment="center", controls=[ 1555 | ft.Text("Amazon "), 1556 | ft.Radio(value=".com", label=".com"), 1557 | ft.Radio(value=".es", label=".es"), 1558 | ft.Radio(value=".it", label=".it"), 1559 | ft.Radio(value=".in", label=".in")]), value = ".com") 1560 | 1561 | minutes_publish = TextField(value='0', label = 'Minutes', text_align="start", keyboard_type = "text", width=70, height = 50, text_size=12, content_padding = 10) 1562 | press_button_publish_on_stop = ft.ElevatedButton("Stop", icon="stop_circle_rounded", on_click=stop_publish_on) 1563 | press_button_search_stop = ft.ElevatedButton("Stop", icon="stop_circle_rounded", on_click=stop_search_product) 1564 | 1565 | # To know if a product has been selected or not 1566 | check_status = False 1567 | 1568 | # Menu 1569 | press_button_main = IconButton(on_click=page_main, icon="home_rounded", tooltip= 'Home') 1570 | press_button_list_result = IconButton(on_click=page_search_result, icon="format_list_numbered_rounded", tooltip= 'Search Result') 1571 | press_button_list_publish = IconButton(on_click=page_publish, icon="checklist_rounded", tooltip= 'Products to Publish') 1572 | press_button_history = IconButton(on_click=page_history, icon="history_rounded", tooltip= 'History') 1573 | press_button_setting = IconButton(on_click=page_settings, icon="settings_rounded", tooltip= 'Settings') 1574 | press_button_info = IconButton(on_click=page_support, icon="info_rounded", tooltip= "Support") 1575 | list_all_button_menu = [press_button_main, press_button_list_result, press_button_list_publish, press_button_history, press_button_setting, press_button_info] 1576 | 1577 | # Settings form 1578 | form_amazon_id = TextField(label="Amazon ID", text_align="center", on_blur=change_amazon_id, width=400, height = 45, text_size=13) 1579 | form_telegram_token = TextField(label="Telegram Token", text_align="center", on_blur=change_telegram_token, width=400, height = 45, text_size=13) 1580 | form_chat_id = TextField(label="Chat ID Example: yourchatid", text_align="center", on_blur=change_chat_id, width=400, height = 45, text_size=13) 1581 | 1582 | # For modify message displayed in Telegram 1583 | switch_tinyurl_short_url = ft.Switch(label= 'Tinyurl', on_change=select_short_url) 1584 | switch_isgd_short_url = ft.Switch(label= 'Is.gd',on_change=select_short_url) 1585 | switch_dagd_short_url = ft.Switch(label= 'Da.gd',on_change=select_short_url) 1586 | button_select_short_url = ft.ElevatedButton("Modify Short URL", icon="edit_rounded", on_click=page_short_url) 1587 | press_button_custom_message = ft.ElevatedButton("Modify publication message", icon="edit_rounded", on_click=custom_message) 1588 | form_before_title_message = TextField(label="Before Title Message", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13) 1589 | form_sale_price_message = TextField(label="Sale Price Message", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13) 1590 | form_original_price_message = TextField(label="Original Price Message", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13) 1591 | form_currency_message = TextField(label="Currency ($, €)", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13) 1592 | form_url_message = TextField(label="URL Message", text_align="center", on_blur=change_custom_message, width=400, height = 45, text_size=13) 1593 | 1594 | 1595 | # To support or not to support development 1596 | usdt_address = ft.TextField(value='TJajbMu8Q1xPG38VzGHQTKT4Wo2T3x4nUR', read_only = True, text_align="start", keyboard_type = "text", width=300, height = 50, text_size=12, content_padding = 10) 1597 | switch_supp_dev = ft.Switch(on_change=support_development) 1598 | paypal_button = ft.ElevatedButton(text= "Paypal", icon = 'paypal',on_click=urls_support) 1599 | github_button = ft.TextButton(text = "GitHub", on_click=urls_support) 1600 | sulasoftcom_button = ft.TextButton(text = "sulasoft.com", on_click=urls_support) 1601 | linkedin_button = ft.TextButton(text = "Linkedin", on_click=urls_support) 1602 | telegram_channel_button = ft.TextButton(text = "Telegram", icon = 'telegram', on_click=urls_support) 1603 | button_info_supp = ft.IconButton(icon="info_rounded", tooltip= "1 out of 6 published products contains the developer's amazon affiliates tag.") 1604 | 1605 | # Switch to view or not the products with price 0 1606 | switch_show_price_0 = ft.Switch(on_change=page_search_result, value=True) 1607 | 1608 | 1609 | page.add( 1610 | ft.Row(page_main(0)) 1611 | ) 1612 | 1613 | main_interface() 1614 | 1615 | ft.app(target=main) 1616 | -------------------------------------------------------------------------------- /publish.py: -------------------------------------------------------------------------------- 1 | import time 2 | from time import sleep 3 | import requests 4 | from threading import Thread 5 | import threading 6 | from bs4 import BeautifulSoup 7 | from pyshorteners import Shortener 8 | import pandas as pd 9 | from pandas import ExcelWriter 10 | from datetime import datetime 11 | 12 | 13 | def enable(e): 14 | status_script = e 15 | if status_script: 16 | # To keep the program active waiting for requests. 17 | status_publish = True 18 | 19 | count_products = 0 20 | 21 | # To know if URL shorteners will be used or not. 22 | verify_short_url = pd.read_excel('data/short_url.xlsx', header = 0) 23 | url_short = verify_short_url['short_url'].values 24 | sleep(1) 25 | 26 | # To verify program development support data. 27 | verify_support_dev = pd.read_excel('data/support_dev.xlsx', header = 0) 28 | sup_tag = verify_support_dev['sup_tag'].values 29 | sup_dev = verify_support_dev['sup_dev'].values 30 | 31 | sup_tag = sup_tag[0] 32 | sup_dev = sup_dev[0] 33 | 34 | while status_publish: 35 | try: 36 | # It is confirmed that there are products added to be published. 37 | verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0) 38 | 39 | 40 | if len(verify_publish) > 0: 41 | title_publish = verify_publish['title'].values 42 | price_publish = verify_publish['price'].values 43 | url_publish = verify_publish['url'].values 44 | min_publish = verify_publish['min'].values 45 | telegram_publish = verify_publish['telegram'].values 46 | 47 | # To get the configuration data, such as Telegram Token and Chat ID. 48 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0) 49 | telegram_token = verify_setting['telegram_token'].values 50 | chat_id = verify_setting['chat_id'].values 51 | 52 | # To obtain the data stored with the custom message for the publications. 53 | verify_custom_message = pd.read_excel('data/custom_message.xlsx', header = 0) 54 | before_title_message = verify_custom_message['before_title'].values 55 | original_price_message = verify_custom_message['original_price'].values 56 | sale_price_message = verify_custom_message['sale_price'].values 57 | currency_message = verify_custom_message['currency'].values 58 | url_message = verify_custom_message['url'].values 59 | 60 | for i in range(len(verify_publish)): 61 | sleep(2) 62 | # Check again that there are products to be published. 63 | new_verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0) 64 | 65 | if len(new_verify_publish) > 0: 66 | 67 | new_url_publish = url_publish[i] 68 | 69 | # When the published products counter reaches 3, a product will be published with the developer's affiliate tag. 70 | # This will only happen if the user has the option activated to support the development of the program. 71 | if count_products == 5 and 'yes' in sup_dev: 72 | headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 'referer': f'https://google.com',} 73 | 74 | try: 75 | req = requests.get(url_publish[i], headers=headers, timeout=10) 76 | 77 | soup = BeautifulSoup(req.text, "html.parser") 78 | 79 | product_link = soup.find('link', rel='canonical').get('href') + '/&tag=' + sup_tag 80 | 81 | except: 82 | 83 | req = requests.get(url_publish[i], headers=headers, timeout=10) 84 | 85 | soup = BeautifulSoup(req.text, "html.parser") 86 | 87 | product_link = soup.find('link', rel='canonical').get('href') + '/&tag=' + sup_tag 88 | 89 | try: 90 | new_url_publish = Shortener().tinyurl.short(product_link) 91 | except: 92 | sleep(3) 93 | new_url_publish = Shortener().tinyurl.short(product_link) 94 | pass 95 | 96 | print('Thank you! 😊') 97 | count_products = 0 98 | else: 99 | count_products += 1 100 | 101 | 102 | # To verify if any url shortener will be used. 103 | try: 104 | if url_short[0] == 'tinyurl': 105 | new_url_publish = Shortener().tinyurl.short(new_url_publish) 106 | elif url_short[0] == 'isgd': 107 | new_url_publish = Shortener().isgd.short(new_url_publish) 108 | elif url_short[0] == 'dagd': 109 | new_url_publish = Shortener().dagd.short(new_url_publish) 110 | else: 111 | pass 112 | except: 113 | sleep(3) 114 | if url_short[0] == 'tinyurl': 115 | new_url_publish = Shortener().tinyurl.short(new_url_publish) 116 | elif url_short[0] == 'isgd': 117 | new_url_publish = Shortener().isgd.short(new_url_publish) 118 | elif url_short[0] == 'dagd': 119 | new_url_publish = Shortener().dagd.short(new_url_publish) 120 | else: 121 | pass 122 | 123 | # It will publish on Telegram the products that were selected to be published. 124 | if 'yes' in telegram_publish[i]: 125 | try: 126 | requests.post('https://api.telegram.org/bot' + telegram_token[0] + "/sendMessage", 127 | data = {'chat_id' : f'@{chat_id[0]}', 128 | 'text': 129 | before_title_message[0] + ' ' + title_publish[i] + '\n \n' + sale_price_message[0] + ' ' + str(price_publish[i]) + ' ' + currency_message[0] + '\n' + original_price_message[0] + ' ' + str(round(price_publish[i] + (price_publish[i]*30/100 ), 2)) + ' ' + currency_message[0] + '\n' + url_message[0] + ' ' + new_url_publish 130 | }) 131 | except: 132 | sleep(10) 133 | requests.post('https://api.telegram.org/bot' + telegram_token[0] + "/sendMessage", 134 | data = {'chat_id' : f'@{chat_id[0]}', 135 | 'text': 136 | before_title_message[0] + ' ' + title_publish[i] + '\n \n' + sale_price_message[0] + ' ' + str(price_publish[i]) + ' ' + currency_message[0] + '\n' + original_price_message[0] + ' ' + str(round(price_publish[i] + (price_publish[i]*30/100 ), 2)) + ' ' + currency_message[0] + '\n' + url_message[0] + ' ' + new_url_publish 137 | }) 138 | 139 | 140 | # It will save the current date. 141 | date_publish = datetime.now() 142 | 143 | try: 144 | # To remove the published product from the list of requests. 145 | verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0) 146 | verify_publish = verify_publish.drop(0) 147 | update_publish_data = pd.DataFrame(verify_publish, columns = ['title', 'price', 'url', 'min', 'telegram']) 148 | 149 | with ExcelWriter('data/publish_on.xlsx') as writer: 150 | update_publish_data.to_excel(writer, 'Sheet', index=False) 151 | except: 152 | try: 153 | sleep(3) 154 | # To remove the published product from the list of requests. 155 | verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0) 156 | verify_publish = verify_publish.drop(0) 157 | update_publish_data = pd.DataFrame(verify_publish, columns = ['title', 'price', 'url', 'min', 'telegram']) 158 | 159 | with ExcelWriter('data/publish_on.xlsx') as writer: 160 | update_publish_data.to_excel(writer, 'Sheet', index=False) 161 | except: 162 | update_publish_data = pd.DataFrame(columns = ['title', 'price', 'url', 'min', 'telegram']) 163 | 164 | with ExcelWriter('data/publish_on.xlsx') as writer: 165 | update_publish_data.to_excel(writer, 'Sheet', index=False) 166 | 167 | # To check the list of products to be published 168 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 169 | title_publish = verify_list_publish['title'].values 170 | price_publish = verify_list_publish['price'].values 171 | url_publish = verify_list_publish['url'].values 172 | 173 | # They will be used to save the data stored in list_publish.xlsx and add them to publish_on.xlsx 174 | # (this file stores the products that will be published). 175 | title_publish_on = [] 176 | price_publish_on = [] 177 | url_publish_on = [] 178 | minutes_publish_on = [] 179 | telegram_publish_on = [] 180 | 181 | for i in range(len(verify_list_publish)): 182 | title_publish_on.append(title_publish[i]) 183 | price_publish_on.append(price_publish[i]) 184 | url_publish_on.append(url_publish[i]) 185 | minutes_publish_on.append(min_publish[i]) 186 | telegram_publish_on.append('yes') 187 | 188 | 189 | add_history = {'title': title_publish_on, 'price': price_publish_on, 'url': url_publish_on, 'min': minutes_publish_on,'telegram':telegram_publish_on} 190 | 191 | update_publish_on = pd.DataFrame(add_history, columns = ['title', 'price', 'url', 'min', 'telegram']) 192 | 193 | with ExcelWriter('data/publish_on.xlsx') as writer: 194 | update_publish_on.to_excel(writer, 'Sheet', index=False) 195 | 196 | # To remove the published product from the list of requests. 197 | verify_publish = pd.read_excel('data/publish_on.xlsx', header = 0) 198 | verify_publish = verify_publish.drop(0) 199 | 200 | # To remove the published product from the list of products to be published. 201 | try: 202 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 203 | verify_list_publish = verify_list_publish.drop(0) 204 | update_list_publish_data = pd.DataFrame(verify_list_publish, columns = ['title', 'price', 'currency', 'url']) 205 | 206 | with ExcelWriter('data/list_publish.xlsx') as writer: 207 | update_list_publish_data.to_excel(writer, 'Sheet', index=False) 208 | except: 209 | try: 210 | sleep(3) 211 | verify_list_publish = pd.read_excel('data/list_publish.xlsx', header = 0) 212 | verify_list_publish = verify_list_publish.drop(0) 213 | update_list_publish_data = pd.DataFrame(verify_list_publish, columns = ['title', 'price', 'currency', 'url']) 214 | 215 | with ExcelWriter('data/list_publish.xlsx') as writer: 216 | update_list_publish_data.to_excel(writer, 'Sheet', index=False) 217 | except: 218 | update_list_publish_data = pd.DataFrame(columns = ['title', 'price', 'currency', 'url']) 219 | with ExcelWriter('data/list_publish.xlsx') as writer: 220 | update_list_publish_data.to_excel(writer, 'Sheet', index=False) 221 | 222 | # To add the published product to the history. 223 | try: 224 | verify_history = pd.read_excel('data/history.xlsx', header = 0) 225 | add_history = {'date': date_publish.today(), 'title': title_publish[i], 'price': price_publish[i], 'url': url_publish[i], 'platform': 'Telegram'} 226 | add_history = pd.DataFrame(add_history, index=[0]) 227 | 228 | verify_history = pd.concat([verify_history, add_history], axis=0) 229 | update_history_data = pd.DataFrame(verify_history, columns = ['date', 'title', 'price', 'url', 'platform']) 230 | 231 | with ExcelWriter('data/history.xlsx') as writer: 232 | update_history_data.to_excel(writer, 'Sheet', index=False) 233 | except: 234 | try: 235 | sleep(3) 236 | verify_history = pd.read_excel('data/history.xlsx', header = 0) 237 | add_history = {'date': date_publish.today(), 'title': title_publish[i], 'price': price_publish[i], 'url': url_publish[i], 'platform': 'Telegram'} 238 | add_history = pd.DataFrame(add_history, index=[0]) 239 | 240 | verify_history = pd.concat([verify_history, add_history], axis=0) 241 | update_history_data = pd.DataFrame(verify_history, columns = ['date', 'title', 'price', 'url', 'platform']) 242 | 243 | with ExcelWriter('data/history.xlsx') as writer: 244 | update_history_data.to_excel(writer, 'Sheet', index=False) 245 | 246 | except: 247 | update_history_data = pd.DataFrame(columns = ['date', 'title', 'price', 'url', 'platform']) 248 | 249 | with ExcelWriter('data/history.xlsx') as writer: 250 | update_history_data.to_excel(writer, 'Sheet', index=False) 251 | 252 | sleep(float(min_publish[i])*60) 253 | 254 | else: 255 | break 256 | 257 | else: 258 | # If there are no requests, it will wait for a new one. 259 | print('Waiting for publish...') 260 | sleep(1) 261 | status_script = False 262 | 263 | 264 | except Exception as e: 265 | print('Error ' + str(e)) 266 | 267 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.11.1 2 | flet==0.3.2 3 | pandas==1.5.2 4 | pyshorteners==1.0.1 5 | requests==2.28.1 6 | openpyxl==3.0.10 -------------------------------------------------------------------------------- /search_products.py: -------------------------------------------------------------------------------- 1 | import time 2 | from time import sleep 3 | import requests 4 | from threading import Thread 5 | import threading 6 | from bs4 import BeautifulSoup 7 | from pyshorteners import Shortener 8 | import pandas as pd 9 | from pandas import ExcelWriter 10 | import re 11 | 12 | 13 | def enable(e): 14 | status_script = e 15 | if status_script: 16 | status_search = True 17 | status_settings = True 18 | # To verify that the user has already added their publishing data: amazon id, telegram token and chat id. 19 | # If he has not added them, it will not perform the search and will show error. 20 | while status_settings: 21 | verify_setting = pd.read_excel('data/setting.xlsx', header = 0) 22 | setting_amazon_id = verify_setting['amazon_id'].values 23 | setting_telegram_token = verify_setting['telegram_token'].values 24 | setting_chat_id = verify_setting['chat_id'].values 25 | 26 | if len(setting_amazon_id) == 1 and len(setting_telegram_token) == 1 and len(setting_chat_id) == 1: 27 | amazon_id = setting_amazon_id[0] 28 | telegram_token = setting_telegram_token[0] 29 | chatid = setting_chat_id[0] 30 | status_settings = False 31 | else: 32 | print('Add your Amazon ID, Telegram Token and Chat ID in the Settings tab.') 33 | sleep(2) 34 | 35 | 36 | # So that the program is always active waiting for requests to perform searches. 37 | while status_search: 38 | 39 | verify_search_product = pd.read_excel('data/search_product.xlsx', header = 0) 40 | 41 | title_product = verify_search_product['title'].values 42 | region_product = verify_search_product['region'].values 43 | publish_product = verify_search_product['pub'].values 44 | quick_search = verify_search_product['quick'].values 45 | 46 | if len(verify_search_product) > 0 and not pd.isnull(title_product[0]): 47 | 48 | keyword = title_product[0] 49 | region = region_product[0] 50 | 51 | headers = [] 52 | headers.append({'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 'referer': f'https://google{region}',}) 53 | headers.append({'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 'referer':f'https://google{region}',}) 54 | 55 | headers = headers[1] 56 | 57 | if region == '.com': 58 | currency = 'USD' 59 | elif region =='.in': 60 | currency = 'Rs' 61 | else: 62 | currency = 'EUR' 63 | 64 | # When the person enters the specific URL of a product, the program will scrape that web page. 65 | if keyword.startswith("http"): 66 | 67 | print(f'Searching...{keyword}') 68 | 69 | try: 70 | # Lists that will store the data obtained from the entered URL. 71 | new_title_result = [] 72 | new_price_result = [] 73 | new_currency_result = [] 74 | new_check_result = [] 75 | new_url_result = [] 76 | 77 | url = keyword 78 | 79 | req = requests.get(url, headers=headers, timeout=10) 80 | 81 | soup = BeautifulSoup(req.text, "html.parser") 82 | 83 | product_title = soup.find('span', id="productTitle").text.strip() 84 | 85 | product_price = 0 86 | 87 | # The price of the product is searched for in different classes, if not found 88 | # the price of the product is set to 0. 89 | for k in range(0, 5): 90 | if headers != headers[1]: 91 | headers = headers[0] 92 | else: 93 | headers = headers[1] 94 | try: 95 | req = requests.get(url, headers=headers, timeout=10) 96 | sleep(3) 97 | soup = BeautifulSoup(req.text, "html.parser") 98 | 99 | try: 100 | product_stock = soup.find_all('span', class_="a-size-medium a-color-price") 101 | if len(product_stock) != 0: 102 | for n in product_stock: 103 | stock = n.text.strip() 104 | if 'out of stock' in stock: 105 | product_stock = 'no' 106 | break 107 | elif 'agotado' in stock: 108 | product_stock = 'no' 109 | break 110 | elif 'indisponível' in stock: 111 | product_stock = 'no' 112 | break 113 | elif 'No disponible' in stock: 114 | product_stock = 'no' 115 | break 116 | elif 'Non disponibile' in stock: 117 | product_stock = 'no' 118 | break 119 | elif 'unavailable' in stock: 120 | product_stock = 'no' 121 | else: 122 | pass 123 | except: 124 | pass 125 | 126 | if product_stock == 'no': 127 | break 128 | 129 | 130 | product_price = soup.find_all('span', class_="a-price a-text-price a-size-medium apexPriceToPay") 131 | print(product_price) 132 | if len(product_price) == 0: 133 | product_price = soup.find_all(class_="olpWrapper a-size-small") 134 | if len(product_price) == 0: 135 | product_price = soup.find_all('span', id="color_name_0_price") 136 | 137 | if len(product_price) == 0: 138 | product_price = soup.find_all('span', class_="a-size-base a-color-price") 139 | 140 | if len(product_price) == 0 or len(product_price) >= 2: 141 | 142 | try: 143 | product_price = soup.find('span', class_="a-offscreen").text.strip() 144 | except: 145 | product_price = '0' 146 | else: 147 | product_price = soup.find('span', class_="a-size-base a-color-price").text.strip() 148 | print(product_price) 149 | if len(product_price) > 6: 150 | product_price = '0' 151 | else: 152 | break 153 | else: 154 | product_price = soup.find('span', id="color_name_0_price").text.strip() 155 | # Method used to clean some data including price and other characters. 156 | all_price = '' 157 | for i in product_price: 158 | if '$' in all_price: 159 | all_price = '' 160 | all_price = f'{i}' 161 | 162 | else: 163 | all_price = f'{all_price}{i}' 164 | product_price = all_price 165 | break 166 | else: 167 | product_price = soup.find_all('span', class_="olpWrapper a-size-small") 168 | for i in product_price: 169 | product_price = i.text.strip() 170 | break 171 | all_price = '' 172 | for i in product_price: 173 | if '$' in all_price: 174 | all_price = '' 175 | all_price = f'{i}' 176 | 177 | else: 178 | all_price = f'{all_price}{i}' 179 | product_price = all_price 180 | break 181 | 182 | else: 183 | product_price = soup.find_all('span', class_="a-price a-text-price a-size-medium apexPriceToPay") 184 | for i in product_price: 185 | product_price = i.find('span', class_="a-offscreen").text.strip() 186 | break 187 | 188 | break 189 | 190 | 191 | except Exception as e: 192 | print(str(e)) 193 | product_price = "0" 194 | pass 195 | 196 | 197 | if product_stock == 'no': 198 | pass 199 | else: 200 | # Sometimes the program does not get the price, so it assigns these values. 201 | # If this is the case, then the value of the variable "product_price" is changed to 0. 202 | try: 203 | 204 | if product_price == '': 205 | product_price = '0' 206 | elif 'US$' in product_price: 207 | new_currency_result.append('USD') 208 | product_price = product_price.replace('US$', '') 209 | elif '$' in product_price: 210 | new_currency_result.append('USD') 211 | product_price = product_price.replace('$', '') 212 | elif '€' in product_price: 213 | new_currency_result.append('EUR') 214 | product_price = product_price.replace('€', '') 215 | else: 216 | check_price = float(product_price) 217 | 218 | if len(new_currency_result) == 0: 219 | if '.com' in keyword: 220 | new_currency_result.append('USD') 221 | elif '.in' in keyword: 222 | new_currency_result.append('Rs') 223 | else: 224 | new_currency_result.append('EUR') 225 | except Exception as e: 226 | print(str(e)) 227 | product_price = '0' 228 | pass 229 | # These methods are used to clean the data obtained. 230 | # To remove currency symbols and change commas to dots. 231 | if product_price != 0 and ',' in product_price or product_price != '0' and ',' in product_price: 232 | product_price = product_price.replace(',' , '.') 233 | 234 | product_price = float(product_price) 235 | 236 | # The original link is modified by adding the amazon affiliates tag. 237 | product_link = f'{keyword}&tag={amazon_id}' 238 | 239 | new_title_result.append(product_title) 240 | new_price_result.append(product_price) 241 | new_check_result.append('no') 242 | new_url_result.append(product_link) 243 | 244 | search_result_data = {} 245 | 246 | search_result_data['title'] = new_title_result 247 | search_result_data['price'] = new_price_result 248 | search_result_data['currency'] = new_currency_result 249 | search_result_data['check'] = new_check_result 250 | search_result_data['url'] = new_url_result 251 | 252 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url']) 253 | 254 | print('Product price: ', product_price) 255 | 256 | with ExcelWriter('data/search_result.xlsx') as writer: 257 | search_result_data.to_excel(writer, 'Sheet', index=False) 258 | 259 | search_product_data = pd.DataFrame(columns = ['title', 'region', 'pub', 'quick']) 260 | 261 | with ExcelWriter('data/search_product.xlsx') as writer: 262 | search_product_data.to_excel(writer, 'Sheet', index=False) 263 | 264 | except Exception as e: 265 | print(str(e)) 266 | 267 | # The products will be searched on Amazon through a keyword entered. 268 | else: 269 | count_product = 0 270 | try: 271 | print(f'Searching... {keyword} on amazon{region}') 272 | 273 | # The Amazon URL is modified with the selected region and the keyword of the product to be searched. 274 | url = f'https://www.amazon{region}/s?k={keyword}' 275 | 276 | req = requests.get(url, headers=headers, timeout=10) 277 | 278 | sleep(3) 279 | 280 | soup = BeautifulSoup(req.text, "html.parser") 281 | 282 | # Search for products through different classes 283 | products_list = soup.find_all('div', class_="s-result-item s-asin sg-col-0-of-12 sg-col-16-of-20 sg-col s-widget-spacing-small sg-col-12-of-16") 284 | 285 | if len(products_list) == 0: 286 | products_list = soup.find_all('div', class_="sg-col-4-of-12 s-result-item s-asin sg-col-4-of-16 sg-col s-widget-spacing-small sg-col-4-of-20") 287 | if len(products_list) == 0: 288 | products_list = soup.find_all(class_='s-card-container s-overflow-hidden aok-relative puis-include-content-margin puis s-latency-cf-section s-card-border') 289 | if len(products_list) == 0: 290 | products_list = soup.find_all(class_='sg-col-4-of-24 sg-col-4-of-12 s-result-item s-asin sg-col-4-of-16 sg-col s-widget-spacing-small sg-col-4-of-20') 291 | 292 | # Lists that will store product data. 293 | titles_products = [] 294 | urls_products = [] 295 | prices_products = [] 296 | currency_products = [] 297 | check_products = [] 298 | 299 | # To select each product that is stored in the list of found products. 300 | for product in products_list: 301 | 302 | print("--------------------------------------------------------------") 303 | 304 | product_title = product.find_all('span', class_="a-size-base-plus a-color-base a-text-normal") 305 | 306 | if len(product_title) <= 0: 307 | product_title = product.find_all('h2', class_="a-size-mini a-spacing-none a-color-base s-line-clamp-2") 308 | 309 | if len(product_title) <= 0: 310 | product_title = product.find('span', class_="a-size-base-plus a-color-base a-text-normal").text.strip() 311 | else: 312 | product_title = product.find('h2', class_="a-size-mini a-spacing-none a-color-base s-line-clamp-2").text.strip() 313 | else: 314 | product_title = product.find('span', class_="a-size-base-plus a-color-base a-text-normal").text.strip() 315 | 316 | print(product_title) 317 | 318 | # The link is modified to add the amazon affiliates tag. 319 | product_link = 'https://amazon' + region + product.find('a', class_='a-link-normal s-no-outline').get('href') + '&tag='+ amazon_id 320 | 321 | print('Link: ', product_link) 322 | 323 | product_price = product.find('span', class_="a-price-whole") 324 | 325 | """ 326 | If the product does not show a price, it may be a variable product, 327 | so the product is accessed directly to try to find its price. 328 | """ 329 | if product_price is None and 'no' in quick_search: 330 | 331 | try: 332 | for i in range(0, 3): 333 | if headers != headers[1]: 334 | headers = headers[0] 335 | else: 336 | headers = headers[1] 337 | 338 | new_req = requests.get(product_link, headers=headers, timeout=10) 339 | new_soup = BeautifulSoup(new_req.text, "html.parser") 340 | product_stock = new_soup.find_all('span', class_="a-size-medium a-color-price") 341 | 342 | if len(product_stock) != 0: 343 | for n in product_stock: 344 | stock = n.text.strip() 345 | if 'out of stock' in stock: 346 | product_stock = 'no' 347 | break 348 | elif 'agotado' in stock: 349 | product_stock = 'no' 350 | break 351 | elif 'indisponível' in stock: 352 | product_stock = 'no' 353 | break 354 | elif 'No disponible' in stock: 355 | product_stock = 'no' 356 | break 357 | 358 | elif 'Non disponibile' in stock: 359 | product_stock = 'no' 360 | break 361 | elif 'unavailable' in stock: 362 | product_stock = 'no' 363 | break 364 | else: 365 | pass 366 | 367 | if product_stock == 'no': 368 | break 369 | 370 | product_price = new_soup.find_all('span', class_="a-price a-text-price a-size-medium apexPriceToPay") 371 | if len(product_price) == 0: 372 | product_price = new_soup.find_all(class_="a-button a-button-selected a-button-thumbnail a-button-toggle") 373 | if len(product_price) == 0: 374 | product_price = new_soup.find_all(class_="swatch-list-item-text inline-twister-swatch reduced-text-swatch-width a-declarative desktop-configurator-dim-row-0") 375 | if len(product_price) == 0: 376 | product_price = new_soup.find_all('span', id="color_name_0_price") 377 | if len(product_price) == 0: 378 | product_price = new_soup.find_all('span', class_="a-size-base a-color-price") 379 | if len(product_price) == 0 or len(product_price) >= 2: 380 | product_price = '0' 381 | else: 382 | product_price = new_soup.find('span', class_="a-size-base a-color-price").text.strip() 383 | if len(product_price) > 6: 384 | product_price = '0' 385 | else: 386 | break 387 | else: 388 | product_price = new_soup.find('span', id="color_name_0_price").text.strip() 389 | # Method used to clean some data including price and other characters. 390 | all_price = '' 391 | for i in product_price: 392 | if '$' in all_price: 393 | all_price = '' 394 | all_price = f'{i}' 395 | 396 | else: 397 | all_price = f'{all_price}{i}' 398 | product_price = all_price 399 | break 400 | else: 401 | product_price = new_soup.find_all(class_="swatch-list-item-text inline-twister-swatch reduced-text-swatch-width a-declarative desktop-configurator-dim-row-0") 402 | for i in product_price: 403 | product_price = i.text.strip() 404 | break 405 | all_price = '' 406 | for i in product_price: 407 | if '$' in all_price: 408 | all_price = '' 409 | all_price = f'{i}' 410 | 411 | else: 412 | all_price = f'{all_price}{i}' 413 | product_price = all_price 414 | break 415 | else: 416 | product_price = new_soup.find_all('span', class_="a-button a-button-selected a-button-thumbnail a-button-toggle") 417 | for i in product_price: 418 | product_price = i.text.strip() 419 | break 420 | all_price = '' 421 | for i in product_price: 422 | if '$' in all_price: 423 | all_price = '' 424 | all_price = f'{i}' 425 | 426 | else: 427 | all_price = f'{all_price}{i}' 428 | product_price = all_price 429 | break 430 | else: 431 | product_price = new_soup.find_all('span', class_="a-price a-text-price a-size-medium apexPriceToPay") 432 | for i in product_price: 433 | product_price = i.find('span', class_="a-offscreen").text.strip() 434 | break 435 | break 436 | 437 | if product_stock == 'no': 438 | pass 439 | else: 440 | # Sometimes the program does not get the price, so it assigns these values. 441 | # If this is the case, then the value of the variable "product_price" is changed to 0. 442 | try: 443 | if product_price == '': 444 | product_price = '0' 445 | elif 'US$' in product_price: 446 | product_price = product_price.replace('US$' , '') 447 | elif '$' in product_price: 448 | 449 | product_price = product_price.replace('$' , '') 450 | elif '€' in product_price: 451 | product_price = product_price.replace('€' , '') 452 | else: 453 | check_price = float(product_price) 454 | 455 | except Exception as e: 456 | print(str(e)) 457 | product_price = '0' 458 | 459 | print('Product Price: ' + str(product_price)) 460 | 461 | # These methods are used to clean the data obtained. 462 | # To remove currency symbols and change commas to dots. 463 | if product_price != 0 and ',' in product_price: 464 | product_price = product_price.replace(',' , '.') 465 | 466 | if 'US$' in product_price: 467 | product_price = product_price.replace('US$' , '') 468 | elif '$' in product_price: 469 | product_price = product_price.replace('$' , '') 470 | elif '€' in product_price: 471 | product_price = product_price.replace('€' , '') 472 | else: 473 | pass 474 | 475 | # The data found are added to the lists. 476 | titles_products.append(product_title) 477 | urls_products.append(product_link) 478 | currency_products.append(currency) 479 | check_products.append('no') 480 | prices_products.append(product_price) 481 | 482 | except Exception as e: 483 | print(str(e)) 484 | 485 | try: 486 | product_price = new_soup.find_all('span', class_="olp-message a-color-price") 487 | if len(product_price) == 0: 488 | product_price = new_soup.find_all('span', id="color_name_0_price") 489 | if len(product_price) == 0: 490 | product_price = new_soup.find('span', class_="a-offscreen").text.strip() 491 | else: 492 | product_price = new_soup.find('span', id="color_name_0_price").text.strip() 493 | # Method used to clean some data including price and other characters. 494 | all_price = '' 495 | for i in product_price: 496 | if '$' in all_price: 497 | all_price = '' 498 | all_price = f'{i}' 499 | new_currency_result.append('USD') 500 | else: 501 | all_price = f'{all_price}{i}' 502 | product_price = all_price 503 | else: 504 | product_price = new_soup.find('span', class_="a-size-base a-color-price").text.strip() 505 | 506 | 507 | except Exception as e: 508 | print(str(e)) 509 | product_price = "0" 510 | 511 | # The data found are added to the lists. 512 | titles_products.append(product_title) 513 | urls_products.append(product_link) 514 | currency_products.append(currency) 515 | check_products.append('no') 516 | prices_products.append(product_price) 517 | 518 | 519 | else: 520 | try: 521 | product_price = product.find('span', class_="a-price-whole").text.strip() 522 | 523 | product_price = product_price.replace('.' , '') 524 | product_price = product_price.replace(',' , '.') 525 | product_price = float(product_price) 526 | except Exception as e: 527 | print(str(e)) 528 | product_price = 0 529 | pass 530 | 531 | # The data found are added to the lists. 532 | titles_products.append(product_title) 533 | urls_products.append(product_link) 534 | currency_products.append(currency) 535 | check_products.append('no') 536 | prices_products.append(product_price) 537 | 538 | 539 | # The data is added to the file "search_results.xlsx" which will store the search results. 540 | search_result_data = {} 541 | search_result_data['title'] = titles_products 542 | search_result_data['price'] = prices_products 543 | search_result_data['currency'] = currency_products 544 | search_result_data['check'] = check_products 545 | search_result_data['url'] = urls_products 546 | 547 | search_result_data = pd.DataFrame(search_result_data, columns = ['title', 'price', 'currency', 'check', 'url']) 548 | 549 | with ExcelWriter('data/search_result.xlsx') as writer: 550 | search_result_data.to_excel(writer, 'Sheet', index=False) 551 | 552 | # The data in the file that stores the search requests is deleted so that it does not continue searching. 553 | delete_product_data = pd.DataFrame(columns = ['title', 'region', 'pub', 'quick']) 554 | 555 | with ExcelWriter('data/search_product.xlsx') as writer: 556 | delete_product_data.to_excel(writer, 'Sheet', index=False) 557 | 558 | except Exception as e: 559 | print(str(e)) 560 | 561 | else: 562 | # When there are no requests, the following message will be displayed. 563 | for i in range(3): 564 | sleep(2) 565 | print(f'Waiting for request...{i}') 566 | status_script = False 567 | 568 | 569 | 570 | 571 | --------------------------------------------------------------------------------