start page
This commit is contained in:
parent
76495b8b57
commit
3ce9899e82
56
compare.py
56
compare.py
|
@ -7,38 +7,46 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import datetime
|
from datetime import datetime
|
||||||
from tinydb import TinyDB, Query
|
from tinydb import TinyDB, Query
|
||||||
import urllib3
|
import urllib3
|
||||||
import sys
|
import sys
|
||||||
import scrape_listing as sl
|
import scrape_listing as sl
|
||||||
import search_eBay as se
|
import search_eBay as se
|
||||||
|
import export_html as exhtml
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
seller_db = TinyDB("seller_db.json")
|
seller_db = TinyDB("seller_db.json")
|
||||||
database_lenght = len(seller_db.all())
|
database_lenght = len(seller_db.all())
|
||||||
|
comparison_results = list()
|
||||||
if database_lenght == 0:
|
if database_lenght == 0:
|
||||||
print("Unable to load seller shop database!")
|
print("Unable to load seller shop database!")
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
print("Loaded seller shop database: " + str(database_lenght) + " listings")
|
print("Loaded seller shop database: " + str(database_lenght) + " listings")
|
||||||
|
|
||||||
|
compare_start_timestamp = datetime.now() #set start time for comparing
|
||||||
for shop_listing_url in seller_db.all():
|
for shop_listing_url in seller_db.all():
|
||||||
#print(shop_listing_url["epid"])
|
#print(shop_listing_url["epid"])
|
||||||
|
|
||||||
for retrieve_counter in range(5):
|
for retrieve_counter in range(5):
|
||||||
try:
|
try:
|
||||||
shop_listing_data = sl.scrape_listing(shop_listing_url["epid"])
|
seller_listing_data = sl.scrape_listing(shop_listing_url["epid"])
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
#pass
|
#pass
|
||||||
print("Unable to retrieve seller listing data from: " + shop_listing_url["epid"])
|
print("Unable to retrieve seller listing data from: " + shop_listing_url["epid"])
|
||||||
|
|
||||||
if shop_listing_data:
|
if seller_listing_data:
|
||||||
print("\n\nCompare: " + shop_listing_data["title"] + " | " + str(shop_listing_data["price"]) + "€ | " + shop_listing_url["epid"])
|
print("\n\nCompare: " + seller_listing_data["title"] + " | " + str(seller_listing_data["price"]) + "€ | " + shop_listing_url["epid"])
|
||||||
|
|
||||||
competitor_listings = se.search(shop_listing_data["title"], 1)
|
comparison_result = {
|
||||||
print("Found " + str(len(competitor_listings)) + " listings from competitors with term: " + shop_listing_data["title"])
|
'seller_listing': seller_listing_data,
|
||||||
|
'competitor_listings': list(),
|
||||||
|
'max_price_delta': float(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
competitor_listings = se.search(seller_listing_data["title"], 1)
|
||||||
|
print("Found " + str(len(competitor_listings)) + " listings from competitors with term: " + seller_listing_data["title"])
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
cheaper_listings = list()
|
cheaper_listings = list()
|
||||||
for competitor_listing_url in competitor_listings:
|
for competitor_listing_url in competitor_listings:
|
||||||
|
@ -46,7 +54,6 @@ if __name__ == "__main__":
|
||||||
#print(shop_listing_url["epid"])
|
#print(shop_listing_url["epid"])
|
||||||
|
|
||||||
if seller_db.search(Query().epid == competitor_listing_url):
|
if seller_db.search(Query().epid == competitor_listing_url):
|
||||||
#if competitor_listing_url == shop_listing_url["epid"]:
|
|
||||||
print("Found listing from sellers shop --> ignore " + competitor_listing_url)
|
print("Found listing from sellers shop --> ignore " + competitor_listing_url)
|
||||||
continue
|
continue
|
||||||
#else:
|
#else:
|
||||||
|
@ -63,16 +70,41 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
if competitor_listing_data:
|
if competitor_listing_data:
|
||||||
#print(competitor_listing_data["price"])
|
#print(competitor_listing_data["price"])
|
||||||
if competitor_listing_data["price"] < shop_listing_data["price"]:
|
if competitor_listing_data["price"] < seller_listing_data["price"]:
|
||||||
#print("found cheaper competitor: " + str(competitor_listing_data["price"]) + "€ instead: " + str(shop_listing_data["price"]) + "€ ---> " + competitor_listing_url)
|
#print("found cheaper competitor: " + str(competitor_listing_data["price"]) + "€ instead: " + str(seller_listing_data["price"]) + "€ ---> " + competitor_listing_url)
|
||||||
cheaper_listings.append({
|
cheaper_listings.append({
|
||||||
'title': competitor_listing_data["title"],
|
'title': competitor_listing_data["title"],
|
||||||
'price': competitor_listing_data["price"],
|
'price': competitor_listing_data["price"],
|
||||||
|
'image': competitor_listing_data["image"],
|
||||||
'url': competitor_listing_url})
|
'url': competitor_listing_url})
|
||||||
|
|
||||||
for cheaper_listing in sorted(cheaper_listings, key=lambda d: d['price']) :
|
for cheaper_listing in sorted(cheaper_listings, key=lambda d: d['price']) :
|
||||||
#print(cheaper_listing)
|
#print(cheaper_listing)
|
||||||
print("found cheaper competitor: " + str(cheaper_listing["price"]) + "€ instead: " + str(shop_listing_data["price"]) + "€ ---> " + cheaper_listing["url"])
|
print("found cheaper competitor: " + str(cheaper_listing["price"]) + "€ instead: " + str(seller_listing_data["price"]) + "€ ---> " + cheaper_listing["url"])
|
||||||
#break
|
comparison_result['competitor_listings'].append(cheaper_listing)
|
||||||
|
if comparison_result['max_price_delta'] == 0.0:
|
||||||
|
comparison_result['max_price_delta'] = seller_listing_data["price"] - cheaper_listing["price"]
|
||||||
|
|
||||||
|
if cheaper_listings:
|
||||||
|
comparison_results.append(comparison_result)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
now = datetime.now() # current date and time
|
||||||
|
|
||||||
|
exp = exhtml.exporter("./html_out/")
|
||||||
|
|
||||||
|
for comparison in sorted(comparison_results, key=lambda d: d['max_price_delta'], reverse=True):
|
||||||
|
exp.export_comparison(comparison['seller_listing'], comparison['competitor_listings'])
|
||||||
|
|
||||||
|
exp.export_startpage(str(database_lenght), len(comparison), datetime.timestamp(compare_start_timestamp), now.strftime("%m/%d/%Y, %H:%M:%S"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import os
|
import os
|
||||||
import template_html as thtml
|
import template_html as thtml
|
||||||
|
import shutil
|
||||||
|
|
||||||
class exporter:
|
class exporter:
|
||||||
export_dir=""
|
export_dir=""
|
||||||
|
@ -21,27 +22,53 @@ class exporter:
|
||||||
os.mkdir(self.export_dir)
|
os.mkdir(self.export_dir)
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
os.mkdir(os.path.join(self.export_dir,"compare/"))
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.copy_static_export()
|
||||||
|
|
||||||
|
def copy_static_export(self):
|
||||||
|
try:
|
||||||
|
os.mkdir(os.path.join(self.export_dir,"css/"))
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.mkdir(os.path.join(self.export_dir,"data/"))
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
shutil.copy("./html/css/w3.css", os.path.join(self.export_dir,"css/","w3.css"))
|
||||||
|
shutil.copy("./html/data/favicon.ico", os.path.join(self.export_dir,"data/","favicon.ico"))
|
||||||
|
shutil.copy("./html/data/icon.png", os.path.join(self.export_dir,"data/","icon.png"))
|
||||||
|
|
||||||
def export_comparison(self, seller_listing, competitor_listings):
|
def export_comparison(self, seller_listing, competitor_listings):
|
||||||
self.counter +=1
|
self.counter +=1
|
||||||
f = open(os.path.join(self.export_dir, str(self.counter) + ".html"), "a")
|
f = open(os.path.join(self.export_dir, "compare/", str(self.counter) + ".html"), "a")
|
||||||
|
|
||||||
f.write(thtml.html_comparison_head())
|
f.write(thtml.html_comparison_head())
|
||||||
|
f.write("<body>")
|
||||||
|
f.write(thtml.html_comparison_navigation(self.counter))
|
||||||
|
f.write(thtml.html_comparison_seller_listing(seller_listing))
|
||||||
|
f.write(thtml.html_comparison_competitor_list_header())
|
||||||
|
competitor_listing_counter = 0
|
||||||
|
for competitor_listing in competitor_listings:
|
||||||
|
competitor_listing_counter +=1
|
||||||
|
f.write(thtml.html_comparison_competitor_listing(competitor_listing, competitor_listing_counter))
|
||||||
|
f.write(thtml.html_comparison_trailer())
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
def export_startpage(self, seller_listings_count, cheaper_listings_count, compare_time, date):
|
||||||
|
duration_export = datetime.timestamp(self.tsStart)
|
||||||
|
print("Comparison needed: ", duration_export)
|
||||||
|
|
||||||
|
f = open(os.path.join(self.export_dir, "index.html"), "a")
|
||||||
|
f.write(thtml.html_startpage_head())
|
||||||
def export_startpage():
|
f.write(thtml.html_startpage_info(seller_listings_count, cheaper_listings_count, compare_time, duration_export, date))
|
||||||
duration = datetime.timestamp(self.tsStart)
|
f.write(thtml.html_startpage_trailer())
|
||||||
print("Comparison needed: ", duration)
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
seller_listing_dummy = {
|
seller_listing_dummy = {
|
||||||
|
|
|
@ -19,8 +19,21 @@
|
||||||
<body class="w3-animate-zoom">
|
<body class="w3-animate-zoom">
|
||||||
<div class="w3-container w3-content w3-center" style="margin-top:1%">
|
<div class="w3-container w3-content w3-center" style="margin-top:1%">
|
||||||
<h1 class="w3-wide w3-text-white">eBay competitor price compare</h1>
|
<h1 class="w3-wide w3-text-white">eBay competitor price compare</h1>
|
||||||
<div class="w3-panel w3-card-4 w3-white w3-padding">
|
<div class="w3-panel w3-card-4 w3-dark-gray w3-padding">
|
||||||
<iframe src="test_fragment.html" title="W3Schools Free Online Web Tutorials"></iframe>
|
<div class="w3-left-align">
|
||||||
|
<h3>Seller info</h3>
|
||||||
|
<p>Number of seller listings: </p>
|
||||||
|
<p>Possibly cheaper listings: </p>
|
||||||
|
<h3>Runtime info</h3>
|
||||||
|
<p>Compare time needed: </p>
|
||||||
|
<p>Export time needed: </p>
|
||||||
|
<p>Date of creation: </p>
|
||||||
|
</div>
|
||||||
|
<div class="w3-center-align">
|
||||||
|
<form action="https://google.com">
|
||||||
|
<input type="submit" value="Start manual comparing" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w3-container w3-content w3-center" style="max-width:600px;">
|
<div class="w3-container w3-content w3-center" style="max-width:600px;">
|
||||||
|
|
|
@ -34,9 +34,9 @@ def scrape_listing(url):
|
||||||
listing = {
|
listing = {
|
||||||
'title': soup.find("div", class_="vim x-item-title").span.text,
|
'title': soup.find("div", class_="vim x-item-title").span.text,
|
||||||
'price': float(soup.find("span", id="prcIsum")["content"]),
|
'price': float(soup.find("span", id="prcIsum")["content"]),
|
||||||
'image': soup.find("img", id="icImg")["src"]
|
'image': soup.find("img", id="icImg")["src"],
|
||||||
|
'url' : url
|
||||||
}
|
}
|
||||||
|
|
||||||
return listing
|
return listing
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
131
template_html.py
131
template_html.py
|
@ -12,10 +12,10 @@ def html_comparison_head():
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="shortcut icon" href="./data/favicon.ico">
|
<link rel="shortcut icon" href="../data/favicon.ico">
|
||||||
<link rel="icon" sizes="192x192" href="./data/icon.png">
|
<link rel="icon" sizes="192x192" href="../data/icon.png">
|
||||||
<title>eBay competitor price compare</title>
|
<title>eBay competitor price compare</title>
|
||||||
<link rel="stylesheet" href="./css/w3.css">
|
<link rel="stylesheet" href="../css/w3.css">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background-color: #000000;
|
background-color: #000000;
|
||||||
|
@ -58,6 +58,10 @@ def html_comparison_head():
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
img{
|
||||||
|
max-width:600px;
|
||||||
|
max-width:600px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
'''
|
'''
|
||||||
|
@ -66,6 +70,7 @@ def html_comparison_navigation(counter):
|
||||||
|
|
||||||
back_link = str((str(counter-1)+".html") if ((counter-1) > 0) else "#")
|
back_link = str((str(counter-1)+".html") if ((counter-1) > 0) else "#")
|
||||||
current = str(counter)
|
current = str(counter)
|
||||||
|
current_link = str(counter)+".html"
|
||||||
next_link = str((str(counter+1)+".html")) #TODO: test if last one and replace with '#'
|
next_link = str((str(counter+1)+".html")) #TODO: test if last one and replace with '#'
|
||||||
|
|
||||||
return '''
|
return '''
|
||||||
|
@ -76,7 +81,7 @@ def html_comparison_navigation(counter):
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="w3-container w3-dark-gray w3-cell w3-center">
|
<div class="w3-container w3-dark-gray w3-cell w3-center">
|
||||||
<a class="w3-hover" style="text-decoration: none" href="''' + current + '''">
|
<a class="w3-hover" style="text-decoration: none" href="''' + current_link + '''">
|
||||||
<h1>Compare #''' + current + '''</h1>
|
<h1>Compare #''' + current + '''</h1>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -86,4 +91,120 @@ def html_comparison_navigation(counter):
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
def html_comparison_seller_listing(seller_listing):
|
||||||
|
return '''
|
||||||
|
<div>
|
||||||
|
<a class="w3-hover" style="text-decoration: none" href="''' + seller_listing['url'] + '''" target="_blank">
|
||||||
|
<div class="w3-container">
|
||||||
|
<div class="w3-panel w3-green">
|
||||||
|
<div class="w3-container w3-cell">
|
||||||
|
<img src="''' + seller_listing['image'] + '''" class="w3-card-4" alt="image not found" style="float:left">
|
||||||
|
</div>
|
||||||
|
<div class="w3-container w3-cell">
|
||||||
|
<h1 class="w3-monospace w3-xxlarge">''' + seller_listing['title'] + '''</h1>
|
||||||
|
<h2 class="w3-monospace w3-jumbo">''' + str(seller_listing['price']) + ''' €</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def html_comparison_competitor_list_header():
|
||||||
|
return '''
|
||||||
|
<h3 class="w3-text-white">Competitor results:</h3>
|
||||||
|
<div class="holster">
|
||||||
|
<div class="container y mandatory-scroll-snapping" dir="ltr">
|
||||||
|
'''
|
||||||
|
|
||||||
|
def html_comparison_competitor_listing(competitor_listing, competitor_listing_counter):
|
||||||
|
return '''
|
||||||
|
<div class="result_scroll_element w3-text-white">
|
||||||
|
<a class="w3-hover" style="text-decoration: none" href="''' + competitor_listing['url'] + '''" target="_blank">
|
||||||
|
<div class="w3-container">
|
||||||
|
<div class="w3-panel w3-indigo">
|
||||||
|
<h6 class="w3-text-white">#''' + str(competitor_listing_counter) + '''</h6>
|
||||||
|
<div class="w3-container w3-cell">
|
||||||
|
<img src="''' + competitor_listing['image'] + '''" class="w3-card-4" alt="image not found" style="float:left">
|
||||||
|
</div>
|
||||||
|
<div class="w3-container w3-cell">
|
||||||
|
<h1 class="w3-monospace w3-xxlarge">''' + competitor_listing['title'] + '''</h1>
|
||||||
|
<h2 class="w3-monospace w3-jumbo">''' + str(competitor_listing['price']) + ''' €</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def html_comparison_trailer():
|
||||||
|
return '''
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def html_startpage_head():
|
||||||
|
return '''
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="shortcut icon" href="./data/favicon.ico">
|
||||||
|
<link rel="icon" sizes="192x192" href="./data/icon.png">
|
||||||
|
<title>eBay competitor price compare</title>
|
||||||
|
<link rel="stylesheet" href="./css/w3.css">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #000000;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def html_startpage_info(seller_listings_count, cheaper_listings_count, compare_time, export_time, date):
|
||||||
|
|
||||||
|
|
||||||
|
return '''
|
||||||
|
<div class="w3-container w3-content w3-center" style="margin-top:1%">
|
||||||
|
<h1 class="w3-wide w3-text-white">eBay competitor price compare</h1>
|
||||||
|
<div class="w3-panel w3-card-4 w3-dark-gray w3-padding">
|
||||||
|
<div class="w3-left-align">
|
||||||
|
<h3>Seller info</h3>
|
||||||
|
<p>Number of seller listings: ''' + str(seller_listings_count) + '''</p>
|
||||||
|
<p>Possibly cheaper listings: ''' + str(cheaper_listings_count) + '''</p>
|
||||||
|
<h3>Runtime info</h3>
|
||||||
|
<p>Compare time needed: ''' + str(compare_time) + '''</p>
|
||||||
|
<p>Export time needed: ''' + str(export_time) + '''</p>
|
||||||
|
<p>Date of creation: ''' + str(cheaper_listings_count) + '''</p>
|
||||||
|
</div>
|
||||||
|
<div class="w3-center-align">
|
||||||
|
<form action="compare/1.html"+">
|
||||||
|
<input type="submit" value="Start manual comparing" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def html_startpage_trailer():
|
||||||
|
return '''
|
||||||
|
<div class="w3-container w3-content w3-center" style="max-width:600px;">
|
||||||
|
<div class="w3-panel w3-card w3-dark-gray w3-padding">
|
||||||
|
<div class="w3-center-align">
|
||||||
|
<a class="w3-hover" style="text-decoration: none" href="mailto:mail@hendrikschutter.com">
|
||||||
|
<h6>mail@hendrikschutter.com</h6></a>
|
||||||
|
<a class="w3-hover" style="text-decoration: none" href="https://git.mosad.xyz/localhorst/eBayCompetitorPriceCompare">
|
||||||
|
<h6>https://git.mosad.xyz/localhorst/eBayCompetitorPriceCompare</h6></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="w3-container w3-center">Last update: 2022/03/30/<footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue