2016-02-26 15 views
5

tôi đang học scrapy với hướng dẫn: http://doc.scrapy.org/en/1.0/intro/tutorial.htmlTại sao xpath bên trong một vòng lặp selector vẫn trả về một danh sách trong hướng dẫn

Khi tôi chạy đoạn mã ví dụ sau đây trong hướng dẫn. Tôi thấy rằng mặc dù nó đã được looping thông qua danh sách chọn, gạch tôi nhận được từ sel.xpath('a/text()').extract() vẫn là một danh sách, trong đó có một chuỗi. Giống như [u'Python 3 Object Oriented Programming'] thay vì u'Python 3 Object Oriented Programming'. Trong ví dụ sau, danh sách được gán cho mục là item['title'] = sel.xpath('a/text()').extract(), mà tôi cho là không chính xác về mặt logic.

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 

Tuy nhiên nếu tôi sử dụng đoạn mã sau:

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) 

các link là một chuỗi chứ không phải là một danh sách.

Đây có phải là lỗi hoặc dự định không?

Trả lời

8

.xpath().extract().css().extract() trả lại danh sách vì .xpath().css() trả về SelectorList đối tượng.

Xem https://parsel.readthedocs.org/en/v1.0.1/usage.html#parsel.selector.SelectorList.extract

(SelectorList) .extract():

Gọi .extract() phương pháp cho mỗi phần tử là danh sách này và trả về kết quả của họ phẳng, như một danh sách các chuỗi unicode.

.extract_first() là những gì bạn đang tìm kiếm (được giấy tờ kém)

Taken từ http://doc.scrapy.org/en/latest/topics/selectors.html:

Nếu bạn muốn trích xuất chỉ phần tử đầu tiên xuất hiện, bạn có thể gọi selector .extract_first()

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

Trong ví dụ khác của bạn:

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

mỗi href trong vòng lặp sẽ là một đối tượng Selector.Gọi .extract() vào nó sẽ giúp bạn có một chuỗi Unicode đơn lại:

$ 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/'>] 

nên .css() trên response trả về một SelectorList:

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

Looping trên đối tượng cung cấp cho bạn Selector trường hợp:

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/'> 

Và gọi .extract() cung cấp cho bạn một đường Unicode duy nhất 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'> 

Lưu ý: .extract() trên Selectorwrongly documented như trả về một danh sách các chuỗi. Tôi sẽ mở một vấn đề trên parsel (giống như bộ chọn Scrapy, và được sử dụng dưới mui xe trong phế liệu 1.1+)

+0

Cảm ơn câu trả lời nhanh! Tôi vừa chỉnh sửa bài đăng và thêm một ví dụ từ hướng dẫn trong đó 'extract()' đưa ra một chuỗi. Đây có phải là vì tôi đang sử dụng css không? – entron

+0

Phải, những gì tôi viết không chính xác (quá nhanh của câu trả lời). Trong thực tế '.xpath(). Extract()' và '.css(). Extract()' trả về các danh sách vì các đối tượng '.xpath()' và '.css()' return 'SelectorList'. Nhưng lặp lại trên '.xpath()' với cung cấp cho bạn một 'Selector', từ đó bạn có thể gọi' .extract() 'và nhận một phần tử đơn. Tôi sẽ sửa đổi câu trả lời của tôi –

+0

Phần này thực sự khó hiểu, nhưng bây giờ tôi đã hiểu! Cảm ơn nhiều! – entron

Các vấn đề liên quan