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 xmlhtmlclass 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 requestsfrom lxml import html as xmlhtmlimport csvfrom Extractor import Extractorclass 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()
Amazon web scraper
python;object oriented;python 3.x;web scraping