抓取网页时出现403错误如何解决?

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

我正在从已发布的属性列表中抓取信息。当我运行代码时,页面似乎有一个防抓取系统。

代码应该打开每个属性的链接,抓取我需要的数据,然后转到下一个。我之前的问题是它没有从每个页面中抓取所有数据,但现在由于 403 错误而无法打开页面。我的代码如下:

import scrapy
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import pandas as pd
import requests  # Asegúrate de tener instalada la librería requests
from bs4 import BeautifulSoup

class ScrapingClubSpider(scrapy.Spider):
    name = "scraping_club"

    # Inicializa un DataFrame y una lista para cada atributo
    data = {"ID": [], "Coordenadas": [], "Region": [], "Comuna": [], "Barrio": [],
            "Precio_UF": [], "Precio_Pesos": [], "Metros_Cuadrados_Totales": [],
            "Metros_Cuadrados_Utiles": [], "Num_Piezas": [], "Num_Baños": [],
            "Captado_Por": [], "Nombre_Captador": [], "Tiempo_Publicado": []}

    def start_requests(self):
        # Pregunta al usuario si es venta o arriendo
        venta_arriendo = input("¿Deseas buscar venta o arriendo? (venta/arriendo): ").lower()

        # Pregunta al usuario el tipo de propiedad
        tipo_propiedad = input("¿Qué tipo de propiedad buscas? (casa/departamento/otro): ").lower()

        # Pregunta al usuario la región
        region = input("¿Qué región buscas? (metropolitana, valparaiso): ").lower()

        # Construye la URL en función de las respuestas
        url = f"https://www.portalinmobiliario.com/{venta_arriendo}/{tipo_propiedad}/propiedades-usadas/{region}"

        # Abre la URL y comienza el scraping
        yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        driver = response.request.meta["driver"]
        wait = WebDriverWait(driver, 10)

        try:
            for page_number in range(1,3):
                # ... (código existente)
                # Espera a que se carguen los productos
                wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".andes-card.ui-search-result.ui-search-result--res.andes-card--flat.andes-card--padding-16.andes-card--animated")))

                for product in driver.find_elements(By.CSS_SELECTOR, ".andes-card.ui-search-result.ui-search-result--res.andes-card--flat.andes-card--padding-16.andes-card--animated"):
                    item = {}
                    item['id'] = product.get_attribute('data-view')  # ID de la propiedad
                    item['coordinates'] = product.get_attribute('data-lat') + ', ' + product.get_attribute('data-lon')  # Coordenadas
                    item['region'] = product.find_element(By.CSS_SELECTOR, ".ui-search-item__location span:nth-child(1)").text  # Región
                    item['comuna'] = product.find_element(By.CSS_SELECTOR, ".ui-search-item__location span:nth-child(3)").text  # Comuna
                    item['barrio'] = product.find_element(By.CSS_SELECTOR, ".ui-search-item__location span:nth-child(5)").text  # Barrio
                    item['price_uf'] = product.find_element(By.CSS_SELECTOR, ".price-tag-fraction").text if product.find_elements(By.CSS_SELECTOR, ".price-tag-fraction") else ''  # Precio en UF
                    item['price_clp'] = product.find_element(By.CSS_SELECTOR, ".ui-search-price__second-line .price-tag-fraction").text if product.find_elements(By.CSS_SELECTOR, ".ui-search-price__second-line .price-tag-fraction") else ''  # Precio en CLP
                    item['total_area'] = product.find_element(By.CSS_SELECTOR, ".ui-search-card-attributes .ui-search-card-attributes__attribute:nth-child(2) span:nth-child(2)").text  # Metros cuadrados totales
                    item['usable_area'] = product.find_element(By.CSS_SELECTOR, ".ui-search-card-attributes .ui-search-card-attributes__attribute:nth-child(3) span:nth-child(2)").text  # Metros cuadrados útiles
                    item['bedrooms'] = product.find_element(By.CSS_SELECTOR, ".ui-search-card-attributes .ui-search-card-attributes__attribute:nth-child(4) span:nth-child(2)").text  # Número de piezas
                    item['bathrooms'] = product.find_element(By.CSS_SELECTOR, ".ui-search-card-attributes .ui-search-card-attributes__attribute:nth-child(5) span:nth-child(2)").text  # Número de baños
                    item['captured_by'] = product.find_element(By.CSS_SELECTOR, ".ui-search-list__item .ui-search-result__content-wrapper .ui-search-item__group .ui-search-item__group--seller .ui-search-item__seller-info .ui-search-item__seller-name").text  # Captado por
                    item['capturer_name'] = product.find_element(By.CSS_SELECTOR, ".ui-search-list__item .ui-search-result__content-wrapper .ui-search-item__group .ui-search-item__group--seller .ui-search-item__seller-info .ui-search-item__seller-subtitle").text  # Nombre del captador
                    item['published_time'] = product.find_element(By.CSS_SELECTOR, ".ui-search-list__item .ui-search-result__content-wrapper .ui-search-item__group .ui-search-item__group--seller .ui-search-item__group--price .ui-search-item__group__element .ui-search-item__highlight-label").text  # Tiempo publicado
                    print(item)
                next_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".andes-pagination__link.ui-search-link")))
                next_button.click()

        except Exception as e:
            print(f"Error general: {str(e)}")

        # Después de iterar todas las páginas, crea un DataFrame y guarda en CSV
        df = pd.DataFrame(self.data)
        df.to_csv("datos_scraping.csv", index=False)
        self.log("Datos guardados exitosamente en datos_scraping.csv")
python web-scraping scrapy web-crawler
1个回答
0
投票

正常情况下您无法解决该错误。您已与服务器正确通信 - 它只是不想与您合作。用更正式的术语来说,“HTTP 403 Forbidden 响应状态代码表示服务器理解该请求,但拒绝授权。

需要注意的一件事是,如果您在浏览器中访问该链接并且没有收到错误,但在使用脚本时收到错误,则可能是一个

User Agent
问题。如果是这种情况,您需要更改以下内容:

首先,创建标题:

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

然后,改变

这个:

yield scrapy.Request(url=url, callback=self.parse)

对此:

yield scrapy.Request(url=url, headers=headers, callback=self.parse)

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