Драматург – скупка сделок на eBay

from playwright.sync_api import Playwright, sync_playwright

with sync_playwright() as playwright:
    chromium = playwright.chromium
    browser = chromium.launch()
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://www.ebay.com/deals/tech/ipads-tablets-ereaders")
    button = page.locator("button.load-more-btn.btn.btn--secondary")
    try:
        while button:
            button.scroll_into_view_if_needed()
            button.click()
    except:
        pass
        items = page.locator("div.dne-itemtile.dne-itemtile-large").all()
        for item in items:
            print(item.locator("img").get_attribute("src"))
            print(item.locator("span.first").text_content())
            print(item.locator("span.ebayui-ellipsis-2").text_content())
            print()
        print(len(items), "items")

Я пытаюсь получить выгодные предложения на eBay.
В моем блоке try с headless = False я видел, как браузер нажимал кнопку, чтобы показать мне, пока эта кнопка больше не исчезнет, ​​но код не будет очищать все элементы, но, возможно, максимум первые 4 страницы.

В сделке eBay может быть более 800 товаров, но я смогу собрать первые 96.

🤔 А знаете ли вы, что...
В Python есть множество библиотек и фреймворков для разработки веб-приложений.


50
1

Ответ:

Решено

Короче говоря, когда вы нажимаете (или прокручиваете вниз), сервер отправляет запрос (вы можете просмотреть его в режиме разработчика) на получение сделок. Вы можете заключать сделки, используя только запросы, не беспокоясь о Playwright или Selenium.

Пример:

import time
import json
import requests
from bs4 import BeautifulSoup

LISTINGS_URL = "https://www.ebay.com/deals/spoke/ajax/listings"
TIMEZONE_OFFSET = 63072000

def get_dp1():
    current_time = hex(int(time.time()) + TIMEZONE_OFFSET)[2:]
    return f"bbl/DE{current_time}^"

def parse_deals(content):
    soup = BeautifulSoup(content, "lxml")
    items = []
    for el in soup.select("div[data-listing-id]"):
        image = el.select_one("img").get("src")
        price = el.select_one("span.first").text
        title = el.select_one("span.ebayui-ellipsis-2").text
        items.append({"title": title, "price": price, "image": image})
    return items

items = []

with requests.Session() as session:
    session.cookies.set("dp1", get_dp1())
    params = {"_ofs": 0, "category_path_seo": "tech,ipads-tablets-ereaders"}
    while True:
        print(f"Total: {len(items):<5} | Offset: {params['_ofs']}")
        response = session.get(LISTINGS_URL, params=params)
        data = response.json().get("fulfillmentValue", {})
        params = data.get("pagination", {}).get("params")
        if not params:
            break
        ditems = parse_deals(data["listingsHtml"])
        items.extend(ditems)

with open("data.json", "w") as f:
    json.dump(items, f, ensure_ascii=False, indent=2)

Выход:

[
  {
    "title": "Samsung Galaxy Tab A9+ 11.0\" 64GB Gray Wi-Fi Tablet Bundle SM-X210NZAYXAR 2023",
    "price": "$139.99",
    "image": "https://i.ebayimg.com/images/g/qbUAAOSw1o1l1Rtt/s-l300.jpg"
  },
  ...
]

Для получения сделок, как упоминалось ранее, сервер отправляет запрос GET с обязательным файлом cookie dp1, который представляет текущее время Unix (например, bbl/DE6a9839a1^). Здесь bbl/DE и ^ — постоянные значения (насколько я понимаю), а между ними — текущее время Unix в шестнадцатеричном формате.

Возможно, вам придется настроить смещение времени Unix, поскольку при доступе к сайту он отправляет значение файла cookie dp1 относительно своего часового пояса.

После этого сервер отвечает объектом JSON, содержащим всю необходимую информацию для парсинга.