Проблема, когда вы соскабливаете немного СКРЕБКА и конвейера с MONGODB

#python #mongodb #web-scraping #scrapy

Вопрос:

Я пытаюсь очистить этот сайт https://www.vivareal.com.br/aluguel/sp/sao-jose-dos-campos/apartamento_residencial/. Это сайт реального штата, но по той же причине, когда начинает менять страницы, получает только одни и те же данные, я действительно не знаю, что происходит. Кто-нибудь может мне помочь, пожалуйста?

init.py

 import scrapy

from realstatedata.items import RealstatedataItem

class RsdataSpider(scrapy.Spider):
    name = 'realstatedata'
    allowed_domains = ['vivareal.com.br']
    start_urls = ['https://www.vivareal.com.br/aluguel/sp/sao-jose-dos-campos/apartamento_residencial/']

    def parse(self, response):
        nextpageurl = response.xpath('//a[@title="Próxima página"]/@href')
        yield from self.scrape(response)

        if nextpageurl:
            path = nextpageurl.extract_first()
            #print(path)
            # Got #pagina=2   =>    Replace with ?pagina=2
            path = '?'   path[1:]
            #print(path)
            nextpage = response.urljoin(path)
            print("Found url: {}".format(nextpage))
            yield scrapy.Request(nextpage)

    def scrape(self, response):
        for resource in response.xpath('//article[@class="property-card__container js-property-card"]/..'):

            item = RealstatedataItem()

            item['description'] = resource.xpath('.//h2/span[@class="property-card__title js-cardLink js-card-title"]/text()').extract_first().strip().lower()
            item['address'] = resource.xpath('.//span[@class="property-card__address"]/text()').extract_first().strip().lower()
            item['prop_area'] = resource.xpath('.//span[@class="property-card__detail-value js-property-card-value property-card__detail-area js-property-card-detail-area"]/text()').extract_first().strip()
            item['prop_rooms'] = resource.xpath('.//span[@class="property-card__detail-value js-property-card-value"]/text()').extract_first().strip()
            item['prop_bath'] = resource.xpath('.//span[@class="property-card__detail-value js-property-card-value"]/text()').extract_first().strip()
            item['prop_parking'] = resource.xpath('.//ul/li[4]/span[@class="property-card__detail-value js-property-card-value"]/text()').extract_first().strip()
            item['price_rent'] = resource.xpath('.//p[@style="display: block;"]/text()').extract_first().strip().replace('R

settings.py

 BOT_NAME = 'realstatedata'

SPIDER_MODULES = ['realstatedata.spiders']
NEWSPIDER_MODULE = 'realstatedata.spiders'

ITEM_PIPELINES = {'realstatedata.pipelines.MongoPipeline':100, }

MONGO_URI = 'mongodb://localhost:27017'
MONGO_DATABASE = "vivareal_db"


# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32

# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16

# Disable cookies (enabled by default)
#COOKIES_ENABLED = False

# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False

# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
#   'Accept': 'text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8',
#   'Accept-Language': 'en',
#}

# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
#    'realstatedata.middlewares.RealstatedataSpiderMiddleware': 543,
#}

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
#    'realstatedata.middlewares.RealstatedataDownloaderMiddleware': 543,
#}

# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': None,
#}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
#ITEM_PIPELINES = {
#    'realstatedata.pipelines.RealstatedataPipeline': 300,
#}

# Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False

# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = [301,302]
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
 

pipeline.py

 import logging
import pymongo

class MongoPipeline(object):

    collection_name = 'rent_properties'

    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls, crawler):
        ## pull in information from settings.py
        return cls(
            mongo_uri=crawler.settings.get('MONGO_URI'),
            mongo_db=crawler.settings.get('MONGO_DATABASE')
        )

    def open_spider(self, spider):
        ## initializing spider
        ## opening db connection
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    def close_spider(self, spider):
        ## clean up when spider is closed
        self.client.close()

    def process_item(self, item, spider):
        ## how to handle each post
        #self.db[self.collection_name].insert(dict(item))
        #self.db[self.collection_name].insert_one(ItemAdapter(item).asdict())
        self.db[self.collection_name].update({'address': item['address']}, dict(item), upsert=True)
        logging.debug("Properties added to MongoDB")
        return item
 

items.py

 import scrapy

class RealstatedataItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    description = scrapy.Field()
    address = scrapy.Field()
    prop_area = scrapy.Field()
    prop_rooms = scrapy.Field()
    prop_bath = scrapy.Field()
    prop_parking = scrapy.Field()
    price_rent = scrapy.Field()
    price_cond = scrapy.Field()
    realstate_name = scrapy.Field()

    pass
 

Ответ №1:

Разбиение на страницы основано на javascript. Scrapy ведет себя аналогично другим http-клиентам, таким как requests , httpx . Он не поддерживает javascript. Вам нужно перехватить запрос и обработать его в некоторых браузерах, таких как безголовый Chrome, Splash. Учитывая совместимость, лучшим решением является использование браузера Chrome без головы и управление им с помощью scrapy-драматурга.

Других вариантов вам следует избегать

  • царапающий всплеск. Всплеск поддерживается организацией Scrapy. Но этот легкий браузер использует движок Webkit, который ведет себя по-другому с такими популярными браузерами, как Firefox, Chrome. Многие сайты неправильно отображаются с помощью Splash.
  • лоскутно-селеновый или лоскутно-безголовый.
    1. эти плагины используют Селен, который является синхронным.
    2. эти плагины создавали пользовательские Request и неправильно кодировали маринование. Обычай Request нарушается после того, как он выскочил из внутренней очереди Scrapy.

, '')
item['price_cond'] = resource.xpath('.//strong[@class="js-condo-price"]/text()').extract_first()
item['realstate_name'] = resource.xpath('.//picture/img/@alt').extract_first().strip().lower()

yield item
settings.py


pipeline.py


items.py


Ответ №1:

Разбиение на страницы основано на javascript. Scrapy ведет себя аналогично другим http-клиентам, таким как requests , httpx . Он не поддерживает javascript. Вам нужно перехватить запрос и обработать его в некоторых браузерах, таких как безголовый Chrome, Splash. Учитывая совместимость, лучшим решением является использование браузера Chrome без головы и управление им с помощью scrapy-драматурга.

Других вариантов вам следует избегать

  • царапающий всплеск. Всплеск поддерживается организацией Scrapy. Но этот легкий браузер использует движок Webkit, который ведет себя по-другому с такими популярными браузерами, как Firefox, Chrome. Многие сайты неправильно отображаются с помощью Splash.
  • лоскутно-селеновый или лоскутно-безголовый.
    1. эти плагины используют Селен, который является синхронным.
    2. эти плагины создавали пользовательские Request и неправильно кодировали маринование. Обычай Request нарушается после того, как он выскочил из внутренней очереди Scrapy.