skip to Main Content

I am trying to scrape a custom eBay search that shows 200 items on a single page. I need to get the title of the item, the price and the link to the said item. So far so good. But I also would like the code to follow the link to the next page with 200 or less items and extract them as well.

This is the code, I am using:

from urllib.request import urlopen as Req
from bs4 import BeautifulSoup as souce

start_url='https://www.ebay.de/sch/i.html?_fosrp=1&_from=R40&_nkw=iphone&_in_kw=1&_ex_kw=&_sacat=0&_mPrRngCbx=1&_udlo=600&_udhi=4.800&LH_BIN=1&LH_ItemCondition=4&_ftrt=901&_ftrv=1&_sabdlo=&_sabdhi=&_samilow=&_samihi=&_sadis=10&_fpos=&LH_SubLocation=1&_sargn=-1%26saslc%3D0&_fsradio2=%26LH_LocatedIn%3D1&_salic=77&_saact=77&LH_SALE_CURRENCY=0&_sop=2&_dmd=1&_ipg=200'


Client=Req(start_url)
page_html=Client.read()
Client.close()


page_soup=souce(page_html, "html.parser")


containers_listings = page_soup.findAll("li",{"class":"sresult lvresult clearfix li"})
container_next=page_soup.find("td",{"class":"pagn-next"})
next_url=container_next.a["href"]

filename="scrape_ebay.csv"
f=open(filename,"w")
headers="item_title,item_link,item_pricen"
f.write(headers)

for container in containers_listings:
item_title=container.h3.text.strip()
item_link=container.h3.a["href"].strip()
item_price=container.span.text.strip()

f.write(item_title + "," + item_link + "," + item_price.replace(",",".") + "n")

f.close()

I am running into a problem with the eBay pagination. I have managed to isolate and extract the next link but I have no idea how to implement it into a loop that would visit the next pages and extract the information. Any help would be greatly appreciated!
Thanks in advance.

3

