Получение данных со следующей страницы с помощью Scrapy - PullRequest
0 голосов
/ 12 марта 2020

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

Поскольку я использую Scrapy Framework в Jupyter Notebook, это мой код:

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    link = 'https://www.vivareal.com.br/venda/sp/sao-paulo/?pagina={number}#onde=BR-Sao_Paulo-NULL-Sao_Paulo&tipos=apartamento_residencial'

    start_urls = ['https://www.vivareal.com.br/venda/sp/sao-paulo/apartamento_residencial/#onde=BR-Sao_Paulo-NULL-Sao_Paulo&tipos=apartamento_residencial',
                 ]
    for i in range(1,3):
        start_urls.append(link.format(number=i))
        #print(start_urls)

    start_urls = ['https://www.vivareal.com.br/venda/sp/sao-paulo/apartamento_residencial/#onde=BR-Sao_Paulo-NULL-Sao_Paulo&tipos=apartamento_residencial',
                 ]

    custom_settings = {
        'LOG_LEVEL': logging.WARNING,
        'ITEM_PIPELINES': {'__main__.JsonWriterPipeline': 1}, # Used for pipeline 1
        'FEED_FORMAT':'json',                                 # Used for pipeline 2
        'FEED_URI': 'quoteresult.json',                        # Used for pipeline 2
        'CLOSESPIDER_PAGECOUNT': 3
    }



    def parse(self, response):
        display(response.body)
        table_rows = response.css('div.property-card__main-content')  #//*[@id="js-site-main"]/div[2]/div
        for quote in table_rows:
            time.sleep(0.2)
            yield {
               'address': quote.css('span.property-card__address::text').extract_first(),#.re(r'.*'),
               'title': quote.css('a.property-card__title::text').extract_first(),
               'area': quote.css('span.js-property-card-detail-area::text').extract_first(),
               'price': quote.css('div.js-property-card__price-small::text').extract_first(),
               'cond_price': quote.css('strong.js-condo-price::text').extract_first(),
               'bedrooms': quote.css('span.property-card__detail-value::text').extract()[1],
               'bathrooms': quote.css('span.property-card__detail-value::text').extract()[3],
               'amenities': quote.css('.amenities__item::attr(title)').extract(),
               #'pictures': quote.css('div.carousel__item-wrapper::text').extract()[2]
           }

Это Код отлично работает на первой странице с 36 свойствами. Однако, когда он переходит на следующую страницу, веб-сайту требуется некоторое время для обновления содержимого, и я получаю испорченную версию веб-сайта (со смесью свойств с первой страницы и второй).

Я прочитал несколько примеров относительно следующего и дополнил свой код следующим

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    link = 'https://www.vivareal.com.br/venda/sp/sao-paulo/?pagina={number}#onde=BR-Sao_Paulo-NULL-Sao_Paulo&tipos=apartamento_residencial'

    start_urls = ['https://www.vivareal.com.br/venda/sp/sao-paulo/apartamento_residencial/#onde=BR-Sao_Paulo-NULL-Sao_Paulo&tipos=apartamento_residencial',
                 ]
    for i in range(1,3):
        start_urls.append(link.format(number=i))
        #print(start_urls)

    start_urls = ['https://www.vivareal.com.br/venda/sp/sao-paulo/apartamento_residencial/#onde=BR-Sao_Paulo-NULL-Sao_Paulo&tipos=apartamento_residencial',
                 ]

    custom_settings = {
        'LOG_LEVEL': logging.WARNING,
        'ITEM_PIPELINES': {'__main__.JsonWriterPipeline': 1}, # Used for pipeline 1
        'FEED_FORMAT':'json',                                 # Used for pipeline 2
        'FEED_URI': 'quoteresult.json',                        # Used for pipeline 2
        'CLOSESPIDER_PAGECOUNT': 3
    }



    def parse(self, response):
        display(response.body)
        table_rows = response.css('div.property-card__main-content')  #//*[@id="js-site-main"]/div[2]/div
        for quote in table_rows:
            time.sleep(0.2)
            yield {
               'address': quote.css('span.property-card__address::text').extract_first(),#.re(r'.*'),
               'title': quote.css('a.property-card__title::text').extract_first(),
               'area': quote.css('span.js-property-card-detail-area::text').extract_first(),
               'price': quote.css('div.js-property-card__price-small::text').extract_first(),
               'cond_price': quote.css('strong.js-condo-price::text').extract_first(),
               'bedrooms': quote.css('span.property-card__detail-value::text').extract()[1],
               'bathrooms': quote.css('span.property-card__detail-value::text').extract()[3],
               'amenities': quote.css('.amenities__item::attr(title)').extract(),
               #'pictures': quote.css('div.carousel__item-wrapper::text').extract()[2]
           }
# next_page = /page-{}/ where {} number of page.
        next_page = response.xpath('//*[@id="js-site-main"]/div[2]/div/section/div[2]/div[2]/div/ul/li[9]/a').extract_first()

        # next_page = https://sanet.st/page-{}/ where {} number of page.
        next_page = response.urljoin(next_page)

        # If next_page have value
        if next_page:
            # Recall parse with url https://sanet.st/page-{}/ where {} number of page.
            yield scrapy.Request(url=next_page, callback=self.parse)

Однако я получаю только результаты первой страницы и не могу понять, как ограничить количество страниц, которые я получаю, так как у меня есть нет доступа к счетчику l oop. Другими словами, как мне определить, когда это прекратится?

Спасибо вам

1 Ответ

0 голосов
/ 12 марта 2020

Ваша проблема в том, что 2-я и последующие страницы выбираются с использованием API-запросов, которые не html, а json

Попробуйте этот запрос в оболочке Scrapy, чтобы увидеть подробности:

from scrapy import Request

url = 'https://glue-api.vivareal.com/v2/listings?addressCity=S%C3%A3o%20Paulo&addressLocationId=BR%3ESao%20Paulo%3ENULL%3ESao%20Paulo&addressNeighborhood=&addressState=S%C3%A3o%20Paulo&addressCountry=Brasil&addressStreet=&addressZone=&addressPointLat=-23.550519&addressPointLon=-46.633309&business=SALE&facets=amenities&unitTypes=APARTMENT&unitSubTypes=&unitTypesV3=&usageTypes=&listingType=USED&parentId=null&categoryPage=RESULT&includeFields=page%2Csearch%2Cexpansion%2Cnearby%2CfullUriFragments%2Caccount%2Cdevelopments&size=36&from=72&q=&developmentsSize=5&__vt='

headers = {
    "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0",
    "Accept": "application/json, text/javascript, */*; q=0.01",
    "Accept-Language": "en-US,en;q=0.5",
    "x-domain": "www.vivareal.com.br",
    "Origin": "https://www.vivareal.com.br",
    "Connection": "keep-alive",
    "Referer": "https://www.vivareal.com.br/venda/sp/sao-paulo/?pagina=2",
    "TE": "Trailers"
}

request = Request(
    url=url,
    method='GET',
    dont_filter=True,
    headers=headers,
)

fetch(request)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...