пагинация при парсинге

robisho

Активный пользователь
Пользователь
Окт 19, 2020
151
26
28
Добрый день. При парсинге возник затык, есть страница категории со статьями, у каждой категории разное количество страниц со статьями, нужно вытащить все ссылки на статьи со всех страниц у каждой категории.
Написал такой цикл
Python:
import requests
from bs4 import BeautifulSoup
from lxml import html


def get_html_code(session, url):  # получение html кода
    response = session.get(url, headers=headers)
    response.encoding = 'utf8'
    html_code = response.text
    return html_code


def get_subcat_urls(session, url):  # urls из субкатегории
    # https://www.site.net/category/cat_name/subcat_name/
    html_code = get_html_code(session, url)
    tree = html.fromstring(html_code)
    subcat_urls = []
    urls = get_page_urls(session, url)
    subcat_urls.append(urls)

    href = tree.xpath("//a[@class='nextpostslink']/@href")[0]
    # ссылка на следующую страницу со статьями
    # https://www.site.net/category/cat_name/subcat_name/page/2/
    link = href[:-2]
    # формируем ссылку https://www.site.net/category/cat_name/subcat_name/page/
    count = int(href[-2]) # это счетчик страниц, равен 2 сначала
    while True:
        post_cat = tree.xpath("//div[@class='post-cat']")
        # это флаг, если он есть на странице - парсим, если нету - страница пустая
        if not post_cat:
            break
        next_url = link + str(count) + '/'

        urls = get_page_urls(session, next_url)
        subcat_urls.append(urls)
        count += 1

        #print(subcat_urls)
        return(subcat_urls)

  
session = requests.Session()
url = 'https://www.site.net/category/cat_name/subcat_name'
print(get_subcat_urls(session, url))

если запускать в таком варианте - выводит на печать ссылки только с двух первых страниц, если раскомментировать print(subcat_urls) - выдает то, что нужно, все ссылки с категории, но в бесконечном цикле ((( чувствую, что хожу где-то рядом, но голова уже не соображает.... пагинация на сайте устроена по-дебильному, на странице указано 10 ссылок, а со статьями может быть только 5, поэтому цикл while нужен.
 

robisho

Активный пользователь
Пользователь
Окт 19, 2020
151
26
28
может быть кому-нибудь будет интересно, победил таким образом:
в цикле необходима была проверка флага, добавил функцию

Python:
def parsing_flag(session, url):  # проверка наличия тега на странице
    html_code = get_html_code(session, url)
    tree = html.fromstring(html_code)
    post_cat = tree.xpath("//div[@class='post-cat']")
    if post_cat:
        return True
    else:
        return False

и функция, получающая ссылки из субкатегории вышла такой

Python:
def get_subcat_urls(session, url):  # все урлы из субкатегории
    html_code = get_html_code(session, url)
    tree = html.fromstring(html_code)
    subcat_urls = []
    urls = get_page_urls(session, url)
    subcat_urls.append(urls)

    # если страница не одна
    try:
        href = tree.xpath("//a[@class='nextpostslink']/@href")[0]
        link = href[:-2]
        count = int(href[-2])

        while True:
            next_url = link + str(count) + '/'
            if not parsing_flag(session, next_url):
                break

            urls = get_page_urls(session, next_url)
            subcat_urls.append(urls)
            count += 1
    except:
        print('У этой подкатегории одна страница со статьями')
        
    # преобразование списка списков в плоский список
    flat_list = [item for sublist in subcat_urls for item in sublist]
    return flat_list
 

Форум IT Специалистов