2015-03-16 3 views
2

Я triyng, чтобы построить скребок с Scapy. Я не понимаю, почему Scrapy не хочет перейти на следующую страницу. Я хочу извлечь ссылку из области разбивки на страницы ... но, увы. Мое правило для извлечения URL-адресов для перехода к следующей страницеКак добраться до следующей страницы?

Rule(LinkExtractor(restrict_xpaths='/html/body/div[19]/div[5]/div[2]/div[5]/div/div[3]/ul',allow=('page=[0-9]*')), follow=True) 

Гусеничный

Class DmozSpider(CrawlSpider): 
    name = "arbal" 
    allowed_domains = ["bigbasket.com"] 
    start_urls = [ 
     "http://bigbasket.com/pc/bread-dairy-eggs/bread-bakery/?nc=cs" 
    ] 

    rules = (
      Rule(LinkExtractor(restrict_xpaths='/html/body/div[19]/div[4]/ul',allow=('pc\/.*.\?nc=cs')), follow=True), 
      Rule(LinkExtractor(restrict_xpaths='/html/body/div[19]/div[5]/div[2]/div[5]/div/div[3]/ul',allow=('page=[0-9]*')), follow=True), 
      Rule(LinkExtractor(restrict_xpaths='//*[@id="products-container"]',allow=('pd\/*.+')), callback='parse_item', follow=True) 
      ) 

    def parse_item(self, response): 
     item = AlabaItem() 
     hxs = HtmlXPathSelector(response) 
     item['brand_name'] = hxs.select('.//*[contains(@id, "slidingProduct")]/div[2]/div[1]/a/text()').extract() 
     item['prod_name'] = hxs.select('//*[contains(@id, "slidingProduct")]/div[2]/div[2]/h1/text()').extract() 
     yield item 
+0

кажется, что сканирование не хочет идти на следующий url beacause, получая относительный url. –

ответ

3

Существует AJAX-стиль нумерации страниц, которые не так легко следовать, но выполнимо.

Использование инструментов разработчика браузера вы можете увидеть, что каждый раз при переключении страниц, есть запрос XHR направляется http://bigbasket.com/product/facet/get-page/ с sid и page параметрами:

enter image description here

Проблема заключается в том, что sid параметр - это это то, что мы выберем из первой ссылки, содержащей sid на странице.

Ответ в формате JSON, содержащий products ключ, который является в основном кодом HTML блока products_container на странице.

Обратите внимание, что CrawlSpider не помогло бы в этом случае. Мы должны использовать регулярный паук и следовать за страницей «вручную».

Еще один вопрос, который у вас может возникнуть: как мы узнаем, сколько страниц потребуется? Идея здесь заключалась бы в том, чтобы извлечь общее количество продуктов на странице с ярлыка «Показывать X-Y продуктов Z» внизу страницы, затем разделите общее количество продуктов на 20 (20 продуктов на страницу).

Реализация:

import json 
import urllib 

import scrapy 


class DmozSpider(scrapy.Spider): 
    name = "arbal" 
    allowed_domains = ["bigbasket.com"] 
    start_urls = [ 
     "http://bigbasket.com/pc/bread-dairy-eggs/bread-bakery/?nc=cs" 
    ] 

    def parse(self, response): 
     # follow pagination 
     num_pages = int(response.xpath('//div[@class="noItems"]/span[@class="bFont"][last()]/text()').re(r'(\d+)')[0]) 
     sid = response.xpath('//a[contains(@href, "sid")]/@href').re(r'sid=(\w+)(?!&|\z)')[0] 

     base_url = 'http://bigbasket.com/product/facet/get-page/?' 
     for page in range(1, num_pages/20 + 1): 
      yield scrapy.Request(base_url + urllib.urlencode({'sid': sid, 'page': str(page)}), dont_filter=True, callback=self.parse_page) 

    def parse_page(self, response): 
     data = json.loads(response.body) 

     selector = scrapy.Selector(text=data['products']) 
     for product in selector.xpath('//li[starts-with(@id, "product")]'): 
      title = product.xpath('.//div[@class="muiv2-product-container"]//img/@title').extract()[0] 
      print title 

Для страницы, установленной в start_urls печатает 281 наименований продукции.

+0

Ok.Это хороший способ. Но если я напечатаю значение этого: 'Rule (LinkExtractor (restrict_xpaths = '/ html/body/div [19]/div [5]/div [2]/div [5]/div [3]/ul ', allow = (' pc \ /.*. \? Nc = cs #! Page = [0-9] * '), process_value = my_process_value), follow = True) 'Я получаю истинные URL-адреса, scrapy не открывает их –

+0

@AleksanderGordienko да, это то, что я пытаюсь сказать - это разбиение на страницы на основе AJAX, и вам приходится иметь дело с ним так, как я предложил..понимаешь, Сань? :) – alecxe

+0

Конечно! Я понимаю ! Спасибо, тезка;) –

Смежные вопросы