Scrapy: оптимизация паука



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



Этот сайт имеет такую структуру:




  • на главной странице есть ссылки на страницы "семья-предметы" и "подсемейство-предметы"

  • каждая страница семейства и подсемейства содержит список продуктов, разбитых на страницы


Прямо сейчас у меня есть 2 паука:





  • GeneralSpider чтобы получить ссылки на домашнюю страницу и сохранить их


  • ItemSpider для получения элементов из каждого Страница


Я совершенно новичок в Scrapy, я следую некоторым учебникам, чтобы достичь этого. Мне интересно, насколько сложными могут быть функции синтаксического анализа и как работают правила. Мои пауки прямо сейчас выглядят так:



GeneralSpider:



class GeneralSpider(CrawlSpider):

name = 'domain'
allowed_domains = ['domain.org']
start_urls = ['http://www.domain.org/home']

def parse(self, response):
links = LinksItem()
links['content'] = response.xpath("//div[@id='h45F23']").extract()
return links


ItemSpider:



class GeneralSpider(CrawlSpider):

name = 'domain'
allowed_domains = ['domain.org']
f = open("urls.txt")
start_urls = [url.strip() for url in f.readlines()]
# Each URL in the file has pagination if it has more than 30 elements
# I don't know how to paginate over each URL
f.close()

def parse(self, response):
item = ShopItem()
item['name'] = response.xpath("//h1[@id='u_name']").extract()
item['description'] = response.xpath("//h3[@id='desc_item']").extract()
item['prize'] = response.xpath("//div[@id='price_eur']").extract()
return item



  • , который является лучшим способом, чтобы паук последующих страниц url-адрес ?


  • Если пагинация JQuery , то есть нет GET переменной в URL, можно было бы следить за пагинацией ?



  • Можно мне по-другому?" правила" в одном и том же пауке ломать разные части страницы ? или лучше, чтобы пауки специализировались , каждый паук был сосредоточен на чем-то одном?



Я также искал в гугле любую книгу, связанную со Скрэпи, но, похоже, еще нет ни одной законченной книги, или, по крайней мере, я не смог найти ее.




  • кто-нибудь знает, если какая-нибудь Скрэппи книга, которая будет скоро освободят ?


Правка:



Этот 2 URL-адрес подходит для этого примера. На странице Eroski Home вы можете получить URL-адрес страницы products.



На странице товаров у вас есть список товаров, разбитых на страницы (Eroski Items):




На странице Eroski Fruits разбиение элементов на страницы выглядит как JQuery / AJAX, потому что при прокрутке вниз отображается больше элементов, есть ли способ получить все эти элементы с помощью Scrapy ?

529   1  

1 ответ:

Какой лучший способ заставить паука следовать за пагинацией url-адреса ?

Это очень специфично для сайта и зависит от того, как реализована пагинация.

Если разбиение на страницы является JQuery, то есть в URL нет переменной GET, можно ли следовать разбиению на страницы ?

Это именно ваш вариант использования-разбиение на страницы производится с помощью дополнительных вызовов AJAX, которые вы можете имитировать внутри вашего Scrapy spider.

Могу ли я иметь разные "правила" в одном и том же пауке, чтобы очистить разные части страницы ? или лучше, чтобы пауки специализировались, каждый паук был сосредоточен на чем-то одном?

Да, механизм "правил", который предоставляет CrawlSpider, является очень мощным элементом технологии - он легко настраивается - у вас может быть несколько правил, некоторые из них будут следовать определенным ссылкам, соответствующим определенным критериям, или расположены в определенном разделе страницы. Наличие одного паука с несколькими правилами должно быть предпочтительнее, чем иметь несколько пауков. Говоря о вашем конкретном случае использования, вот идея:
  • сделайте rule, чтобы следить за категориями и подкатегориями в меню навигации домашней страницы - это там restrict_xpaths поможет
  • в обратном вызове для каждой категории или подкатегории yield a Request, который будет имитировать запрос AJAX, отправленный вашим браузером, когда вы открываете страницу категории
  • в обработчике ответа AJAX (callback) проанализируйте доступные элементы и yield другой Request для той же категории / подкатегории, но увеличивающий параметр page GET (получение следующей страницы)

Пример рабочей реализации:

import re
import urllib

import scrapy
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor


class ProductItem(scrapy.Item):
    description = scrapy.Field()
    price = scrapy.Field()


class GrupoeroskiSpider(CrawlSpider):
    name = 'grupoeroski'
    allowed_domains = ['compraonline.grupoeroski.com']
    start_urls = ['http://www.compraonline.grupoeroski.com/supermercado/home.jsp']

    rules = [
        Rule(LinkExtractor(restrict_xpaths='//div[@class="navmenu"]'), callback='parse_categories')
    ]

    def parse_categories(self, response):
        pattern = re.compile(r'/(\d+)\-\w+')
        groups = pattern.findall(response.url)
        params = {'page': 1, 'categoria': groups.pop(0)}

        if groups:
            params['grupo'] = groups.pop(0)
        if groups:
            params['familia'] = groups.pop(0)

        url = 'http://www.compraonline.grupoeroski.com/supermercado/ajax/listProducts.jsp?' + urllib.urlencode(params)
        yield scrapy.Request(url,
                             meta={'params': params},
                             callback=self.parse_products,
                             headers={'X-Requested-With': 'XMLHttpRequest'})

    def parse_products(self, response):
        for product in response.xpath('//div[@class="product_element"]'):
            item = ProductItem()
            item['description'] = product.xpath('.//span[@class="description_1"]/text()').extract()[0]
            item['price'] = product.xpath('.//div[@class="precio_line"]/p/text()').extract()[0]
            yield item

        params = response.meta['params']
        params['page'] += 1

        url = 'http://www.compraonline.grupoeroski.com/supermercado/ajax/listProducts.jsp?' + urllib.urlencode(params)
        yield scrapy.Request(url,
                             meta={'params': params},
                             callback=self.parse_products,
                             headers={'X-Requested-With': 'XMLHttpRequest'})

Надеюсь, что это хорошая отправная точка для вас.


Кто-нибудь знает, есть ли какая-нибудь отрывочная книга, которая скоро выйдет?

Ничего конкретного, что я могу вспомнить.

хотя я слышал, что какой-то издатель планирует выпустить книгу. насчет паутины, но я не должен тебе этого говорить.

Comments

    Ничего не найдено.