├── requirment ├── LICENSE ├── README.md └── main.py /requirment: -------------------------------------------------------------------------------- 1 | asgiref==3.4.1 2 | certifi==2021.10.8 3 | charset-normalizer==2.0.8 4 | colored==1.4.3 5 | Django==3.2.9 6 | django-scheduler==0.9.5 7 | icalendar==4.0.9 8 | idna==3.3 9 | numpy==1.21.4 10 | python-dateutil==2.8.2 11 | pytz==2021.3 12 | requests==2.26.0 13 | six==1.16.0 14 | sqlparse==0.4.2 15 | termcolor==1.1.0 16 | urllib3==1.26.7 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Amirhossein Mohammadi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # snapp_minimizer 2 | پیداکردن کم ترین قیمت اسنپ در حوالی نقطه مبدا و مقصد\ 3 | \ 4 | تا حالا احتمالا همه شما از سرویس‌های درخواست انلاین ماشین استفاده کرده‌اید. سیستم قیمت گذاری این سرویس ‌ها به پارامتر‌هایی مانند ترافیک زمان در‌خواست و مکان درخواست مرتبط است. 5 | در این کد شما با وارد کردن موقعیت جغرافیایی مبذا و مقصد می‌توانید کم‌ترین قیمت در نقاط حوالی مبدا و حوالی مقصد را پیدا کنید. 6 | 7 | حالا توضیح این‌که چطوری استفاده کنیم. شما در قدم اول باید فایل main.py رو دریافت کنید. برای این‌کار هم می‌تونید این فایل رو دانلود کنید و هم clone کنید. راه اسون‌تر برای کسایی که تا حالا با ابزار گیت کار نکردن همون دانلود کردن فایل‌ هست. یا این که می‌تونید کد رو داخل یک فایل کپی کنید. 8 | در مرحله بعدی شما برای اجرای این فایل به مفسر python3 نیاز داریم. این کار خیلی آسونه و می‌تونید از [این‌جا](https://blog.faradars.org/%D9%86%D8%B5%D8%A8-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%D8%AF%D8%B1-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2/) 9 | این مفسر رو نصب کنید. 10 | بعد از نصب python3 شما می‌تونید این برنامه رو اجرا کنید. چطوری؟ یک cmd باز کنید و دستور زیر را اجرا کنید 11 | 12 | ``` 13 | python main.py 14 | ``` 15 | باید ادرس فایل رو به جای main.py بذارید. حالا اگه فایل در پوشه Downloads باشه می‌ذارید C:\Users\user\Downloads\main.py 16 | \ 17 | در گام بعدی شما باید lat , long مبدا و مقصدتون رو بدونید. برای پیدا این مقادری می‌تونید از [اپن استریت](https://www.openstreetmap.org/) 18 | کمک بگیرید. این مقادیر رو بعد از پیدا کردن به جای موارد زیر بگذارید. دقت کنید که بعد از پیدا کردن مبدا و مقصد بر روی نقشه در نقشه به ادرس شما یک عدد نسبت می‌ده که این عدد با ',' از هم جدا شده اند و دو عدد اعشاری هست. عدد اعشاری اول lat و عدد اعشاری دوم long هست 19 | \ 20 | origin_lat , origin_long -> موقعیت جغرافیایی مبدا\ 21 | dest_lat , dest_long -> موقعیت جغرافیایی مقصد\ 22 | \ 23 | برای تغییر محدوده جستجو و مقدار‌ گام‌های جستجو می‌توانید دو متغیر radius و step را تغییر دهید. مقدار این دو متغیر تقریبا بر اساس متر قابل اندازه‌گیری است 24 | \ 25 | نمونه خروجی 26 | ``` 27 | 12:31:05 28 | 12:32:50 200000 29 | origin location 35.7992,51.4075 30 | dest location 35.7114,51.407 31 | max price 285000 32 | ``` 33 | فقط یک نکته! شما باید authorization code مختص به خودتون رو در قسمت header قرار بدید 34 | این کد همان کدی‌است که اسنپ شما را به عنوان مشتری می‌شناسد. برای گرفتن این کد یک بار با مرورگر وارد شوید و از قسمت inspect این کد را کپی کنید 35 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from builtins import min 2 | 3 | import requests 4 | import json 5 | from datetime import date 6 | import time 7 | import numpy as np 8 | from termcolor import colored 9 | 10 | 11 | def request(origin_lat, origin_long, dest_lat, dest_long): 12 | try: 13 | headers = { 14 | 'authority': 'app.snapp.taxi', 15 | 'content-type': 'application/json', 16 | 'x-app-name': 'passenger-pwa', 17 | 'x-app-version': '5.0.1', 18 | 'authorization': 'ENTER YOUR AUTH KEY', 19 | 'locale': 'fa-IR', 20 | 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Mobile Safari/537.36', 21 | 'app-version': 'pwa', 22 | 'accept': '*/*', 23 | 'origin': 'https://app.snapp.taxi', 24 | 'sec-fetch-site': 'same-origin', 25 | 'sec-fetch-mode': 'cors', 26 | 'sec-fetch-dest': 'empty', 27 | 'referer': 'https://app.snapp.taxi/pre-ride?utm_source=website&utm_medium=webapp-button', 28 | 'accept-language': 'en-US,en;q=0.9,fa;q=0.8', 29 | 'cookie': '_ga=GA1.2.630158201.1604921803; _gid=GA1.2.2129247538.1605042565; facb35cfb204e400bdbaa82b44a500a9=9061bb9db340faf4174fe4745d27fc7b; 34b7ed1b00e796d0bcdc387e62021f03=acd89f353aefff86ad7cc9f6453e7a39', 30 | } 31 | 32 | data = '{"origin_lat":' + str(origin_lat) + ',"origin_lng":' + str(origin_long) + ',"destination_lat":' + str( 33 | dest_lat) + ',"destination_lng":' + str( 34 | dest_long) + ',"waiting":null,"tag":0,"round_trip":false,"voucher_code":null}' 35 | 36 | response = requests.post('https://app.snapp.taxi/api/api-base/v2/passenger/price/s/6/0', headers=headers, 37 | data=data) 38 | if response.status_code != 200: 39 | raise ValueError(response.content) 40 | 41 | data = json.loads(response.content) 42 | data = data["data"] 43 | service = data['prices'] 44 | m = int(10000000) 45 | for i in range(len(service) - 2): 46 | final = int(service[i]['final']) 47 | m = int(np.min([m, final])) 48 | return m 49 | 50 | except Exception as e: 51 | print(colored(e, 'red')) 52 | write_in_file('something wrong') 53 | return 0 54 | 55 | 56 | def write_in_file(price): 57 | fi = open("snapp.csv", 'a') 58 | fi.write(str(price) + ' , ' + str(date.today()) + ' , ' + str(time.strftime("%H:%M:%S", time.localtime()))) 59 | fi.write('\n') 60 | fi.close() 61 | 62 | 63 | if __name__ == '__main__': 64 | print(time.strftime("%H:%M:%S", time.localtime())) 65 | res = 100000000 66 | price_list = [] 67 | origin_lat = 35.7992 68 | origin_long = 51.4075 69 | dest_lat = 35.7114 70 | dest_long = 51.407 71 | 72 | step = 100 73 | radius = 500 74 | 75 | res_origin_lat = origin_lat 76 | res_origin_long = origin_long 77 | res_dest_long = dest_long 78 | res_dest_lat = dest_lat 79 | 80 | for a in range(-radius, radius, step): 81 | for b in range(-radius, radius, step): 82 | lat = origin_lat + round(a * .00001, 4) 83 | long = origin_long + round(a * .00001, 4) 84 | price = request(lat, long, dest_lat, dest_long) 85 | res = min(price, res) 86 | if price == res: 87 | res_lat = lat 88 | res_long = long 89 | price_list.append(price) 90 | 91 | for a in range(-radius, radius, step): 92 | for b in range(-radius, radius, step): 93 | lat = dest_lat + round(a * .00001, 4) 94 | long = dest_long + round(a * .00001, 4) 95 | price = request(res_origin_lat, res_origin_long, lat, long) 96 | res = min(price, res) 97 | if price == res: 98 | res_dest_lat = lat 99 | res_dest_long = long 100 | price_list.append(price) 101 | 102 | print(colored(str(time.strftime("%H:%M:%S", time.localtime())), 'yellow'), colored(res, 'green')) 103 | print('origin location \t' + str(res_origin_lat) + ',' + str(res_origin_long)) 104 | print('dest location \t' + str(res_dest_lat) + ',' + str(res_dest_long)) 105 | print('max price \t' + colored(max(price_list), 'red')) 106 | write_in_file(res) 107 | --------------------------------------------------------------------------------