Answers


  1. You need to append new urls to a list as you find them, and continually iterate through the list of urls extracting the content you are looking for.

    from urllib.request import urlopen as Req
    from bs4 import BeautifulSoup as souce
    
    start_url='https://www.ebay.de/sch/i.html?_fosrp=1&_from=R40&_nkw=iphone&_in_kw=1&_ex_kw=&_sacat=0&_mPrRngCbx=1&_udlo=600&_udhi=4.800&LH_BIN=1&LH_ItemCondition=4&_ftrt=901&_ftrv=1&_sabdlo=&_sabdhi=&_samilow=&_samihi=&_sadis=10&_fpos=&LH_SubLocation=1&_sargn=-1%26saslc%3D0&_fsradio2=%26LH_LocatedIn%3D1&_salic=77&_saact=77&LH_SALE_CURRENCY=0&_sop=2&_dmd=1&_ipg=200'
    
    page_urls =[start_url]
    
    for purl in page_urls:
    
        Client=Req(purl)
        page_html=Client.read()
        Client.close()
    
    
        page_soup=souce(page_html, "html.parser")
    
    
        containers_listings = page_soup.findAll("li",{"class":"sresult lvresult clearfix li"})
        container_next=page_soup.find("td",{"class":"pagn-next"})
        next_url=container_next.a["href"]
    
        #this is where you would add your new link
        if next_url not in page_urls:
            page_urls.append(next_url)
    
        filename="scrape_ebay.csv"
        f=open(filename,"w")
        headers="item_title,item_link,item_pricen"
        f.write(headers)
    
        for container in containers_listings:
            item_title=container.h3.text.strip()
            item_link=container.h3.a["href"].strip()
            item_price=container.span.text.strip()
    
        f.write(item_title + "," + item_link + "," + item_price.replace(",",".") + "n")
    
        f.close()
    
    Login or Signup to reply.
  2. Your current link garners results under 200, thus, no pagination is given, however, navigating to a more popular page, such as listings for “macbooks” yields results on multiple pages. The link used for demonstration can be found here. To find the pages, the full pagination a tag text can be found, and when looping over the latter results, the page number at the current iteration can be concatenated at the end of the link:

    from bs4 import BeautifulSoup as soup
    import requests, re
    from collections import namedtuple
    def check_under_val(val = 200):
      def outer(f):
        def wrapper(cls):
          if cls.page is not None:
            raise StopIteration("Search results for given link under {}".format(val))
          return f(cls)
        return wrapper
      return outer
    
    class Results:
       product = namedtuple('product', ['title', 'description', 'price', 'rating', 'link'])
       def __init__(self, link):
          self.link = link
          self.pagination = [i.text for i in soup(requests.get(link).text, 'html.parser').find_all('li', {'class':'x-pagination__li'})] 
          self.page = [Results.product(*i) for i in Results.scrape_page(self.link)] if not self.pagination else None 
       @staticmethod
       def concatenate(link, num:str):
          return re.sub('d+$', num, link)
       @staticmethod
       def scrape_page(url):
         current_page = soup(requests.get(url).text, 'html.parser')
         tags = [['h3', 's-item__title'], ['span', 'SECONDARY_INFO'], ['span', 's-item__price'], ['span', 'b-starrating__star'], ['a', 's-item__link']]
         items = [i for i in current_page.find_all('li', {'class':'s-item'})]
         return [[getattr(i.find(tag, {'class':c}), 'text', 'N/A') for tag, c in tags] for i in items]
       @check_under_val(val = 200)
       def __iter__(self):
         for page in self.pagination:
           yield [Results.product(*i) for i in Results.scrape_page(Results.concatenate(self.link, page))]
    
    start = 'https://www.ebay.de/sch/i.html?_sacat=0&_sop=2&_nkw=macbook&_frs=1&_pgn=1'
    r = Results(start)
    for page_results in r:
      print(page_results)
    

    Output (first printed result):

    [product(title='SSD 1TB 1Terabyte passend für Apple Macbook Pro und Air Modelle', description='Gebraucht', price='EUR 1,00', rating='N/A', link='SSD 1TB 1Terabyte passend für Apple Macbook Pro und Air Modelle'), product(title='Apple MacBook Pro A1398 39,1 cm (15,4 Zoll) Nur Display', description='Gebraucht', price='EUR 1,00', rating='5.0 von 5 Sternen - Apple MacBook Pro A1398 39,1 cm (15,4 Zoll) Nur Display', link='Apple MacBook Pro A1398 39,1 cm (15,4 Zoll) Nur Display'), product(title='Neues AngebotMacbook Late 2008', description='Gebraucht', price='EUR 1,00', rating='N/A', link='Neues AngebotMacbook Late 2008'), product(title='Apple MacBook Pro 39,1 cm (15,4 Zoll) Laptop - MB134D/A (Februar, 2008)', description='Nur Ersatzteile', price='EUR 1,00', rating='3.5 von 5 Sternen - Apple MacBook Pro 39,1 cm (15,4 Zoll) Laptop - MB134D/A (Februar, 2008)', link='Apple MacBook Pro 39,1 cm (15,4 Zoll) Laptop - MB134D/A (Februar, 2008)'), product(title='Neues AngebotApple MacBook Pro 2,53 Ghz (13,3 Zoll) Laptop (Juni, 2009), viel Leistung!', description='Gebraucht', price='EUR 1,00', rating='4.5 von 5 Sternen - Apple MacBook Pro 2,53 Ghz (13,3 Zoll) Laptop (Juni, 2009), viel Leistung!', link='Neues AngebotApple MacBook Pro 2,53 Ghz (13,3 Zoll) Laptop (Juni, 2009), viel Leistung!'), product(title='Neues AngebotMacBook Pro 15.4" Matt - Gebraucht, Mitte 2009', description='Gebraucht', price='EUR 1,00', rating='N/A', link='Neues AngebotMacBook Pro 15.4" Matt - Gebraucht, Mitte 2009'), product(title='Neues AngebotApple Macbook Air 11 inch late 2010 128 gb', description='Gebraucht', price='EUR 1,00', rating='N/A', link='Neues AngebotApple Macbook Air 11 inch late 2010 128 gb'), product(title='Neues AngebotApple MacBook A1342 33,8 cm (13,3 Zoll) Laptop (Mai, 2010) - Individuelle Konfig', description='Gebraucht', price='EUR 1,00', rating='4.5 von 5 Sternen - Apple MacBook A1342 33,8 cm (13,3 Zoll) Laptop (Mai, 2010) - Individuelle Konfig', link='Neues AngebotApple MacBook A1342 33,8 cm (13,3 Zoll) Laptop (Mai, 2010) - Individuelle Konfig'), product(title='Neues AngebotApple MacBook Air A1370 29,5 cm (11,6 Zoll) Laptop - MC506D/A (Oktober, 2010)', description='Gebraucht', price='EUR 1,00', rating='5.0 von 5 Sternen - Apple MacBook Air A1370 29,5 cm (11,6 Zoll) Laptop - MC506D/A (Oktober, 2010)', link='Neues AngebotApple MacBook Air A1370 29,5 cm (11,6 Zoll) Laptop - MC506D/A (Oktober, 2010)'), product(title='Neues AngebotApple MacBook A1342 13,3 Zoll mid 2010, 2,4GHz, 320GB HDD', description='Gebraucht', price='EUR 1,00', rating='4.5 von 5 Sternen - Apple MacBook A1342 13,3 Zoll mid 2010, 2,4GHz, 320GB HDD', link='Neues AngebotApple MacBook A1342 13,3 Zoll mid 2010, 2,4GHz, 320GB HDD'), product(title='Neues AngebotApple MacBook Pro 15" Mitte 2009 2,66 Ghz 8GB RAM 64 BIT 500GB HDD Laptop Matt', description='Gebraucht', price='EUR 1,00', rating='N/A', link='Neues AngebotApple MacBook Pro 15" Mitte 2009 2,66 Ghz 8GB RAM 64 BIT 500GB HDD Laptop Matt'), product(title='Neues AngebotApple MacBook Air - 8 GB! - 13,3 Zoll Laptop, MJVE2D/A, kaum benutzt / quasi neu', description='Gebraucht', price='EUR 1,00', rating='N/A', link='Neues AngebotApple MacBook Air - 8 GB! - 13,3 Zoll Laptop, MJVE2D/A, kaum benutzt / quasi neu'), product(title='Neues AngebotApple MacBook Pro A1278 33,8 cm (13,3 Zoll) Laptop (Juni, 2009)', description='Gebraucht', price='EUR 1,00', rating='N/A', link='Neues AngebotApple MacBook Pro A1278 33,8 cm (13,3 Zoll) Laptop (Juni, 2009)'), product(title='Neues AngebotApple Macbook Pro Modell (15 Zoll) Top Zustand  DVD Brenner, MacOS X', description='Gebraucht', price='EUR 1,00', rating='N/A', link='Neues AngebotApple Macbook Pro Modell (15 Zoll) Top Zustand  DVD Brenner, MacOS X'), product(title='Apple Macbook Pro 13 Zoll silber   ', description='Gebraucht', price='EUR 1,50', rating='N/A', link='Apple Macbook Pro 13 Zoll silber   '), product(title='Neues AngebotApple MacBook Air A1369 33,8 cm (13,3 Zoll) Laptop - MC965D/A (Juli, 2011)', description='Gebraucht', price='EUR 1,50', rating='5.0 von 5 Sternen - Apple MacBook Air A1369 33,8 cm (13,3 Zoll) Laptop - MC965D/A (Juli, 2011)', link='Neues AngebotApple MacBook Air A1369 33,8 cm (13,3 Zoll) Laptop - MC965D/A (Juli, 2011)'), product(title='Neues AngebotApple MacBook Pro A1278 13,3 Zoll Laptop Anfang 2011 i5 2,3Ghz 8GB DDR3 in OVP !', description='Gebraucht', price='EUR 2,00', rating='5.0 von 5 Sternen - Apple MacBook Pro A1278 13,3 Zoll Laptop Anfang 2011 i5 2,3Ghz 8GB DDR3 in OVP !', link='Neues AngebotApple MacBook Pro A1278 13,3 Zoll Laptop Anfang 2011 i5 2,3Ghz 8GB DDR3 in OVP !'), product(title='Apple MacBook Pro (13,3 Zoll, 2009) - 120GB SSD - 2GB RAM', description='Gebraucht', price='EUR 2,50', rating='N/A', link='Apple MacBook Pro (13,3 Zoll, 2009) - 120GB SSD - 2GB RAM'), product(title='Neues AngebotApple MacBook 12“ Space Grau/ 1.1 GHz/ 8GB/ 256 GB inkl. Zubehör', description='Gebraucht', price='EUR 2,72', rating='N/A', link='Neues AngebotApple MacBook 12“ Space Grau/ 1.1 GHz/ 8GB/ 256 GB inkl. Zubehör'), product(title='Apple MacBook Pro A1286 39,1 cm, 2011, 16gb, SSD + HDD, HI-RES', description='Gebraucht', price='EUR 4,00', rating='5.0 von 5 Sternen - Apple MacBook Pro A1286 39,1 cm, 2011, 16gb, SSD + HDD, HI-RES', link='Apple MacBook Pro A1286 39,1 cm, 2011, 16gb, SSD + HDD, HI-RES'), product(title='Original Karton - Apple MacBook Air (2014) - Intel i5 1,4 GHz, 4GB - NUR KARTON', description='Gebraucht', price='EUR 4,95', rating='N/A', link='Original Karton - Apple MacBook Air (2014) - Intel i5 1,4 GHz, 4GB - NUR KARTON'), product(title='Macbook Air 13 Zoll Baujahr 2012 OHNE Festplatte Silber Space', description='Gebraucht', price='EUR 5,00', rating='N/A', link='Macbook Air 13 Zoll Baujahr 2012 OHNE Festplatte Silber Space'), product(title='Apple MacBook Pro A1286 39,1 cm (15,4 Zoll) Laptop -  (Juni, 2009)', description='Gebraucht', price='EUR 6,00', rating='5.0 von 5 Sternen - Apple MacBook Pro A1286 39,1 cm (15,4 Zoll) Laptop -  (Juni, 2009)', link='Apple MacBook Pro A1286 39,1 cm (15,4 Zoll) Laptop -  (Juni, 2009)'), product(title='Neues AngebotApple MacBook 12" Laptop , 256GB - MNYF2D/A - August 2017, Space Grau neuwertig!', description='Gebraucht', price='EUR 6,50', rating='1.0 von 5 Sternen - Apple MacBook 12" Laptop , 256GB - MNYF2D/A - August 2017, Space Grau neuwertig!', link='Neues AngebotApple MacBook 12" Laptop , 256GB - MNYF2D/A - August 2017, Space Grau neuwertig!'), product(title='MacBook Pro 15 Zoll A1211 Defekt', description='Gebraucht', price='EUR 8,00', rating='N/A', link='MacBook Pro 15 Zoll A1211 Defekt'), product(title='Apple Macbook Pro 13', description='Brandneu', price='EUR 8,26', rating='N/A', link='Apple Macbook Pro 13'), product(title='Apple MacBook A1342 33,8 cm (13,3 Zoll) Laptop - MC207D/A (Oktober, 2009)', description='Gebraucht', price='EUR 8,50', rating='4.5 von 5 Sternen - Apple MacBook A1342 33,8 cm (13,3 Zoll) Laptop - MC207D/A (Oktober, 2009)', link='Apple MacBook A1342 33,8 cm (13,3 Zoll) Laptop - MC207D/A (Oktober, 2009)'), product(title='Apple Macbook Pro 13', description='Brandneu', price='EUR 8,63', rating='N/A', link='Apple Macbook Pro 13'), product(title='Apple MacBook 33,8 cm (13,3 Zoll) Laptop -(2008)', description='Gebraucht', price='EUR 10,00', rating='4.5 von 5 Sternen - Apple MacBook 33,8 cm (13,3 Zoll) Laptop -(2008)', link='Apple MacBook 33,8 cm (13,3 Zoll) Laptop -(2008)'), product(title='Neues AngebotApple MacBook Pro A1502 33,8 cm (13,3 Zoll) Laptop - ME865D/A (Oktober, 2013)', description='Gebraucht', price='EUR 10,00', rating='5.0 von 5 Sternen - Apple MacBook Pro A1502 33,8 cm (13,3 Zoll) Laptop - ME865D/A (Oktober, 2013)', link='Neues AngebotApple MacBook Pro A1502 33,8 cm (13,3 Zoll) Laptop - ME865D/A (Oktober, 2013)'), product(title='Apple MacBook A1181 33,8 cm (13,3 Zoll) Laptop - MB061D/A ', description='Gebraucht', price='EUR 10,50', rating='5.0 von 5 Sternen - Apple MacBook A1181 33,8 cm (13,3 Zoll) Laptop - MB061D/A ', link='Apple MacBook A1181 33,8 cm (13,3 Zoll) Laptop - MB061D/A '), product(title="Neues AngebotApple MacBook Pro  13.3'' A1706 256GB Laptop mit Touchbar - DEFEKT", description='Nur Ersatzteile', price='EUR 10,50', rating="5.0 von 5 Sternen - Apple MacBook Pro  13.3'' A1706 256GB Laptop mit Touchbar - DEFEKT", link="Neues AngebotApple MacBook Pro  13.3'' A1706 256GB Laptop mit Touchbar - DEFEKT"), product(title='apple macbook pro 13', description='Gebraucht', price='EUR 10,50', rating='N/A', link='apple macbook pro 13'), product(title='Neues AngebotMacbook Pro 15 Zoll von 2007 A1211, 2 GB ram, Core 2 Duo, ATI Grafikkarte, 350GB', description='Gebraucht', price='EUR 11,50', rating='N/A', link='Neues AngebotMacbook Pro 15 Zoll von 2007 A1211, 2 GB ram, Core 2 Duo, ATI Grafikkarte, 350GB'), product(title='Apple MacBook A1181 33,8 cm (13,3 Zoll) Laptopxa0', description='Gebraucht', price='EUR 11,50', rating='5.0 von 5 Sternen - Apple MacBook A1181 33,8 cm (13,3 Zoll) Laptopxa0', link='Apple MacBook A1181 33,8 cm (13,3 Zoll) Laptopxa0'), product(title='Neues AngebotApple MacBook Air Mitte 2011 13,3 Zoll i5 121 GB SSD 4 GB RAM', description='Gebraucht', price='EUR 11,50', rating='N/A', link='Neues AngebotApple MacBook Air Mitte 2011 13,3 Zoll i5 121 GB SSD 4 GB RAM'), product(title='Apple MacBook Pro 43,2 cm (17 Zoll) Laptop - MA611D/A (Oktober, 2006)', description='Gebraucht', price='EUR 11,50', rating='5.0 von 5 Sternen - Apple MacBook Pro 43,2 cm (17 Zoll) Laptop - MA611D/A (Oktober, 2006)', link='Apple MacBook Pro 43,2 cm (17 Zoll) Laptop - MA611D/A (Oktober, 2006)'), product(title='Apple MacBook Pro 15“ 2,33 GHz 500GB HDD 2GB RAM', description='Gebraucht', price='EUR 12,50', rating='N/A', link='Apple MacBook Pro 15“ 2,33 GHz 500GB HDD 2GB RAM'), product(title='Apple MacBook A1181 13,3 Zoll, 2,2 GHz 256GB HDD, 4GB Ram, OS X Lion & Bootcamp', description='Gebraucht', price='EUR 12,50', rating='N/A', link='Apple MacBook A1181 13,3 Zoll, 2,2 GHz 256GB HDD, 4GB Ram, OS X Lion & Bootcamp'), product(title='MacBook 13‘‘ Ende 2009', description='Gebraucht', price='EUR 13,50', rating='N/A', link='MacBook 13‘‘ Ende 2009'), product(title='Apple MacBook Pro 17 Zoll Core 2 Duo 2.33 GHz 3Gb Ram 100GB 7200rpm HDD', description='Gebraucht', price='EUR 15,50', rating='N/A', link='Apple MacBook Pro 17 Zoll Core 2 Duo 2.33 GHz 3Gb Ram 100GB 7200rpm HDD'), product(title='Macbook pro A1278 Originalverpackung TOP', description='Gebraucht', price='EUR 19,00', rating='N/A', link='Macbook pro A1278 Originalverpackung TOP'), product(title='Macbook Pro 13" 2017', description='Brandneu', price='EUR 21,41', rating='N/A', link='Macbook Pro 13" 2017'), product(title='2 x Original Apple Macbook Pro Retina 15“ Verpackung OVP Karton Box A1398', description='Gebraucht', price='EUR 22,00', rating='N/A', link='2 x Original Apple Macbook Pro Retina 15“ Verpackung OVP Karton Box A1398'), product(title='Apple MacBook Air A1466 33,8 cm (13,3 Zoll) Laptop - MD760B/A (Juni, 2013)', description='Gebraucht', price='EUR 22,50', rating='5.0 von 5 Sternen - Apple MacBook Air A1466 33,8 cm (13,3 Zoll) Laptop - MD760B/A (Juni, 2013)', link='Apple MacBook Air A1466 33,8 cm (13,3 Zoll) Laptop - MD760B/A (Juni, 2013)'), product(title='MacBook Air 13, 2013', description='Brandneu', price='EUR 23,50', rating='N/A', link='MacBook Air 13, 2013'), product(title='Apple MacBook Pro A1278 33,8 cm (13,3 Zoll) Laptop (Juni, 2009) -...', description='Gebraucht', price='EUR 25,00', rating='4.5 von 5 Sternen - Apple MacBook Pro A1278 33,8 cm (13,3 Zoll) Laptop (Juni, 2009) -...', link='Apple MacBook Pro A1278 33,8 cm (13,3 Zoll) Laptop (Juni, 2009) -...'), product(title='macbook pro 13', description='Gebraucht', price='EUR 25,00', rating='N/A', link='macbook pro 13'), product(title='Neues AngebotMacBook Pro 15 Zoll Late 2011 Batterie', description='Gebraucht', price='EUR 25,00', rating='N/A', link='Neues AngebotMacBook Pro 15 Zoll Late 2011 Batterie'), product(title='MacBook Air SuperDrive', description='Gebraucht', price='EUR 29,99', rating='N/A', link='MacBook Air SuperDrive')]
    

    However, if the input does not contain pagination links, only the first page will be accessible:

    start = 'https://www.ebay.de/sch/i.html?_fosrp=1&_from=R40&_nkw=iphone&_in_kw=1&_ex_kw=&_sacat=0&_mPrRngCbx=1&_udlo=600&_udhi=4.800&LH_BIN=1&LH_ItemCondition=4&_ftrt=901&_ftrv=1&_sabdlo=&_sabdhi=&_samilow=&_samihi=&_sadis=10&_fpos=&LH_SubLocation=1&_sargn=-1%26saslc%3D0&_fsradio2=%26LH_LocatedIn%3D1&_salic=77&_saact=77&LH_SALE_CURRENCY=0&_sop=2&_dmd=1&_ipg=200'
    r1 = Results(start)
    for page in r1:
      print(page)
    

    StopIteration: Search results for given link under 200

    Update November 2019:

    The solution is outdated. A possible way to handle Ebay pagination currently is below:

    import requests, re
    from bs4 import BeautifulSoup as soup
    def get_products(_d):
       return [{'link':i.h3.a['href'], 'title':i.h3.a.text, 'price':i.find('li', {'class':'lvprice prc'}).get_text(strip=True)} for i in _d.find('ul', {'id':'ListViewInner'}).find_all('li', {'id':re.compile('^item')})]
    
    d = soup(requests.get('https://www.ebay.de/sch/i.html?_fosrp=1&_from=R40&_nkw=iphone&_in_kw=1&_ex_kw=&_sacat=0&_mPrRngCbx=1&_udlo=600&_udhi=4.800&LH_BIN=1&LH_ItemCondition=4&_ftrt=901&_ftrv=1&_sabdlo=&_sabdhi=&_samilow=&_samihi=&_sadis=10&_fpos=&LH_SubLocation=1&_sargn=-1%26saslc%3D0&_fsradio2=%26LH_LocatedIn%3D1&_salic=77&_saact=77&LH_SALE_CURRENCY=0&_sop=2&_dmd=1&_ipg=200').text, 'html.parser')
    vals = [get_products(d)]
    while (k:=d.find('td', {'class':'pagn-next'}).a).attrs.get('aria-disabled') != 'true':
       d = soup(requests.get(k['href']).text, 'html.parser')
       vals.append(get_products(d))
    
    Login or Signup to reply.
  3. eBay has a _pgn URL parameter which responsible for pagination. With that in mind, we can increment its value by 1 for the second, third, and so on pages accordingly.

    We need to increment the page value only when a certain condition is met and only use the while loop to paginate through all possible pages dynamically i.e not using for i in range(1, 100) which is hardcoded way of doing pagination.

    Keep in mind that your requests.get() and soup need to be inside while loop as this is what let data be updated.

    To exit from the infinite while loop we need to check every time if the next page button is active (in the case of eBay, on different websites it might be different) with a .pagination__next CSS selector. If it becomes inactive (no next page), we’ll break out of the loop:

    if soup.select_one(".pagination__next"):
         params['_pgn'] += 1
    else:
         break
    

    A prettier and more readable way could be to use parameters dict, it is a convenient way of updating URL search parameters:

    params = {
        '_nkw': 'iphone',     # search query  
        '_pgn': 1,            # page number
        '_ipg': 200           # number of products per page
    }
    

    With frequent requests, the site may start blocking your requests if using requests as default user-agent in requests library is a python-requests. You can learn more about ways to bypass the blocking in the Reducing the chance of being blocked while web scraping blog post.

    See how pagination works in online IDE

    from bs4 import BeautifulSoup
    import requests, json, lxml
    
    # https://requests.readthedocs.io/en/latest/user/quickstart/#custom-headers
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
    }
        
    params = {
        '_nkw': 'iphone',     # search query  
        '_pgn': 1,            # page number
        '_ipg': 200           # number of products per page
    }
    
    data = []
    
    while True:
        page = requests.get('https://www.ebay.com/sch/i.html', params=params, headers=headers, timeout=30)
        soup = BeautifulSoup(page.text, 'lxml')
        
        print(f"Extracting page: {params['_pgn']}")
    
        print("-" * 10)
        
        for products in soup.select(".s-item__info"):        
            try:
                price = products.select_one(".s-item__price").text
            except: 
                price = None        
            try:
                link = products.select_one(".s-item__link")["href"]
            except: 
                link = None
            try:
                title = products.select_one(".s-item__title span").text
            except: 
                title = None
            
            data.append({
              "title" : title,
              "price" : price,
              "link" : link
            })
    
        if soup.select_one(".pagination__next"):
            params['_pgn'] += 1
        else:
            break
    
    print(json.dumps(data, indent=2, ensure_ascii=False))
    

    Example output:

    [
        {
        "title": "Apple iPhone 7 (Excellent Condition) Factory Unlocked, Verizon, AT&T, T-Mobile",
        "price": "$129.99",
        "link": "https://www.ebay.com/itm/324760206655?epid=28032604856&hash=item4b9d377d3f:g:3QIAAOSwDRZfsXS~&amdata=enc%3AAQAHAAAA4OnuvF3hbbEHp5ShpGLkGWwWNQPFcMOczn8qAbaiRH3JN3RnA%2Fo5KU5rTG1pfDtAJEljpPhRFMqTtzr%2BSxYdqDMdOc%2BOn8hBqRl6b1weyByx9gaI%2FACq1tPY4Y%2B5JQsDZrhGEBmrB7sb4PTTl526RmlKGlU46o6xnn%2Fhkddngh2EKWS4FsFKLjy9fYRaXWCWtmx1wy%2BWtf6%2BngisW38qIbcLjmK28PD2SMrXHw7H58EzkT64JwHduKSxlKKSWktiy0PRGeTBZ5AW2zNoqpXookQ%2FtL2bbmuzMU8SN0nYVzln%7Ctkp%3ABFBM6u6V0Ith"
      },
      {
        "title": "Apple iPhone 11 Pro - 64GB - Space Gray - Factory Unlocked - NO FACE ID",
        "price": "$300.00",
        "link": "https://www.ebay.com/itm/275240933691?epid=6034218747&hash=item4015a3593b:g:v0oAAOSwcPNg8MAr&amdata=enc%3AAQAHAAAA4C%2FemhH0GiJs2YQM%2BWmSUZc7UiKZbdMXYJ9chsRMvB1m1Nz0AdYQIxSs4ocR22nY9ZUElw4hQGn0y261ccNRG2uGjuuZbLznB96IjBsdxtWR3zI%2F9HuxbG5Hsq819Ym9EXqO1ZzAzrEter3VT6aJknjDpLc8pQZq%2B1%2Fwd07gt9fU%2BlNEjAD0fwCoColJ8x89lsxujaVkHEw1rliqHDXALqdaT72Jt16asg6n4aU5pARcFW8SBrtPHXUUd7u4V35DlEphzS4NFr70AffXe8AGjgUv6MU5SSDxm%2F359MGE1JSM%7Ctkp%3ABFBM6u6V0Ith"
      }
      #...
    ]
    

    As another option you can use Ebay Organic Results API from SerpApi. It’s a paid API with a free plan that handles blocks and parsing on their backend.

    Example code with pagination:

    from serpapi import EbaySearch
    from urllib.parse import (parse_qsl, urlsplit)
    import os, json
    
    params = {
        "api_key": os.getenv("API_KEY"),  # serpapi api key    
        "engine": "ebay",                 # search engine
        "ebay_domain": "ebay.com",        # ebay domain
        "_nkw": "iphone",                 # search query
      # "LH_Sold": "1"                    # shows sold items
    }
    
    search = EbaySearch(params)        # where data extraction happens
    
    page_num = 0
    
    data = []
    
    while True:
        results = search.get_dict()     # JSON -> Python dict
    
        if "error" in results:
            print(results["error"])
            break
        
        for organic_result in results.get("organic_results", []):
            link = organic_result.get("link")
            price = organic_result.get("price")
    
            data.append({
              "price" : price,
              "link" : link
            })
                        
        page_num += 1
        print(page_num)
        
        if "next" in results.get("pagination", {}):
            params['_pgn'] += 1
    
        else:
            break
    
        print(json.dumps(data, indent=2))
    

    Output:

    [
        {
        "price": {
          "raw": "$123.24",
          "extracted": 123.24
        },
        "link": "https://www.ebay.com/itm/174901208061?epid=15051465978&hash=item28b8eca3fd:g:9qkAAOSwM5JhH1-5&amdata=enc%3AAQAHAAAA0EYv8HDEOrSLxH0eIwB1UB5foXEAG8GR4ajz2llsgzSIbbwLB0L6LxZ5%2BkKYXD46p4T%2FALftbn0g3JdvFtTMvnUzaP4QU0rBZdL%2Btge%2Bu8k%2BXIOmRjUCc4OsYb%2BQ9H8Tpxo8sAyxE2HeJ4PFbDJb1m%2FPAoaPZXYEliH22fuHBEsW3ThKHFL4HQDncIZc8Jo7OIiN4esC6anSU3bE330cHPXMF9%2FfBkPeh46%2BOPc97xhsknSQEav0ulOvoEFiKPWLBf1N9LrobncdyaW9USRVZxA%3D%7Ctkp%3ABFBMjJ-p0Ith"
      },
      {
        "price": {
          "raw": "$293.24",
          "extracted": 293.24
        },
        "link": "https://www.ebay.com/itm/194316866035?epid=8023709558&hash=item2d3e3011f3:g:DfAAAOSw1ephFOPR&amdata=enc%3AAQAHAAAA4NSJ9hyAPoE3EL%2F86975ibO6oGJ9BL4HI5AkaO1CpnUgkAlpF8cadAuGjNZXbb7NorsDrNpRkpSPHhOe9Z0qN9EWi%2B3l1UF%2Fhvs4IX9GPHjoAnyVJJxNH9z7H05O58Zszl6CnNGiI7nMNf9Wbsu9ZYkd4wzDHnpsokoFSm720TeOWpdQrOGWusd7UbAxaXhyoJyw2Ea0%2BJIbs6bgo7UuMy%2F62Na%2F4Nqgtrt5kROM3pYzxw%2FIc%2Fw%2BnbdYKFfO09EstxjjYMVWKx9M7nlMLvGxjH4H85p4eXZ7FyOlEuArUrAW%7Ctkp%3ABFBMjJ-p0Ith"
      }
      # ...
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search