如何处理加载更多按钮?

问题描述 投票:0回答:1

我有关于加载更多按钮的问题。页面需要做这样一个“路线图”:进入搜索页面,一一“查看”产品,点击它们,然后返回搜索页面。我的方法是单击“加载更多”按钮,直到它不再存在,然后将其废弃。但是当转到drive.back()时,它不再是同一页面,并且我所做的自动滚动丢失了,它根本不渲染所有产品。另外,通过手动方法,我发现,例如,如果我单击“加载更多”按钮,选择此“其他页面”的一个产品,单击它,那么当我返回搜索页面时,它不会返回到上一页,我需要再次单击“加载更多”按钮。我想到的一种方法是使用 JSON 获取它,但问题是:在我的代码中,用户将自定义搜索,因此它将是不同的页面,永远不会相同。所以指向 json 的 url 总是会改变。怎样制作呢?无论如何,这是代码:


def extrai_dados_prodirectsports():
    print("entrou")
    url_linha = "https://www.prodirectsport.com/soccer/l/adults/departments-boots/activity-football/brand-adidas/silo-predator/"
    data_planilha = []
    data_pdf = []
    tamanhos = []

    cotacao_libra()  # Supondo que essa função já esteja definida
    i = 0
    driver.get(url_linha)
    
    #Cookies
    WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.XPATH,"//button[@title='Accept all cookies']"))).click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH,"//div[@id='zonos']")))
    botao_close = driver.find_element(By.XPATH, "//a[@class = 'z-close']")
    driver.execute_script("arguments[0].click();",botao_close)
    #WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.XPATH,"//div[@class='global-popup']")))
    botao = driver.find_element(By.XPATH,"//button[@aria-label='Close']")
    driver.execute_script("arguments[0].click();",botao)
    #driver.implicitly_wait(500000)
            
   
    df_planilha = pd.DataFrame(columns=COLUNAS_PLANILHA)
    #pdf = FPDF()
    #pdf.add_page()
    #pdf.set_font('Arial', 'B', 12)
    
    x = 0 
    driver.maximize_window()
    produtos_lista = WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[@class = 'product-listing__grid']//div[@class = '_root_129ai_6 product-listing__grid-item']/a")))
    produtos_container = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//div[@class = 'product-listing__grid']")))#driver.execute_script("arguments[0].scrollIntoView();", produtos_lista)
    while True:
        try:
        # Reencontrar o botão dentro do loop para evitar stale element
            botao_vermais = WebDriverWait(driver, 20).until(
                    EC.presence_of_element_located((By.XPATH, "//div[@class='product-listing__view-more']/button"))
                    )

            if botao_vermais.is_displayed():
                driver.execute_script("arguments[0].scrollIntoView();", botao_vermais)
                driver.execute_script("arguments[0].click();", botao_vermais)
                
                x += 1
                print(x)
            else:
                driver.execute_script("arguments[0].scrollIntoView();", produto_container)
                break  # Sai do loop se o botão não for mais exibido
        except StaleElementReferenceException:
            print("Elemento 'Ver mais' tornou-se stale, reencontrando o botão...")
            continue  # Tenta novamente o loop
        except TimeoutException:
            print("Tempo esgotado esperando o botão 'Ver mais'.")
            break
        
    pagina_atual = driver.current_url
            
    for index, value in enumerate(produtos_lista):
        
        driver.get(pagina_atual)
        
        produtos_lista = WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[@class = 'product-listing__grid']//div[@class = '_root_129ai_6 product-listing__grid-item']/a")))    
        driver.execute_script("arguments[0].scrollIntoView();", produtos_lista[index])
        time.sleep(10)
        driver.save_screenshot("janela.png")
        imagem_element = WebDriverWait(driver, 50).until(EC.presence_of_element_located((By.TAG_NAME, "img")))
        imagem = imagem_element.get_attribute("src")
        i += 1
        print(i)
        #actions.move_to_element(produtos_lista[index]).perform()
        driver.execute_script("arguments[0].click();", produtos_lista[index])
        time.sleep(10)
        driver.save_screenshot("projetoecommerce/screenshots_produtos/prodirectsports/" + str(i) +".png")
        nome_produto = WebDriverWait(driver, 1000).until(EC.visibility_of_element_located((By.CLASS_NAME, "ml-meta__title"))).text
        print(nome_produto)
        preco = WebDriverWait(driver, 1000).until(EC.visibility_of_element_located((By.CLASS_NAME, "ml-prices__price"))).text
        preco = re.sub("£", "", preco)
        preco_produto = float(preco) 
        print(preco_produto)
        codigo_produto = driver.current_url.split('-')[-1]
        print(codigo_produto)
        lista_tamanhos = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CLASS_NAME,  "ml-size__sizes")))
            
        if lista_tamanhos:
            driver.execute_script("arguments[0].scrollIntoView();", lista_tamanhos)
            for tamanho in lista_tamanhos.find_elements(By.XPATH, "//button[@class='ml-size__size qa-size-item']"):
                tamanho_produto = tamanho.text
                tamanhos.append(tamanho_produto)
                if "-" in tamanho.text:
                    tamanho_produto = tamanho.text.split('-')[0] 
                    tamanhos.append(tamanho_produto)
                elif "(" in tamanho.text:
                    tamanho_produto = tamanho.text.split('(')[0]
                    tamanhos.append(tamanho_produto)
                else:
                    tamanho_produto = ""
                    tamanhos.append(tamanho_produto)
            print(tamanhos)

        preco_reais = calcula_preco_reais(preco_produto)  # Função precisa estar definida
        preco_venda = calcula_preco_venda(preco_produto)  # Função precisa estar definida

        data_planilha.append({
            'Photo': imagem,
            'Código': codigo_produto,
            'Descrição': nome_produto,
            'Compra': preco_reais,
            'Venda': preco_venda,
            'Tamanhos': tamanhos
            })
        
        driver.back()   
        #driver.execute_script("window.history.go(-1)")
        
        time.sleep(5)
            
            #driv
    figura = gera_pdf(data_pdf)
    df_planilha = pd.DataFrame(data_planilha)
    df_planilha.to_excel(url_linha + "catalogo.xlsx")    

