Muszę przebierać elementy, które są ograniczone przez nagłówki. Walczę ze sformułowaniem wyrażenia XPATH lub prostego parsera, który może grupować moje elementy w sekcje podane przez zmienność.

Rozumiem, jak zeskrobać listy, w których elementy znajdują się na tym samym poziomie lub poziom elementu podaje się przez pojemnik, ale zmagam się, aby dowiedzieć się, jak przeanalizować dane, w których pojemniki są ograniczone przez elementy. Na przykład:

<div>
<h1>section a</h1>
<item>221</item>
<item>453</item>
<item>473</item>
<h1>section b</h1>
<item>430</item>
<item>493</item>
<h1>section c</h1>
<item>694</item>
<item>931</item>
</div>

Czy istnieje jakiś paradygmatyczny sposób, aby zwrócić uwagę na strukturę za pomocą XPath? Czy istnieje sposób, aby zwarzyć Selekcjonerów przewijania, dzięki czemu widzę widok Domu i wykrywanie rozpoczęcia i zatrzymania tych sekcji?

1
Mikhail 12 sierpień 2014, 12:03

2 odpowiedzi

Najlepsza odpowiedź

Jednym rozwiązaniem przy użyciu XPath jest liczenie poprzedniego h1 rodzeństwa węzłów pod div, węzły, które same nie są h1

$ ipython
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
Type "copyright", "credits" or "license" for more information.

IPython 1.2.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import scrapy

In [2]: selector = scrapy.Selector(text="""
<div>
<h1>section a</h1>
<item>221</item>
<item>453</item>
<item>473</item>
<h1>section b</h1>
<item>430</item>
<item>493</item>
<h1>section c</h1>
<item>694</item>
<item>931</item>
</div>""")

In [3]: for i, header in enumerate(selector.xpath('.//div/h1'), start=1):
    print header.xpath('normalize-space()').extract()
    between = selector.xpath(""".//div/node()[count(preceding-sibling::h1)=%d]
                                             [not(self::h1)]""" % i)
    print between.extract()
   ...:     
[u'section a']
[u'\n', u'<item>221</item>', u'\n', u'<item>453</item>', u'\n', u'<item>473</item>', u'\n']
[u'section b']
[u'\n', u'<item>430</item>', u'\n', u'<item>493</item>', u'\n']
[u'section c']
[u'\n', u'<item>694</item>', u'\n', u'<item>931</item>', u'\n']
2
paul trmbrth 12 sierpień 2014, 09:24
var header = null
var items = []

for each element in div
    if element is header
        process previous header, items
        header = the element text
        items = []
    else
        items append element text
end
process last header, items
0
xfx 12 sierpień 2014, 08:12