我正在从已发布的属性列表中抓取信息。当我运行代码时,页面似乎有一个反抓取系统。
代码应该打开每个属性的链接,抓取我需要的数据,然后移动到下一个。我以前的问题是它没有从每个页面抓取所有数据,但现在它不会打开页面,因为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")
字符串
2条答案
按热度按时间jecbmhm31#
在 * 正常 * 情况下无法解决此错误。您已与服务器正确通信-它只是不想与您一起工作。更正式的说法是“the HTTP 403 Forbidden response status code indicates that the server understands the request but refuses to authorize it.“
需要注意的一点是,如果您在浏览器中访问该链接,并且没有收到错误,但在使用脚本时收到错误,则可能是
User Agent
问题。如果是这种情况,则需要更改以下内容:首先,创建你的header:
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)
xtupzzrd2#
尝试通过Chrome浏览器访问目标网站,查看哪些标头正在使用各个请求类型发送,然后使用Scrapy添加它们。通常,单个标头元素可以解决问题,无需进一步调试。