还有什么其他方法呢?如果我逐个产品进行搜索,然后在返回时单击“加载更多”,那么当我返回搜索页面时根本没有单击它,它仍然会出现。在我看来,json 抓取是最好的方法,但是我怎样才能获得它的确切 url 呢?实际上,url_line是该方法的一个参数,程序将从txt文件中读取它。我把它拿出来给你测试一下。

python selenium-webdriver web-scraping
1个回答
0
投票

如果这是您想要的,您可以检查一下吗? (我看到你谈论 JSON URL)

我使用这个API端点

https://www.prodirectsport.com/api/v1/search?location=%2Fsoccer%2Fl%2Fadults%2Fdepartments-boots%2Factivity-football%2Fbrand-adidas%2Fsilo-predator%2F%3Fpg%3D1
来获取这些信息

代码:

import requests
import pandas as pd

image = []
name = []
currentPrice = []
originalPrice = []
colors = []
baseColor = []

for i_s in range(1,7): #Your target endoint has 7 page
    url = f'https://www.prodirectsport.com/api/v1/search?location=%2Fsoccer%2Fl%2Fadults%2Fdepartments-boots%2Factivity-football%2Fbrand-adidas%2Fsilo-predator%2F%3Fpg%3D{i_s}'

    header = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/130.0"  
    }

    resp = requests.get(url, headers=header).json()
    product_list = resp['products']
    for num, i in enumerate(product_list):
        name.append(i['name'])
        image.append(i['media']['thumbnail'])
        currentPrice.append(i['pricing']['current'])
        originalPrice.append(i['pricing']['original'])
        colors.append(i['attributes']['colourway'])
        baseColor.append(i['attributes']['baseColour'])
        print(f"------------------------\nName: {i['name']}\nImage: {i['media']['thumbnail']}\nOriginal price: {i['pricing']['original']}\nCurrent price: {i['pricing']['current']}\nColors: {i['attributes']['colourway']}\nBase color: {i['attributes']['baseColour']}")

get_dict = {
    'Name': name,
    'Image': image,
    'Current Price': currentPrice,
    'Original Price': originalPrice,
    'Colors Available': colors,
    'Base Color': baseColor
}
df_planilha = pd.DataFrame(get_dict)
df_planilha.to_excel("catalogo.xlsx", index=False)

示例输出:

------------------------
Name: adidas Predator x Bellingham Elite Tongue FG
Image: https://images.prodirectsport.com/ProductImages/Main/1018916_Main_1871592.jpg
Original price: 250.0
Current price: 250.0
Colors: Core Black/Core Black/Gold Met
Base color: Black
------------------------
Name: adidas Predator x Bellingham League Tongue FG
Image: https://images.prodirectsport.com/ProductImages/Main/1018917_Main_1876537.jpg
Original price: 90.0
Current price: 90.0
Colors: Core Black/Gold Met/Core Black
Base color: Black
------------------------
Name: adidas Predator Sala IN
Image: https://images.prodirectsport.com/ProductImages/Main/1018835_Main_1861766.jpg
Original price: 50.0
Current price: 50.0
Colors: Aurora Black/Turbo/Gum 3
Base color: Black
------------------------
Name: adidas Predator Elite Tongue SG
Image: https://images.prodirectsport.com/ProductImages/Main/1018814_Main_1865133.jpg
Original price: 240.0
Current price: 240.0
Colors: Platin Met/Aurora Black/Carbon
Base color: Grey
------------------------
Name: adidas Predator Elite Tongue FG
Image: https://images.prodirectsport.com/ProductImages/Main/1018813_Main_1865332.jpg
Original price: 240.0
Current price: 240.0
Colors: Platin Met/Aurora Black/Carbon
Base color: Grey

如果我错过了什么,请告诉我

© www.soinside.com 2019 - 2024. All rights reserved.