From 38f82e39936a018d38a642de50ccbfc424731a64 Mon Sep 17 00:00:00 2001 From: Pablo Hoffman Date: Sun, 9 Aug 2009 18:06:12 -0300 Subject: [PATCH] loaders doc: added information about expanders/reducers declaration precendece, and other minor improvements --- docs/experimental/loaders.rst | 80 ++++++++++++++++++++++++++++------ docs/experimental/newitems.rst | 5 +++ 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/docs/experimental/loaders.rst b/docs/experimental/loaders.rst index f6632832d..017870564 100644 --- a/docs/experimental/loaders.rst +++ b/docs/experimental/loaders.rst @@ -34,8 +34,9 @@ Then, you start adding values to the Loader, typically collecting them using same item field, the Loader will know how to "join" those values later using a Reducer. -Here is a typical Loader usage in a :ref:`Spider ` using the -:ref:`Product item defined in the Items chapter `.:: +Here is a typical Loader usage in a :ref:`Spider `, using the +:ref:`Product item ` declared in the :ref:`Items +section `:: from scrapy.item.loader import XPathLoader from scrapy.xpath import HtmlXPathSelector @@ -47,14 +48,14 @@ Here is a typical Loader usage in a :ref:`Spider ` using the l.add_xpath('name', '//div[@class="product_title"]') l.add_xpath('price', '//p[@id="price"]') l.add_xpath('stock', '//p[@id="stock"]') - l.add_value('last_updated', 'today') # you can also literal values + l.add_value('last_updated', 'today') # you can also use literal values return l.get_item() By quickly looking at that code we can see the ``name`` field is being extracted from two different XPath locations in the page: -* ``//div[@class="product_name"]`` -* ``//div[@class="product_title"]`` +1. ``//div[@class="product_name"]`` +2. ``//div[@class="product_title"]`` In other words, data is being collected by extracting it from two XPath locations, using the :meth:`~XPathLoader.add_xpath` method. This is the data @@ -74,14 +75,15 @@ previously extracted and collected with the :meth:`~XPathLoader.add_xpath` and Expanders and Reducers ====================== -A Loader is composed of one expander and one reducer for each item field. The +A Loader is composed of one expander and one reducer for each (item) field. The Expander processes the extracted data as soon as it's received (through the :meth:`~XPathLoader.add_xpath` or :meth:`~Loader.add_value` methods) and the result of the expander is collected and kept inside the Loader. After collecting all data, the :meth:`Loader.get_item` method is called to actually -populate and get the Item. That's when the Reducers are called with the data -previously collected (using the Expanders) and the output of the Reducers are -the actual values that get assigned to the item. +populate and get the :class:`~scrapy.newitem.Item` object. That's when the +Reducers are called with the data previously collected (using the Expanders) +and the output of the Reducers are the actual values that get assigned to the +item. Let's see an example to illustrate how Expanders and Reducers are called, for a particular field (the same applies for any other field):: @@ -135,6 +137,45 @@ As you can see, expanders are declared using the ``_exp`` suffix while reducers are declared using the ``_red`` suffix. And you can also declare a default expander using the :attr:`Loader.default_expander` attribute. +.. _topics-loader-expred-declaring: + +Declaring Extenders and Reducers +================================ + +As seen in the previous section, extenders and reducers can be declared in the +Loader definition, and it's very common to declare expanders this way. However, +there is one more place where you can specify the exanders and reducers to use: +in the :ref:`Item Field