Как получить следующие страницы, используя BeautifulSoup? - PullRequest
0 голосов
/ 25 мая 2019

Я пишу код для извлечения всех продуктов из заданных URL-адресов. Он работает нормально, но некоторые URL-адреса содержат много страниц, поэтому я пытаюсь получить все последующие страницы, найдя ul, содержащий страницы, URL, проблема в том, что он отображается толькопервые 3 страницы и последняя страница enter image description here
Нумерация страниц ul

    <li class="plp-pagination__nav disable">
           <a href="" rel="prev" class="plp-pagination__navpre">
             previous </a>
         </li>
    <li class="plp-pagination__nav active"><a class="plp-pagination__navpages" href="javascript:void(0);">1</a></li>
            <li class="plp-pagination__nav"><a class="plp-pagination__navpages" href="here is the page url ">2</a></li>
                <li class="plp-pagination__nav"><a class="plp-pagination__navpages" href="here is the page url">3</a></li>
                <li class="plp-pagination__nav"><a class="plp-pagination__navpages" href="here is the page url">4</a></li>
                <li class="plp-pagination__nav"><a class="plp-pagination__navpages" href="here is the page url">5</a></li>
                <li class="plp-pagination__nav"> <span class="plp-pagination__navplaceholder"></span></li>
             <li class="plp-pagination__nav"><a class="plp-pagination__navpages" href="here is the page url">54</a></li>
       <li class="plp-pagination__nav">
            <a class="plp-pagination__navnext" href="here is the page url" rel="next">
                  next</a>
            </li>
    </ul>

Функция чтения

def update():
    df = pd.DataFrame( columns=['poduct_name','image_url','price'])
    #lsit of required pages 
    urls= ['1st page','2nd page','3rd page']

    for url in urls:
        page = requests.get(url)
        soup = BeautifulSoup(page.text)
        #get the list of pages in pagination ul   
        new_pages= soup.find('ul', attrs={'class':'plp-pagination__wrapper'})
        #check if there is pagination ul
        if(new_pages!=None):
            new_urls= new_pages.find_all('li', attrs={'class':'plp-pagination__navpages'})
            for x in new_urls: 
                 urls.append(x)
        product_div= soup.find_all('div', attrs={'class':'comp-productcard__wrap'})
        product_list=[]
        for x in product_div:
            poduct_name= x.find('p', attrs={'class':'comp-productcard__name'}).text.strip()
            product_price_p= x.find('p', attrs={'class':'comp-productcard__price'}).text
            product_img= x.img['src']
            product_list.append({'poduct_name':poduct_name,'image_url':product_img,'price':product_price})
            df = df.append(pd.DataFrame(product_list))
    return df

Ответы [ 2 ]

0 голосов
/ 25 мая 2019

Вы можете обойти эту проблему, добавив следующий скрипт:

urls= []
home_page = requests.get("https://www.carrefourksa.com/mafsau/en/food-beverages/c/FKSA1000000?&qsort=relevance&pg")
home_soup = BeautifulSoup(home_page.content, "lxml")
page_nmb_find = home_soup.findAll("a", {"class":"plp-pagination__navpages"})
last_page = int(page_nmb_find[-1].getText())

for nmb in range(0,last_page):
    urls.append(f"https://www.carrefourksa.com/mafsau/en/food-beverages/c/FKSA1000000?&qsort=relevance&pg={nmb}")

В целом ваш код должен выглядеть так:

def update():
    df = pd.DataFrame( columns=['poduct_name','image_url','price'])
    #lsit of required pages 
    urls= []
    home_page = requests.get("https://www.carrefourksa.com/mafsau/en/food-beverages/c/FKSA1000000?&qsort=relevance&pg")
    home_soup = BeautifulSoup(home_page.content, "lxml")
    page_nmb_find = home_soup.findAll("a", {"class":"plp-pagination__navpages"})
    last_page = int(page_nmb_find[-1].getText())
    for nmb in range(0,last_page):
        urls.append(f"https://www.carrefourksa.com/mafsau/en/food-beverages/c/FKSA1000000?&qsort=relevance&pg={nmb}")

    for url in urls:
        page = requests.get(url)
        soup = BeautifulSoup(page.text, "lxml")
        #get the list of pages in pagination ul   
        new_pages= soup.find('ul', attrs={'class':'plp-pagination__wrapper'})
        #check if there is pagination ul
        if(new_pages!=None):
            new_urls= new_pages.find_all('li', attrs={'class':'plp-pagination__navpages'})
            for x in new_urls: 
                 urls.append(x)
        product_div= soup.find_all('div', attrs={'class':'comp-productcard__wrap'})
        product_list=[]
        for x in product_div:
            poduct_name= x.find('p', attrs={'class':'comp-productcard__name'}).text.strip()
            product_price_p= x.find('p', attrs={'class':'comp-productcard__price'}).text
            product_img= x.img['src']
            product_list.append({'poduct_name':poduct_name,'image_url':product_img,'price':product_price_p})
            df = df.append(pd.DataFrame(product_list))
    return df

(PS: похоже, что product_price не существует, поэтому я заменил его на product_price_p)

Надеюсь, это поможет!

0 голосов
/ 25 мая 2019

Судя по всему, речь идет о Carrefour .Это примерно так, как я бы это сделал (псевдокод).

Можно было бы запросить первую страницу.После запроса указанной страницы можно получить привязку с классом plp-pagination__navnext.Затем можно использовать ссылку этого якоря в качестве следующего URL-адреса для запроса.У вас нет списка всех URL страниц в начале.После запроса страницы вы очищаете URL следующей страницы и запрашиваете его.

Псевдокод:

1. Load first page
2. Scrape whatever you're looking to scrape
3. Get href of next page element via selector 'a.pagination__navnext'
4. Load the next page (its URL is the href you just acquired)
5. Repeat from step 2
Stop when reached last page, AKA when next page elem's href is '' on Carrefour.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...