2016-01-09 3 views
2

У меня есть страница, на которой я пытаюсь получить цену. Вот загляните на линию.xpath tag не уверен, что положить

<div itemprop="price" class="js-price-display Price Price--flair Price--medium hide-content-m price-display"> <span class="Price-sup">$</span>34<span class="Price-mark">.</span>96 </div>'] 

Я пробовал кучу разных способов получить его, но не дотягиваю. Лучшее, что я получил это 2. (цена составляет $ 34,96, кстати)

selector.xpath('//div[@itemprop="price"]/text()').extract() 

, который дает мне

[u' ', u'34', u' ', u' ', u'34', u'96 '] 

и таким образом

selector.xpath('//div[@class="js-price-display Price Price--flair Price--medium hide-content-m price-display"]').extract() 

, который дает мне этот результат

[u'<div itemprop="price" class="js-price-display Price Price--flair Price--medium hide-content-m price-display"> <span class="Price-sup">$</span>34<span class="Price-mark">.</span>96 </div>'] 

Если у меня есть только спа n он дает мне $ и. но я не знаю, что этот атрибут (или свойство или ценность или что-то еще) его называют «после» пролета там в конце, где фактическая сумма. Я хотел бы получить первую часть, период и вторую часть, но я возьму что-нибудь лучше, чем то, что у меня есть. Наконец, я запустил этот бит тестового кода, чтобы увидеть свойства куска веб-страницы, которую я там разместил. Вот что я запустил

for item in selector.xpath('.//*[@itemprop]'): 
    print "Item:", item.xpath('@itemtype').extract() 
    for property in item.xpath('.//*[@itemprop]'): 
     print "Property:", 
     print property.xpath('@itemprop').extract(), 
     print property.xpath('string(.)').extract() 
     for position, attribute in enumerate(property.xpath('@*'), start=1): 
      print "attribute: name=%s; value=%s" % (
       property.xpath('name(@*[%d])' % position).extract(), 
       attribute.extract()) 
     print 
    print 

и получил эти результаты.

C:\Python27\bff\bff\spiders>python test.py 
Item: [u'http://schema.org/Offer'] 
Property: [u'priceCurrency'] [u''] 
attribute: name=[u'itemprop']; value=priceCurrency 
attribute: name=[u'content']; value=USD 

Property: [u'price'] [u' $34.96 '] 
attribute: name=[u'itemprop']; value=price 
attribute: name=[u'class']; value=js-price-display Price Price--stylized Price--large hide-content display-inline-m price-display 

Property: [u'price'] [u' $34.96 '] 
attribute: name=[u'itemprop']; value=price 
attribute: name=[u'class']; value=js-price-display Price Price--flair Price--medium hide-content-m price-display 

Property: [u'availability'] [u''] 
attribute: name=[u'itemprop']; value=availability 
attribute: name=[u'itemtype']; value=http://schema.org/ItemAvailability 
attribute: name=[u'content']; value=InStock 

Как это похоже на БУМ, точно так же, как мне нужно, чтобы показать, и я не могу его получить? Я попытался использовать оба этих класса и обе эти значения itemprop и продолжать получать материал, похожий на то, что я разместил. Заранее спасибо за помощь.

ответ

2

Используя /text(), вы получите только текстовые узлы, которые являются прямым дочерним элементом текущего элемента контекста.И используя //text(), вы получите все текстовые узлы в текущем контекстном элементе, либо прямое дочерние, либо вложенные, но отдельные тексты будут возвращены в виде отдельных текстовых узлов.

Что вам нужно, чтобы найти div элементы, а затем вызвать XPath string() функцию на каждом div, это то, что ваш тестовый код сделать, чтобы вывести ожидаемое значение. Если есть только один div в то время, то следующий XPath также будет работать:

selector.xpath('string(//div[@itemprop="price"])').extract() 

В противном случае вам нужно петлю через div элементов, а затем вызвать string() в теле for цикла.

+0

Пригвожден! Я получал все в теге, но не знал, что его изменение в строку будет обрезать только текст! Спасибо, что помог мне сохранить разум. – Nick

2

Попробуйте

//div[@itemprop='price']//text() 

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

Я не использовал Scrapy, но если ваша функция просто возвращает список, вы должны быть в состоянии использовать

''.join(resultlist) 

положить, что вместе в одно выражение тогда.

Если вы хотите, чтобы попытаться получить только цену, без знака доллара, вы можете также использовать

//div[@itemprop='price']/descendant-or-self::*[not(@class='Price-sup')]/text() 

Это будет работать, пока ничто не более чем на один уровень за DIV (не пытайтесь этот двойной косой черт здесь, или он будет идентичен более простому примеру и победит цель удаления этого знака доллара). То, что это захватывает, - это все текстовые узлы либо непосредственно под этим div, либо внутри него (кроме знака доллара). Вам снова придется присоединиться к вашим результатам.

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

+0

Спасибо, Мэтью. Этот код, наряду с соединением, приблизил меня, но удвоил цену. '$ 34.96 $ 34.96' Второй вариант, который вы дали, был еще ближе, но все же немного удвоился после объединения' 34. 34.96' Большое спасибо за попытку. – Nick

+0

Я не знаю, почему это удвоило бы его. Я тестировал каждое из этих выражений в вашем исходном примере, используя lxml в python, и они отлично работали. Я не знаком с лучевой терапией, поэтому возможно что-то странное с выражениями, вызывающими это. В lxml первый дает '['', '$', '34,'. ',' 96 ']', а второй дает то же самое без знака доллара. Странно, что лучевая терапия дает другой результат. – Matthew

+0

Не уверен насчет scrapy, но когда я запускал ваш код, я просто делал это через python и получил двойной. Я только заметил, что рядом с ним есть раздел с другим именем класса, но с тем же именем itemprop и всем остальным. Я думаю, это то, где я получаю удвоение, в противном случае я бы сделал ставку на вашу работу. Благодарю. – Nick

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