I am trying to improve my programming and programming design skills (poor at the moment). I created a small Amazon scraper program. It is a working program. I would be very grateful if you could review my design. What could be improved? Does my class design make sense?
main.py:
if __name__ == "__main__":
from Scraper import Scraper
scraper = Scraper("Schach", 19, 30)
productLinks = scraper.scrapeProductLinks()
for link in productLinks:
try:
product = scraper.scrapeProductDetails(link)
price = product[1]
alternative_price = product[2]
reviews = product[3]
if (price < 20) or (alternative_price < 20) or (reviews) < 30:
continue
scraper.saveProductListToCSV(product)
except Exception as err:
print(err)
Extractor.py:
from lxml import html as xmlhtml
class Extractor:
def __init__(self, html, link=""):
self.html = html
self.link = link
self.xml_tree = xmlhtml.fromstring(html)
def castPrice(self, price):
if not isinstance(price, str):
price = "-1"
return float(price.replace("EUR ", "").replace(",", "."))
def extractTitle(self):
try:
self.title = self.xml_tree.xpath('//*[@id="productTitle"]/text()')[0]
except IndexError:
return "NA"
return self.title
def extractPrice(self):
try:
price = self.xml_tree.xpath('//*[@id="priceblock_ourprice"]/text()')
alternative_price = self.xml_tree.xpath('//*[@id="buyNewSection"]/div/div/div/div[2]/a/div/div[2]/span[1]/span/text()')
if price:
price = price[0]
elif alternative_price:
price = alternative_price[0]
except IndexError:
return "-1"
return self.castPrice(price)
def extractCompetitionPrice(self):
try:
competition_price = self.xml_tree.xpath('//*[@id="olp_feature_div"]/div/span[1]/span/text()')[0]
competition_price = self.castPrice(competition_price)
except IndexError:
return "-1"
return competition_price
def extractReviews(self):
try:
reviews = self.xml_tree.xpath('//*[@id="acrCustomerReviewText"]/text()')[0]
reviews = reviews.replace(" Kundenrezensionen", "")
except IndexError:
return 0
return int(reviews)
def getExtractedProduct(self):
return [self.extractTitle(), self.extractPrice(), self.extractCompetitionPrice(), self.extractReviews(), self.link]
scraper.py:
import requests
from lxml import html as xmlhtml
import csv
from Extractor import Extractor
class Scraper:
def __init__(self, keyword, price_span, min_review):
self.csv_header = "Titel\tPreis\tAnbieter\tBewertungen\tLink\n"
self.startUrl = "http://www.amazon.de/s/field-keywords={0}&page={1}"
self.keyword = keyword
self.price_span = float(price_span)
self.min_review = int(min_review)
self.links_list = list()
def getHtml(self, urlAdress):
r = requests.get(urlAdress)
return r.text
def saveProductListToCSV(self, productList):
with open("amazon.csv", "a", newline='') as f:
writer = csv.writer(f, delimiter="\t", quoting=csv.QUOTE_MINIMAL)
writer.writerow(productList)
def scrapeProductLinks(self):
x = 1
while x < 2:
html = self.getHtml(self.startUrl . format(self.keyword, x))
tree = xmlhtml.fromstring(html)
self.links_list += tree.xpath("//a[@class='a-link-normal s-access-detail-page a-text-normal']/@href")
x += 1
return self.links_list
def scrapeProductDetails(self, url):
extractor = Extractor(self.getHtml(url), url)
return extractor.getExtractedProduct()