Created
April 29, 2020 09:41
-
-
Save virus-warnning/51b96bab3b8a02807c25699b30e5e341 to your computer and use it in GitHub Desktop.
原價屋顯卡報價監測
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import sys | |
import hashlib | |
import time | |
import locale | |
import requests | |
from bs4 import BeautifulSoup | |
class Benchmark(): | |
def __init__(self): | |
self.timings = [ | |
('BEGIN', time.time(), 0, 0) | |
] | |
def doMark(self, name): | |
(_, init_time, _, _) = self.timings[0] | |
(_, prev_time, _, _) = self.timings[-1] | |
curr_time = time.time() | |
step_elapsed = curr_time - prev_time | |
full_elapsed = curr_time - init_time | |
entry = (name, curr_time, step_elapsed, full_elapsed) | |
self.timings.append(entry) | |
def doDone(self, exit): | |
self.doMark('END') | |
print('+-----------------+----------+----------+') | |
print('| {:^15} | {:^8} | {:^8} |'.format('Timing', 'Step', 'Full')) | |
print('+-----------------+----------+----------+') | |
for (timing, _, step_elapsed, full_elapsed) in self.timings: | |
print('| {:15} | {:=8.2f} | {:=8.2f} |'.format(timing, step_elapsed, full_elapsed)) | |
print('+-----------------+----------+----------+') | |
if exit: | |
exit(1) | |
def getSingleton(): | |
if not hasattr(Benchmark, 'singleton'): | |
Benchmark.singleton = Benchmark() | |
return Benchmark.singleton | |
def init(enable=True): | |
Benchmark.staticEnable = enable | |
Benchmark.getSingleton() | |
def mark(name): | |
if not Benchmark.staticEnable: | |
return | |
inst = Benchmark.getSingleton() | |
inst.doMark(name) | |
def done(exit=False): | |
if not Benchmark.staticEnable: | |
return | |
inst = Benchmark.getSingleton() | |
inst.doDone(exit) | |
def md5_hex(data): | |
if isinstance(data, str): | |
data = data.encode('ascii') | |
ho = hashlib.new('md5') | |
ho.update(data) | |
return ho.hexdigest() | |
def load_page(url): | |
cache_dir = os.path.expanduser('~/.sandbox/cache') | |
if not os.path.isdir(cache_dir): | |
os.makedirs(cache_dir) | |
cache_path = '%s/%s.html' % (cache_dir, md5_hex(url)) | |
contents = None | |
if os.path.isfile(cache_path): | |
elapsed = time.time() - os.path.getmtime(cache_path) | |
if elapsed < 3600: | |
with open(cache_path, 'r', encoding='utf-8') as cache_file: | |
contents = cache_file.read() | |
if contents is None: | |
resp = requests.get(url) | |
if resp.status_code != 200: | |
return None | |
contents = resp.text | |
with open(cache_path, 'w', encoding='utf-8') as cache_file: | |
cache_file.write(contents) | |
return contents | |
def list_product(nodes): | |
for node in nodes: | |
item = node.text.strip() | |
print(item) | |
def filter_products(name, price_min, price_max, nodes): | |
products = [] | |
pattern = r'(.*%s[^,]+)[^$]+\$(\d{4,5})↘?\$?(\d{4,5})?' % name | |
for node in nodes: | |
item = node.text.strip() | |
m = re.search(pattern, item) | |
if m is not None: | |
product = m.group(1) | |
if '猛' in product: | |
continue | |
if '五年' not in product: | |
continue | |
price = int(m.group(m.lastindex)) | |
if price_min < price < price_max: | |
products.append((product, price)) | |
products.sort(key=lambda d: d[1]) | |
for (product, price) in products: | |
print(' %d, %s' % (price, product)) | |
def load_price_list(category='gpu'): | |
cat_idx = { | |
'cpu': 4, | |
'ram': 6, | |
'ssd': 7, | |
'gpu': 12 | |
} | |
# soup: | |
# - select 0.26 | |
# - option 1.68 | |
# re: | |
# - select | |
# - option | |
contents = load_page('https://www.coolpc.com.tw/evaluate.php') | |
Benchmark.mark('load_page') | |
target = '#tbdy > tr:nth-child(%d) > td:nth-child(3) > select' % cat_idx[category] | |
soup = BeautifulSoup(contents, 'lxml') | |
nodes = soup.select(target)[0].select('option') | |
Benchmark.mark('select') | |
enabled = [] | |
for node in nodes: | |
if 'disabled' not in node.attrs: | |
enabled.append(node) | |
return enabled | |
def main(): | |
enabled = load_price_list('gpu') | |
print('GTX 1660 SUPER 真香價:') | |
filter_products(r'.+GTX\s?1660(S| SUPER)', 6000, 8000, enabled) | |
print('') | |
print('GTX 1660 TI 真香價:') | |
filter_products(r'.+GTX\s?1660TI', 6000, 9000, enabled) | |
print('') | |
print('RTX 2060 SUPER 真香價:') | |
filter_products(r'.+RTX\s?2060(S| SUPER)', 10000, 14000, enabled) | |
print('') | |
print('RTX 2070 真香價:') | |
filter_products(r'.+RTX\s?2070[^S][^S]', 11000, 16000, enabled) | |
print('') | |
print('RTX 2070 SUPER 真香價:') | |
filter_products(r'.+RTX\s?2070(S| SUPER)', 14000, 20000, enabled) | |
print('') | |
print('RTX 2080 真香價:') | |
filter_products(r'.+RTX\s?2080[^S][^S]', 15000, 25000, enabled) | |
print('') | |
print('RTX 2080 SUPER 真香價:') | |
filter_products(r'.+RTX\s?2080(S| SUPER)', 20000, 30000, enabled) | |
print('') | |
if __name__ == '__main__': | |
Benchmark.init(enable=False) | |
main() | |
Benchmark.done() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment