Home > database >  web scraping amazon reviews precents bs4
web scraping amazon reviews precents bs4

Time:10-10

So I'm Trying To Get The Review Precent Of Each Amount of Stars In an Amazon Product Page. This Is The Output I want To Get:

Awesome Feedback: 72%
Good Feedback: 15%
Regular Feedback: 7%
Bad Feedback: 3%
Awful Feedback: 4%

And So Far This Is The Output I Got:

Awesome Feedback: 72%
Traceback (most recent call last):
  File "c:\Users\Nana\Desktop\stuff\Python\Web Scraping\Amazon Smart 
Buyer\amazonR.py", line 34, in <module>    bot()
  File "c:\Users\Nana\Desktop\stuff\Python\Web Scraping\Amazon Smart 
Buyer\amazonR.py", line 14, in __init__    self.r()
  File "c:\Users\Nana\Desktop\stuff\Python\Web Scraping\Amazon Smart 
Buyer\amazonR.py", line 26, in r       
  print(f'Good Feedback: {self.pd[1]}')
IndexError: list index out of range

As You see, I Have Managed To Get The Awesome Feedback Working But Not The Other Ones... The problem is that I got all the precentages in isolated list and every precntage has his one list. As you see here: ['72%'], ['15%'], ['7%'], ['3%'], ['4%']. I'm quite straggling with it... If there is a way to access all of the indexes of the for loop and merge them all into one list, please share it with me... here is my code:

from bs4 import BeautifulSoup
from selenium import webdriver




class bot:
    def __init__(self):
        self.path = 'C:/Users/Nana/Desktop/stuff/Python/Web Scraping/chromedriver.exe'
        self.browser = webdriver.Chrome(self.path)
        self.browser.get('https://www.amazon.com/מקלדת-מוארת-בצבעי-ועכבר-לגיימינג/dp/B016Y2BVKA/ref=sr_1_1_sspa?dchild=1&keywords=keyboard&qid=1633809059&sr=8-1-spons&psc=1&smid=A3TJEO884AOUB3&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUFCRTg0S1dWNjRTQUMmZW5jcnlwdGVkSWQ9QTA2NTEwNzgzNFdKSVA5NEpQODRQJmVuY3J5cHRlZEFkSWQ9QTAwMjcwNDExUFJOUjA4U0pEWDlRJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==')
        self.r()


    def r(self):
        self.soup = BeautifulSoup(self.browser.page_source, 'lxml')
        self.div5 = self.soup.find('div', id = 'reviewsMedley')
        self.tbody = self.div5.find('tbody')
        self.trs = self.tbody.find_all('tr')
        for self.tr in self.trs:
            self.precents = self.tr.find('td', class_ = 'a-text-right a-nowrap')
            self.pd = [self.precents.text.strip()]
            print(f'Awesome Feedback: {self.pd[0]}')
            print(f'Good Feedback: {self.pd[1]}')
            print(f'Regular Feedback: {self.pd[2]}')
            print(f'Bad Feedback: {self.pd[3]}')
            print(f'Awful Feedback: {self.pd[4]}')



        
bot()

also here is the page i'm currently scraping: https://www.amazon.com/מקלדת-מוארת-בצבעי-ועכבר-לגיימינג/dp/B016Y2BVKA/ref=sr_1_1_sspa?dchild=1&keywords=keyboard&qid=1633809059&sr=8-1-spons&smid=A3TJEO884AOUB3&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUFCRTg0S1dWNjRTQUMmZW5jcnlwdGVkSWQ9QTA2NTEwNzgzNFdKSVA5NEpQODRQJmVuY3J5cHRlZEFkSWQ9QTAwMjcwNDExUFJOUjA4U0pEWDlRJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ&th=1

CodePudding user response:

There is a single //td[@class='a-text-right a-nowrap'] element inside each tr elements you are trying to use.
So, instead of

def r(self):
    self.soup = BeautifulSoup(self.browser.page_source, 'lxml')
    self.div5 = self.soup.find('div', id = 'reviewsMedley')
    self.tbody = self.div5.find('tbody')
    self.trs = self.tbody.find_all('tr')
    for self.tr in self.trs:
        self.precents = self.tr.find('td', class_ = 'a-text-right a-nowrap')
        self.pd = [self.precents.text.strip()]
        print(f'Awesome Feedback: {self.pd[0]}')
        print(f'Good Feedback: {self.pd[1]}')
        print(f'Regular Feedback: {self.pd[2]}')
        print(f'Bad Feedback: {self.pd[3]}')
        print(f'Awful Feedback: {self.pd[4]}')

Try this:

def r(self):
        self.soup = BeautifulSoup(self.browser.page_source, 'lxml')
        self.div5 = self.soup.find('div', id = 'reviewsMedley')
        self.precentages = self.div5.find_all('td', class_ = 'a-text-right a-nowrap')
        for self.precents in self.precentages:
            self.pd = [self.precents.text.strip()]
            print(f'Awesome Feedback: {self.pd[0]}')
            print(f'Good Feedback: {self.pd[1]}')
            print(f'Regular Feedback: {self.pd[2]}')
            print(f'Bad Feedback: {self.pd[3]}')
            print(f'Awful Feedback: {self.pd[4]}')

CodePudding user response:

There are two Options #1 define pd as empty list outside the loop, append each result of iteration and also print outside the loop or do the following:

Example

def r(self):
    self.soup = BeautifulSoup(self.browser.page_source, 'lxml')
    self.pd = [x.text.strip() for x in self.soup.select('div#reviewsMedley tr td.a-text-right.a-nowrap')]
    print(f'Awesome Feedback: {self.pd[0]}')
    print(f'Good Feedback: {self.pd[1]}')
    print(f'Regular Feedback: {self.pd[2]}')
    print(f'Bad Feedback: {self.pd[3]}')
    print(f'Awful Feedback: {self.pd[4]}')

Output:

Awesome Feedback: 72%
Good Feedback: 15%
Regular Feedback: 7%
Bad Feedback: 3%
Awful Feedback: 4%
  • Related