Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
62d1d431b7 | |||
3625f41a8e | |||
e892aa3112 | |||
8d6f933f8e | |||
55be129ccf | |||
6777e1020f | |||
56838aa7eb | |||
4f7b657747 | |||
a8c9ac37b1 | |||
39c84f9e0d |
@ -27,10 +27,7 @@ Przy tworzeniu aplikacji webowej zastosujemy między innymi:
|
|||||||
Użyte technologie w pełni pozwolą zrealizować naszą wizję.
|
Użyte technologie w pełni pozwolą zrealizować naszą wizję.
|
||||||
|
|
||||||
# Zakres funkcjonalności
|
# Zakres funkcjonalności
|
||||||
Przedstawiony prototyp jest prototypem poziomym ponieważ przedstawia główne funkcjonalności, które będzie posiadać aplikacja,
|
|
||||||
tzn. możliwość wpisania danych auta, zdjęć i wygenerowanie raportu.
|
|
||||||
Nie pokazuje wszystkich kroków, które będą wykonywane przy danej funkcjonalności (np. nie pokazuje kroku z wyborem zdjęć),
|
|
||||||
przez co nie jest prototypem pionowym.
|
|
||||||
|
|
||||||
|
|
||||||
# Etap prac
|
# Etap prac
|
||||||
|
43
backend/background_removal.py
Normal file
43
backend/background_removal.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
from rembg import remove
|
||||||
|
import os
|
||||||
|
from PIL import Image
|
||||||
|
import io
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.image as mpimg
|
||||||
|
|
||||||
|
# wskazanie folderów odczytu i zapisu zdjęć
|
||||||
|
src_folder = 'E:\\AUTOwycena\\AUTOpictures\\'
|
||||||
|
dst_folder = 'E:\\AUTOwycena\\AUTOsilhouettes\\'
|
||||||
|
|
||||||
|
# znalezienie plików do modyfikacji
|
||||||
|
files = os.listdir(src_folder)
|
||||||
|
for file in files:
|
||||||
|
# ustalenie nazw oraz rozszerzeń plików
|
||||||
|
file_name, file_extension = os.path.splitext(file)
|
||||||
|
# ustalenie nazwy pliku do modyfikacji
|
||||||
|
file_name_before = src_folder + file
|
||||||
|
with open(file_name_before, 'rb') as i:
|
||||||
|
# ustalenie nazwy pliku po modyfikacji
|
||||||
|
file_name_after = dst_folder + file_name + '_silhouette' + file_extension
|
||||||
|
with open(file_name_after , 'wb') as o:
|
||||||
|
# wczytanie zdjęcia do modyfikacji
|
||||||
|
car_picture = i.read()
|
||||||
|
# usunięcie tła
|
||||||
|
car_silhouette = remove(car_picture)
|
||||||
|
# zpisanie zdjęcia po modyfikacji
|
||||||
|
o.write(car_silhouette)
|
||||||
|
|
||||||
|
|
||||||
|
# odczyt plików
|
||||||
|
car_pictures = os.listdir(src_folder)
|
||||||
|
car_silhouettes = os.listdir(dst_folder)
|
||||||
|
|
||||||
|
for i in range(len(car_pictures)):
|
||||||
|
# odczyt zdjęć
|
||||||
|
img_A = mpimg.imread(src_folder + car_pictures[i])
|
||||||
|
img_B = mpimg.imread(dst_folder + car_silhouettes[i])
|
||||||
|
|
||||||
|
# wydruk zdjęć
|
||||||
|
fig, ax = plt.subplots(1,2)
|
||||||
|
ax[0].imshow(img_A)
|
||||||
|
ax[1].imshow(img_B)
|
119
backend/data_scraping.py
Normal file
119
backend/data_scraping.py
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# IMPORTOWANIE BIBLIOTEK
|
||||||
|
from fileinput import filename
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.chrome.service import Service
|
||||||
|
from selenium.webdriver.common.action_chains import ActionChains
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
|
from selenium.webdriver.common.keys import Keys
|
||||||
|
import urllib.request
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# FUNKCJA ODPOWIADAJĄCA ZA ZAPISYWANIE ZDJĘĆ SAMOCHODÓW
|
||||||
|
def ZAPISYWANIE_ZDJĘĆ(opener, dzisiejszy_folder, miniaturka_link, id_oferty):
|
||||||
|
miniaturka_link = miniaturka_link.replace('/60/', '/800/')
|
||||||
|
for x in range(1, 5): ## zmieniając zasięg można ustawić ilość zdjęć pobieranych dla każdego pojazdu
|
||||||
|
try:
|
||||||
|
opener.retrieve(f'{miniaturka_link[:-5]}{x}.jpg', f'{dzisiejszy_folder}\{id_oferty}_{x}.jpg')
|
||||||
|
except:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
# FUNKCJA ODPOWIADAJĄCA ZA ZAPISYWANIE DANYCH TEKSTOWYCH W PLIKU CSV
|
||||||
|
def ZAPISYWANIE_DANYCH(opener, GŁÓWNY_FOLDER_ZAPISU_DANYCH, dzisiejszy_folder, oferta, dotychczasowe_ids):
|
||||||
|
dane_oferty = oferta.find_elements(By.TAG_NAME, 'td')
|
||||||
|
miniaturka_link = oferta.find_element(By.TAG_NAME, 'a').find_element(By.TAG_NAME, 'img').get_attribute('src')
|
||||||
|
id = oferta.find_element(By.TAG_NAME , "td").find_element(By.TAG_NAME , "a").get_attribute('href').split('/id/')[-1]
|
||||||
|
if int(id) not in dotychczasowe_ids:
|
||||||
|
with open(GŁÓWNY_FOLDER_ZAPISU_DANYCH+'\\IDS.txt', 'a') as f:
|
||||||
|
f.write(str(id)+'\n')
|
||||||
|
marka = oferta.get_attribute('make')
|
||||||
|
model = oferta.get_attribute('model')
|
||||||
|
rodzaj_paliwa = dane_oferty[8].text
|
||||||
|
rok_produkcji = dane_oferty[10].text
|
||||||
|
przebieg = dane_oferty[12].text.replace(' ', '')
|
||||||
|
cena_start_aktualna = ';'.join(dane_oferty[14].text.split('\n')).replace(' ', '')
|
||||||
|
kosztorys_naprawy_ASO = dane_oferty[16].text.replace(' ', '')
|
||||||
|
wycena_przed = dane_oferty[18].text.replace(' ', '')
|
||||||
|
wycena_po = dane_oferty[20].text.replace(' ', '')
|
||||||
|
dane_oferty_razem = [id, marka, model, rodzaj_paliwa, rok_produkcji, przebieg, cena_start_aktualna, kosztorys_naprawy_ASO, wycena_przed, wycena_po]
|
||||||
|
with open(f"{GŁÓWNY_FOLDER_ZAPISU_DANYCH}\{datetime.datetime.now().strftime('%Y-%m-%d')}.csv", 'a', newline='') as file:
|
||||||
|
thewriter = csv.writer(file)
|
||||||
|
thewriter.writerow(dane_oferty_razem)
|
||||||
|
ZAPISYWANIE_ZDJĘĆ(opener, dzisiejszy_folder, miniaturka_link, id)
|
||||||
|
else:
|
||||||
|
print(f' (Dane pojazdu o id={id} zostały już wcześniej pobrane)')
|
||||||
|
|
||||||
|
|
||||||
|
# FUNKCJA ODPOWIADAJĄCA ZA STWORZENIE LISTY WSZYSTKICH DOSTĘPNYCH OFERT DOTYCZĄCYCH SAMOCHODÓW
|
||||||
|
def LISTA_OFERT(driver):
|
||||||
|
dzisiejsze_oferty = driver.find_elements(By.CLASS_NAME, "listCarRow")
|
||||||
|
lista_ofert = []
|
||||||
|
for oferta in dzisiejsze_oferty:
|
||||||
|
lista_ofert.append(oferta)
|
||||||
|
liczba_ofert_dotyczacych_samochodow = int(driver.find_element(By.XPATH, '/html/body/div[2]/div[5]/div[2]/div/div/div[2]/div/div[1]/div[1]/div/span').text[1:-1])
|
||||||
|
return lista_ofert[:liczba_ofert_dotyczacych_samochodow]
|
||||||
|
|
||||||
|
|
||||||
|
# FUNKCJA ODPOWIADAJĄCA ZA PROCES LOGOWANIA
|
||||||
|
def LOGOWANIE(driver):
|
||||||
|
driver.get('https://wrecar.pl/index.php/login')
|
||||||
|
login_box = driver.find_element(By.XPATH, "/html/body/div[2]/div[5]/div[2]/div/div/div/form/center/table/tbody/tr[1]/td[2]/input")
|
||||||
|
password_box = driver.find_element(By.XPATH, "/html/body/div[2]/div[5]/div[2]/div/div/div/form/center/table/tbody/tr[2]/td[2]/input")
|
||||||
|
login_box.send_keys('WrecarDemo1')
|
||||||
|
password_box.send_keys('WrecarDemo2022')
|
||||||
|
password_box.send_keys(Keys.RETURN)
|
||||||
|
|
||||||
|
|
||||||
|
# FUNKCJA ODPOWIADAJĄCA ZA CAŁY PROCES POBIERANIA
|
||||||
|
def POBIERANIE_DANYCH(driver, opener, GŁÓWNY_FOLDER_ZAPISU_DANYCH, dzisiejszy_folder, dotychczasowe_ids):
|
||||||
|
LOGOWANIE(driver)
|
||||||
|
driver.get("https://wrecar.pl/car/auction")
|
||||||
|
lista_ofert = LISTA_OFERT(driver)
|
||||||
|
start = time.time()
|
||||||
|
for num in range(len(lista_ofert)):
|
||||||
|
ZAPISYWANIE_DANYCH(opener, GŁÓWNY_FOLDER_ZAPISU_DANYCH, dzisiejszy_folder, lista_ofert[num], dotychczasowe_ids)
|
||||||
|
# if (num+1) == int(len(lista_ofert))
|
||||||
|
print(f'Pobrano {(num+1)/len(lista_ofert)*100:.2f}% danych!')
|
||||||
|
print(f'Pobieranie zakończone w czasie: {time.strftime("%Mm %Ss", time.gmtime(time.time()-start))}')
|
||||||
|
|
||||||
|
|
||||||
|
# FUNKCJA ZACZYNAJĄCA PROCES POBIERANIA DANYCH
|
||||||
|
def SELENIUM(ŚCIEŻKA_DO_CHROMEDRIVER_EXE, GŁÓWNY_FOLDER_ZAPISU_DANYCH, id_related):
|
||||||
|
opener = urllib.request.URLopener()
|
||||||
|
opener.addheader('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36')
|
||||||
|
options = webdriver.ChromeOptions()
|
||||||
|
options.headless = True ## jeśli linijka jest zakomentowana to widać klienta przegląrki, jeśli NIE jest zakomentowana, to proces wykonuje się w tle
|
||||||
|
options.add_experimental_option('excludeSwitches', ['enable-logging'])
|
||||||
|
options.add_experimental_option("detach", True)
|
||||||
|
driver_service = Service(executable_path=ŚCIEŻKA_DO_CHROMEDRIVER_EXE)
|
||||||
|
driver = webdriver.Chrome(service=driver_service, options=options)
|
||||||
|
POBIERANIE_DANYCH(driver, opener, GŁÓWNY_FOLDER_ZAPISU_DANYCH, id_related[0], id_related[1])
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
# FUNKCJA ODPOWIADAJĄCA ZA SPRAWDZANIE ID SAMOCHODÓW, KTÓRE ZOSTAŁY JUŻ POBRANE (żeby niepotrzebnie nie pobierać tych samych danych)
|
||||||
|
def IDS(GŁÓWNY_FOLDER_ZAPISU_DANYCH):
|
||||||
|
if not os.path.exists(os.path.join(GŁÓWNY_FOLDER_ZAPISU_DANYCH, str(datetime.datetime.now().strftime('%Y-%m-%d')))):
|
||||||
|
dzisiejszy_folder = os.mkdir(os.path.join(GŁÓWNY_FOLDER_ZAPISU_DANYCH, str(datetime.datetime.now().strftime('%Y-%m-%d'))))
|
||||||
|
dzisiejszy_folder = os.path.join(os.path.join(GŁÓWNY_FOLDER_ZAPISU_DANYCH, str(datetime.datetime.now().strftime('%Y-%m-%d'))))
|
||||||
|
if not os.path.exists(GŁÓWNY_FOLDER_ZAPISU_DANYCH+'\\IDS.txt'):
|
||||||
|
with open(GŁÓWNY_FOLDER_ZAPISU_DANYCH+'\\IDS.txt', 'a') as f:
|
||||||
|
f.write('')
|
||||||
|
with open(GŁÓWNY_FOLDER_ZAPISU_DANYCH+'\\IDS.txt') as f:
|
||||||
|
lista_ids = [int(line.strip()) for line in f]
|
||||||
|
return dzisiejszy_folder, lista_ids
|
||||||
|
|
||||||
|
|
||||||
|
ŚCIEŻKA_DO_CHROMEDRIVER_EXE = '' ## np. 'C:\chromedriver.exe'
|
||||||
|
GŁÓWNY_FOLDER_ZAPISU_DANYCH = '' ## np. 'E:\AUTOwycena\PicturesDatabase'
|
||||||
|
|
||||||
|
# ROZPOCZĘCIE PROCESU POBIERANIA DANYCH
|
||||||
|
SELENIUM(ŚCIEŻKA_DO_CHROMEDRIVER_EXE, GŁÓWNY_FOLDER_ZAPISU_DANYCH, IDS(GŁÓWNY_FOLDER_ZAPISU_DANYCH))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user