очистка python selenium из нескольких списков href

#python #selenium-webdriver #web-scraping

#python #selenium-webdriver #очистка веб-страниц

Вопрос:

Это URL для тестирования https://stockx.com/puma?prices=300-400 ,200-300amp;size_types= мужчины и годы = 2017

Я могу извлечь все href ссылки на страницу с подробным описанием продукта, однако в конце я получаю только один результат. Предполагается, что он переходит по всем ссылкам и извлекает мне имя и URL-адрес img. Чего мне здесь не хватает?

Текущий результат вывода в формате json

 [
    {
        "product_name": "Puma Clyde WWE Undertaker Black",
        "imgurl": "https://stockx.imgix.net/Puma-Clyde-WWE-Undertaker-Black.png?fit=fillamp;bg=FFFFFFamp;w=700amp;h=500amp;auto=format,compressamp;q=90amp;dpr=2amp;trim=coloramp;updated_at=1538080256"
    }
]
  

это рабочий код

 import selenium
import json
import time
import re
import string
import requests
import bs4
from selenium import webdriver
from selenium.webdriver import Firefox
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.select import Select

domain =  'https://stockx.com/puma?prices=300-400,200-300amp;size_types=menamp;years=2017'

def prepare_driver(url):
    options = Options()
    # options.add_argument('-headless')
    driver = webdriver.Chrome(executable_path='/Users/Documents/python/Selenium/bin/chromedriver')
    driver.get(url)
    time.sleep(2)
    wait = WebDriverWait(driver, 10).until(EC.presence_of_element_located(
        (By.CLASS_NAME, 'title-container')))
    return driver

def fill_form(driver, search_argument):
    '''Finds all the input tags in form and makes a POST requests.'''
    #search_field = driver.find_element_by_id('q')
    #search_field.send_keys(search_argument)
    # We look for the search button and click it
    #driver.find_element_by_class_name('search__submit')
        #.click()
    wait = WebDriverWait(driver, timeout=10).until(
        EC.presence_of_all_elements_located(
            (By.CLASS_NAME, 'title-container')))
def scrape_results(driver, n_results):
    '''Returns the data from n_results amount of results.'''

    product_urls = list()
    product_data = list()

    for product_title in driver.find_elements_by_css_selector("div[class*='tile browse-tile']"):
        product_urls.append(product_title.find_element_by_css_selector(
            "a[href*='/']").get_attribute('href'))
    print(*product_urls, sep = "n")
    for url in range(0, n_results):
        if url == n_results:
            break
        url_data = scrape_product_data(driver, product_urls[url])
        product_data.append(url_data)
        #print(*product_data, sep = "n")
        return product_data

def scrape_product_data(driver, product_url):
    '''Visits an product page and extracts the data.'''

    if driver == None:
        driver = prepare_driver(product_url)

    driver.get(product_url)
    time.sleep(12)

    product_fields = dict()
    # Get the product name
    product_fields['product_name'] = driver.find_element_by_xpath(
    '//div[@class="col-md-12"]/h1').text

    # Get the image url
    product_fields['imgurl'] = driver.find_element_by_xpath(
    '//img[@class="product-image"]').get_attribute('src')
    return product_fields

if __name__ == '__main__':

    try:
        driver = prepare_driver(domain)
        #fill_form(driver, 'juniole tf')
        product_data = scrape_results(driver, 4)
        product_data = json.dumps(product_data, indent=4) #ensure_acii => changes japanese to correct character
        with open('booking_data_stockx.json', 'w') as f:
            f.write(product_data)
    finally:
        driver.quit()
  

Комментарии:

1. Я не запускал код, но я думаю, что это связано с областью видимости. Вы не добавляете следующий элемент в свой dict(), вы перезаписываете его каждый раз, когда находите элемент.

2. это странно, потому что я сделал то же самое с другим веб-сайтом, и это сработало нормально. Также было бы неплохо посмотреть, сможет ли кто-нибудь запустить код, когда у них будет время, и посмотреть, сможет ли кто-нибудь решить это.

3. почему вы не можете взять URL-адрес img и названия продуктов с первой страницы. Чем отличается от страниц, которые вы посещаете?

4. У меня есть другие данные, которые доступны только на страницах сведений о продукте. Я сначала тестирую его с базовой информацией, прежде чем разрабатывать более сложный код.

Ответ №1:

Я думаю, вы можете сделать все это с помощью запросов. Я выбрал несколько случайных элементов из посещенных страниц, чтобы подтвердить посещаемость.

 import requests
from bs4 import BeautifulSoup as bs
import pandas as pd
baseURL = 'https://stockx.com'
final = []
with requests.Session() as s:
    res = s.get('https://stockx.com/puma?prices=300-400,200-300amp;size_types=menamp;years=2017')
    soup = bs(res.content, 'lxml')
    items  = soup.select('#products-container [href]')
    titles = [item['id'] for item in items]
    links = [baseURL   item['href'] for item in items]
    results = list(zip(titles, links))
    df = pd.DataFrame(results) 
    for result in results:
        res = s.get(result[1])
        soup = bs(res.content, 'lxml')
        details = [item.text for item in soup.select('.detail')]
        final.append([result[0], result[1], details])
df2 = pd.DataFrame(final)
df2.to_csv(r'C:UsersUserDesktopdata.csv', sep=',', encoding='utf-8',index = False )
  

Комментарии:

1. большое вам спасибо и вау, я не знал, что этот метод намного проще и короче. Я хотел бы подробнее остановиться на вашей работе. Если я могу попросить немного больше информации для очистки. Как бы я получил информацию в этом контейнере? details = [item.text for item in soup.select('.pinfo-container')] . Кроме того, каков наилучший способ выгрузить эту информацию в формате csv, json или text?

2. привет, сейчас я посмотрю. Какую информацию вы хотели?

3. привет, Qharr, действительно ценю ваше время. Эта информация приведена на странице сведений о продукте. СТИЛЬ 364669-04 COLORWAY ЧЕРНЫЙ / ЗОЛОТОЙ РОЗНИЧНАЯ ЦЕНА $ 500 ДАТА ВЫПУСКА 2017-04-01

4. с какого URL-адреса вы это извлекли, пожалуйста?

5. еще раз большое вам спасибо за помощь здесь. Для всех, кто посещает эту тему, мой первоначальный план состоял в использовании selenium, но использовать requests было намного проще для моих целей. Надеюсь, это поможет.