Как перебирать страницы в Ebay - PullRequest
1 голос
/ 15 января 2020

Я строю скребок для Ebay. Я пытаюсь найти способ манипулирования частью номера страницы URL-адреса Ebay до go до следующей страницы, пока не останется больше страниц (если бы вы были на странице 2, часть номера страницы выглядела бы как "_pgn = 2 «). Я заметил, что если вы введете любое число, превышающее максимальное количество страниц в списке, страница будет перезагружена до последней страницы, а не выдаст ошибку, как будто страницы не существует. (Если в листинге 5 страниц, то часть URL-адреса номера последней страницы _pgn = 5 будет перенаправлена ​​на ту же страницу, если часть URL-адреса номера страницы будет _pgn = 100). Как я могу реализовать способ начать с первой страницы, получить суп html страницы, получить все необходимые данные из супа, затем загрузить следующую страницу с новым номером страницы и начать процесс снова, пока нет никаких новых страниц, чтобы выскрести? Я попытался получить количество результатов, которое имеет листинг, используя selenium xpath и math.ceil, являющиеся частным от количества результатов и 50 (число записей по умолчанию для макс. Списков на странице), и использую этот коэффициент в качестве моей max_page, но я получаю сообщения об ошибках: элемент не существует, хотя он и существует. self.driver.findxpath ( 'XPath'). Текст. Это 243 - это то, что я пытаюсь получить с помощью xpath. That 243 is what I am trying to get with xpath

class EbayScraper(object):

def __init__(self, item, buying_type):
    self.base_url = "https://www.ebay.com/sch/i.html?_nkw="
    self.driver = webdriver.Chrome(r"chromedriver.exe")
    self.item = item
    self.buying_type = buying_type + "=1"
    self.url_seperator = "&_sop=12&rt=nc&LH_"
    self.url_seperator2 = "&_pgn="
    self.page_num = "1"

def getPageUrl(self):
    if self.buying_type == "Buy It Now=1":
        self.buying_type = "BIN=1"

    self.item = self.item.replace(" ", "+")

    url = self.base_url + self.item + self.url_seperator + self.buying_type + self.url_seperator2 + self.page_num
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    return soup

def getInfo(self, soup):
    for listing in soup.find_all("li", {"class": "s-item"}):
        raw = listing.find_all("a", {"class": "s-item__link"})
        if raw:
            raw_price = listing.find_all("span", {"class": "s-item__price"})[0]
            raw_title = listing.find_all("h3", {"class": "s-item__title"})[0]
            raw_link = listing.find_all("a", {"class": "s-item__link"})[0]
            raw_condition = listing.find_all("span", {"class": "SECONDARY_INFO"})[0]
            condition = raw_condition.text
            price = float(raw_price.text[1:])
            title = raw_title.text
            link = raw_link['href']
            print(title)
            print(condition)
            print(price)
            if self.buying_type != "BIN=1":
                raw_time_left = listing.find_all("span", {"class": "s-item__time-left"})[0]
                time_left = raw_time_left.text[:-4]
                print(time_left)
            print(link)
            print('\n')



if __name__ == '__main__':
item = input("Item: ")
buying_type = input("Buying Type (e.g, 'Buy It Now' or 'Auction'): ")

instance = EbayScraper(item, buying_type)
page = instance.getPageUrl()
instance.getInfo(page)

1 Ответ

2 голосов
/ 15 января 2020

если вы хотите перебрать все страницы и собрать все результаты, тогда ваш скрипт должен проверить, существует ли страница next после посещения страницы

import requests
from bs4 import BeautifulSoup


class EbayScraper(object):

    def __init__(self, item, buying_type):
        ...
        self.currentPage = 1

    def get_url(self, page=1):
        if self.buying_type == "Buy It Now=1":
            self.buying_type = "BIN=1"

        self.item = self.item.replace(" ", "+")
        # _ipg=200 means that expect a 200 items per page
        return '{}{}{}{}{}{}&_ipg=200'.format(
            self.base_url, self.item, self.url_seperator, self.buying_type,
            self.url_seperator2, page
        )

    def page_has_next(self, soup):
        container = soup.find('ol', 'x-pagination__ol')
        currentPage = container.find('li', 'x-pagination__li--selected')
        next_sibling = currentPage.next_sibling
        if next_sibling is None:
            print(container)
        return next_sibling is not None

    def iterate_page(self):
        # this will loop if there are more pages otherwise end
        while True:
            page = instance.getPageUrl(self.currentPage)
            instance.getInfo(page)
            if self.page_has_next(page) is False:
                break
            else:
                self.currentPage += 1

    def getPageUrl(self, pageNum):
        url = self.get_url(pageNum)
        print('page: ', url)
        response = requests.get(url)
        soup = BeautifulSoup(response.text, 'html.parser')
        return soup

    def getInfo(self, soup):
        ...


if __name__ == '__main__':
    item = input("Item: ")
    buying_type = input("Buying Type (e.g, 'Buy It Now' or 'Auction'): ")

    instance = EbayScraper(item, buying_type)
    instance.iterate_page()

важными функциями здесь являются page_has_next и iterate_page

  • page_has_next - функция, которая проверяет, имеет ли нумерация страниц другой элемент li рядом со страницей selected. например, < 1 2 3 >, если мы находимся на странице 1, тогда он проверяет, есть ли 2 рядом -> что-то вроде этого

  • iterate_page - функция, которая l oop, пока нет page_next

также обратите внимание, что для этого вам не нужен селен, если только вам не нужно имитировать c нажатий пользователей или браузер для навигации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...