Невозможно очистить данные с eastbay.com с помощью BS4? - PullRequest
0 голосов
/ 17 апреля 2019

Итак, я выбрал бренды, которые меня интересуют, и был сгенерирован этот URL:

https://www.eastbay.com/category/mens/shoes.html?query=%3Arelevance%3Agender%3A200000%3AproductType%3A200005%3Abrand%3AChampion%3Abrand%3AConverse%3Abrand%3AFila%3Abrand%3AJordan%3Abrand%3ANew+Balance%3Abrand%3ANike%3Abrand%3ANike+SB%3Abrand%3APUMA%3Abrand%3AReebok%3Abrand%3ASalomon%3Abrand%3AThe+North+Face%3Abrand%3ATimberland%3Abrand%3AUGG%3Abrand%3AUnder+Armour%3Abrand%3AVans%3Abrand%3Aadidas%3Abrand%3Aadidas+Originals&

Я пытаюсь почистить данные с этой страницы, в основном продуктURL страницы (href значения атрибутов a элементов с классом Link--product).

Моя первая проблема заключается в том, что, используя BS4, я не смог получить какие-либо данные с веб-сайта.

Даже при запуске этого простого тестового фрагмента (не считая большинства импортов, они используются в основной программе),

import requests
import csv
import io
import os
import re
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from datetime import datetime
from bs4 import BeautifulSoup

headers = {
     'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
}

data = requests.get("https://www.eastbay.com/category/sport/casual/mens/shoes.html",headers=headers)
soup = BeautifulSoup(data.text, 'lxml')

x = soup.find('span', attrs={'class': 'primary'}).text.strip()
print(x)

, который должен печатать текст в первом элементе span с классомprimary (результат должен быть Nike Air Force 1 Low), возвращает ошибку requests.exceptions.ConnectionError: ('Connection aborted.', OSError("(10060, 'WSAETIMEDOUT')")), которая должна указывать, что мои заголовки не принимаются хостом, но я пробовал много разных заголовков без успеха.

Я заставил Selenium работать и отображать Nike Air Force 1 Low, используя этот простой фрагмент:

driver = webdriver.Chrome()
driver.get("https://www.eastbay.com/category/sport/casual/mens/shoes.html") 
x = driver.find_element_by_xpath("//span[@class='primary']")
print(x.text)
driver.close()

, но я бы действительно предпочел использовать BS4, если это возможно.Кто-нибудь знает, как заставить BS4 работать с этим сайтом?

Мой второй вопрос о разбиении на страницы на этом сайте.В нижней части URL-адреса есть кнопка «Загрузить еще», которая отправляет запрос в API, который затем загружает следующую партию продуктов.Тем не менее, URL никогда не меняется.Может ли кто-нибудь помочь мне перебрать партии, чтобы можно было получить все продукты, а не только первые 60?

Я пробовал что-то подобное, измененное из скрипта другого сайта, который также не имеет нумерации страниц в URL:

url = "https://www.eastbay.com/category/mens/shoes.html?query=%3Arelevance%3Agender%3A200000%3AproductType%3A200005%3Abrand%3AChampion%3Abrand%3AConverse%3Abrand%3AFila%3Abrand%3AJordan%3Abrand%3ANew+Balance%3Abrand%3ANike%3Abrand%3ANike+SB%3Abrand%3APUMA%3Abrand%3AReebok%3Abrand%3ASalomon%3Abrand%3AThe+North+Face%3Abrand%3ATimberland%3Abrand%3AUGG%3Abrand%3AUnder+Armour%3Abrand%3AVans%3Abrand%3Aadidas%3Abrand%3Aadidas+Originals"

qsp = {
    'currentPage': 1,
    'pageSize': 100,
    'timestamp': 3
}

container = []


for page_content in range(0,1500,60):
    qsp['currentPage'] = page_content
    res = requests.get(url,params=qsp,headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"})
    soup = BeautifulSoup(res.text, 'lxml')
    for item in soup.select(".c-product-card a"):
        container.append("https://www.eastbay.com"+item['href'])

    for items in soup.select("script"):
        sauce = BeautifulSoup(items.text,"lxml")
        for elem in sauce.select(".c-product-card a"):
            container.append("https://www.eastbay.com"+elem['href'])

print(container)

, но это приводит либо к пустому списку, либо просто застревает.

Я проверил вкладку XHR и Fetch на вкладке Network в инструментах Chrome Dev, и я могу видеть, какой тип запроса нажимает кнопка «Загрузить еще», но я не понимаю, когда речь идет оПередача параметров строки запроса для итерации по партиям продуктов.

Любая помощь очень ценится.

1 Ответ

1 голос
/ 18 апреля 2019

У вас была правильная идея с XHR.Вот как вы можете получить его, а затем выполнить итерацию по этому формату json, чтобы распечатать нужные выходные данные:

import requests

url = 'https://www.eastbay.com/api/products/search'

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'}

payload = {
'query': ':relevance:sport:Casual:gender:200000:productType:200005',
'currentPage': '1',
'pageSize': '200',
'timestamp': '4'}

jsonData = requests.get(url, headers=headers, params=payload).json()

totalPages = jsonData['pagination']['totalPages']
totalResults = jsonData['pagination']['totalResults']

print ('%s total results to aquire' %totalResults)


for page in range(1,totalPages+1):
    payload = {
            'query': ':relevance:sport:Casual:gender:200000:productType:200005',
            'currentPage': page,
            'pageSize': '200',
            'timestamp': '4'}


    jsonData = requests.get(url, headers=headers, params=payload).json()

    try:
        for product in jsonData['products']:
            print (product['name'])
    except:
        print ('Products not found on this request')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...