Skip to content

Instantly share code, notes, and snippets.

@BMU-Verlag
Created April 21, 2020 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BMU-Verlag/d0bb60c9ef75553873f7f65707cb646d to your computer and use it in GitHub Desktop.
Save BMU-Verlag/d0bb60c9ef75553873f7f65707cb646d to your computer and use it in GitHub Desktop.
import requests
import re
import smtplib
import json
from bs4 import BeautifulSoup
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
}
MAIL_ADDRESS = 'you.mail@gmail.com'
PASSWORD = 'generated_password'
ARTICLE_FILE = 'articles.json'
def read_json():
articles = []
try:
with open(ARTICLE_FILE, 'r') as file:
articles = json.load(file)
except FileNotFoundError as e:
print(ARTICLE_FILE, 'does not exist')
except json.decoder.JSONDecodeError as e:
print('Invalid json file:', e.msg, 'in line', e.lineno)
return articles
def validate_articles(articles):
valid_articles = []
for article in articles:
if ('url' not in article or 'target_price' not in article):
continue
if ('amzn.to' not in article['url'] or type(article['target_price'])
is not float):
continue
valid_articles.append(article)
return valid_articles
def parse_price(price_text):
price_text = price_text.replace('€', '')
price_text = price_text.replace('EUR', '')
price_text = price_text.strip()
price_text = price_text.replace('.', '')
price_text = price_text.replace(',', '.')
return float(price_text)
def get_article_details(article):
url = article['url']
article['price'] = 0.0
article['name'] = ''
if url is not None:
page = requests.get(url, headers=HEADERS)
soup = BeautifulSoup(page.content, 'html5lib')
title_span = soup.find('span', id='productTitle')
if title_span is not None:
article['name'] = title_span.get_text().strip()
price_span = soup.find('span', id='priceblock_dealprice')
if price_span is None:
price_span = soup.find('span', id='priceblock_ourprice')
if price_span is None:
price_span = soup.find('span', class_=a-color-price')
if price_span is not None:
article['price'] = parse_price(price_span.get_text())
return article
def send_email(article_details):
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.ehlo()
server.login(MAIL_ADDRESS, PASSWORD)
subject=f"{article_details['name']} price below {article_details['target_price']} €"
body=f"The article {article_details['name']} is available for {article_details['price']} €. Check it here: {article_details['url']}"
message = f'Subject: {subject}\n\n{body}'
server.sendmail(MAIL_ADDRESS, MAIL_ADDRESS, message.encode('utf8'))
server.quit()
if __name__ == '__main__':
articles = read_json()
valid_articles = validate_articles(articles)
for article in valid_articles:
article_details = get_article_details(article)
if (article_details['price'] is not None and
article_details['price'] <= article['target_price']):
send_email(article_details)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment