2016-02-26 26 views
5

मैं ट्यूटोरियल के साथ scrapy सीख रहा हूँ में एक सूची प्रदान करता है: http://doc.scrapy.org/en/1.0/intro/tutorial.htmlक्यों एक चयनकर्ता पाश अंदर xpath अभी भी ट्यूटोरियल

जब मैं ट्यूटोरियल में निम्न उदाहरण स्क्रिप्ट चलाने। मैंने पाया कि भले ही यह चयनकर्ता सूची के माध्यम से पहले से ही लूपिंग कर रहा था, फिर भी sel.xpath('a/text()').extract() से मिली टाइल अभी भी एक सूची थी, जिसमें एक स्ट्रिंग थी। की बजाय [u'Python 3 Object Oriented Programming'] की तरह। बाद के उदाहरण में सूची को item['title'] = sel.xpath('a/text()').extract() के रूप में आइटम सौंपा गया है, जो मुझे लगता है कि तर्कसंगत रूप से सही नहीं है।

import scrapy 

class DmozSpider(scrapy.Spider): 
    name = "dmoz" 
    allowed_domains = ["dmoz.org"] 
    start_urls = [ 
     "http://www.dmoz.org/Computers/Programming/Languages/Python/", 
    ] 

    def parse(self, response): 
     for href in response.css("ul.directory.dir-col > li > a::attr('href')"): 
      link = href.extract() 
      print(link) 

link एक स्ट्रिंग के बजाय एक सूची है:

import scrapy 

class DmozSpider(scrapy.Spider): 
    name = "dmoz" 
    allowed_domains = ["dmoz.org"] 
    start_urls = [ 
     "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", 
     "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" 
    ] 

    def parse(self, response): 
     for sel in response.xpath('//ul/li'): 
      title = sel.xpath('a/text()').extract() 
      link = sel.xpath('a/@href').extract() 
      desc = sel.xpath('text()').extract() 
      print title, link, desc 

लेकिन अगर मैं निम्नलिखित कोड का उपयोग करें।

क्या यह एक बग या इरादा है?

उत्तर

8

.xpath().extract() और .css().extract() वापसी एक सूची क्योंकि .xpath() और .css() वापसी SelectorList वस्तुओं।

देखें https://parsel.readthedocs.org/en/v1.0.1/usage.html#parsel.selector.SelectorList.extract

(SelectorList) .extract():

कॉल .extract() प्रत्येक तत्व के लिए विधि इस सूची है और यूनिकोड स्ट्रिंग की एक सूची के रूप में उनके परिणाम चपटा लौटने के लिए,।

आप केवल सबसे पहले मिलने वाला तत्व निकालना चाहते हैं, तो आप चयनकर्ता .extract_first()

कॉल कर सकते हैं:

.extract_first() आप के लिए क्या देख रहे हैं (जो खराब प्रलेखित है)

http://doc.scrapy.org/en/latest/topics/selectors.html से लिया है

>>> response.xpath('//div[@id="images"]/a/text()').extract_first() 
u'Name: My image 1 ' 

अपने अन्य उदाहरण में:

def parse(self, response): 
    for href in response.css("ul.directory.dir-col > li > a::attr('href')"): 
     link = href.extract() 
     print(link) 

प्रत्येक href पाश में एक Selector वस्तु हो जाएगा।कॉलिंग उस पर .extract() आप एक ही यूनिकोड स्ट्रिंग वापस मिल जाएगा:

$ scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/" 
2016-02-26 12:11:36 [scrapy] INFO: Scrapy 1.0.5 started (bot: scrapybot) 
(...) 
In [1]: response.css("ul.directory.dir-col > li > a::attr('href')") 
Out[1]: 
[<Selector xpath=u"descendant-or-self::ul[@class and contains(concat(' ', normalize-space(@class), ' '), ' directory ') and (@class and contains(concat(' ', normalize-space(@class), ' '), ' dir-col '))]/li/a/@href" data=u'/Computers/Programming/Languages/Python/'>, 
<Selector xpath=u"descendant-or-self::ul[@class and contains(concat(' ', normalize-space(@class), ' '), ' directory ') and (@class and contains(concat(' ', normalize-space(@class), ' '), ' dir-col '))]/li/a/@href" data=u'/Computers/Programming/Languages/Python/'>, 
... 
<Selector xpath=u"descendant-or-self::ul[@class and contains(concat(' ', normalize-space(@class), ' '), ' directory ') and (@class and contains(concat(' ', normalize-space(@class), ' '), ' dir-col '))]/li/a/@href" data=u'/Computers/Programming/Languages/Python/'>] 
तो .css() response पर

रिटर्न एक SelectorList:

In [5]: for href in response.css("ul.directory.dir-col > li > a::attr('href')"): 
    ...:  print href 
    ...:  
<Selector xpath=u"descendant-or-self::ul[@class and contains(concat(' ', normalize-space(@class), ' '), ' directory ') and (@class and contains(concat(' ', normalize-space(@class), ' '), ' dir-col '))]/li/a/@href" data=u'/Computers/Programming/Languages/Python/'> 
<Selector xpath=u"descendant-or-self::ul[@class and contains(concat(' ', normalize-space(@class), ' '), ' directory ') and (@class and contains(concat(' ', normalize-space(@class), ' '), ' dir-col '))]/li/a/@href" data=u'/Computers/Programming/Languages/Python/'> 
(...) 
<Selector xpath=u"descendant-or-self::ul[@class and contains(concat(' ', normalize-space(@class), ' '), ' directory ') and (@class and contains(concat(' ', normalize-space(@class), ' '), ' dir-col '))]/li/a/@href" data=u'/Computers/Programming/Languages/Python/'> 
:

In [2]: type(response.css("ul.directory.dir-col > li > a::attr('href')")) 
Out[2]: scrapy.selector.unified.SelectorList 

उस वस्तु पर लूपिंग आप Selector उदाहरणों देता है

और .extract() पर कॉल करने से आपको एक यूनिकोड स्ट्र ing:

In [6]: for href in response.css("ul.directory.dir-col > li > a::attr('href')"): 
    print type(href.extract()) 
    ...:  
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 
<type 'unicode'> 

नोट: .extract() पर Selectorwrongly documented स्ट्रिंग की एक सूची लौटने के रूप में है। मैं parsel पर एक मुद्दा खोलूंगा (जो स्केपर चयनकर्ताओं के समान है, और स्प्रैयर 1.1+ में हुड के तहत उपयोग किया जाता है)

+0

त्वरित उत्तर के लिए धन्यवाद! मैंने अभी पोस्ट संपादित किया है और ट्यूटोरियल से एक उदाहरण जोड़ा है जहां 'निकालें()' एक स्ट्रिंग देता है। क्या ऐसा इसलिए है क्योंकि मैं सीएसएस का उपयोग कर रहा हूं? – entron

+0

ठीक है, मैंने जो लिखा है वह सही नहीं है (उत्तर का बहुत तेज़)। वास्तव में '.xpath() निकालें()' और '.css() निकालें() 'वापसी सूची क्योंकि' .xpath() 'और' .css()' वापसी 'चयनकर्ता सूची' ऑब्जेक्ट्स। लेकिन 'xpath()' पर लूपिंग आपको 'चयनकर्ता' प्रदान करता है, जिससे आप '.extract() 'को कॉल कर सकते हैं और एक तत्व प्राप्त कर सकते हैं। मैं अपना जवाब संशोधित करूंगा –

+0

यह हिस्सा वास्तव में भ्रमित है, लेकिन अब मैं समझता हूं! आपका बहुत बहुत धन्यवाद! – entron

संबंधित मुद्दे