我們在 Scrapy 的 shell 中展示如何從網(wǎng)頁提取數(shù)據(jù):
scrapy shell "http://quotes.toscrape.com/page/1/"
注意:windows 系統(tǒng)下 url 需要用雙引號未巫。
你會看到這樣的輸出:
2017-06-14 21:26:03 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
[s] Available Scrapy objects:
[s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s] crawler <scrapy.crawler.Crawler object at 0x01047E90>
[s] item {}
[s] request <GET http://quotes.toscrape.com/page/1/>
[s] response <200 http://quotes.toscrape.com/page/1/>
[s] settings <scrapy.settings.Settings object at 0x0427C310>
[s] spider <DefaultSpider 'default' at 0x4e43af0>
[s] Useful shortcuts:
[s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s] fetch(req) Fetch a scrapy.Request and update local objects
[s] shelp() Shell help (print this help)
[s] view(response) View response in a browser
>>>
下面我們在 shell 里面利用 css 選擇器來提取網(wǎng)頁的數(shù)據(jù):
>>> response.css('title')
[<Selector xpath='descendant-or-self::title' data='<title>Quotes to Scrape</title>'>]
執(zhí)行上述命令將會返回一個類似列表的對象:SelectorList
令花;這是由選擇器根據(jù)提取規(guī)則提取出來的 XML/HTML 元素潘酗,你可以對它進一步細分或提取溪食。
要提取 <title>
標簽里面的內(nèi)容链沼,可以這樣:
>>> response.css('title::text').extract()
['Quotes to Scrape']
在 css 選擇器表達式中使用 ::text
理逊,可以提取標簽的內(nèi)容春叫,如果不使用,結(jié)果如下:
>>> response.css('title').extract()
['<title>Quotes to Scrape</title>']
.extract()
方法會根據(jù) SelectorList 內(nèi)容返回一個列表碾褂,如果我們只需要返回列表中第一個元素兽间,或者知道列表中只存在一個元素,可以這樣寫:
>>> response.css('title::text').extract_first()
'Quotes to Scrape'
又或者正塌,可以用列表切片的方式:
>>> response.css('title::text')[0].extract()
'Quotes to Scrape'
但我們還是建議采用 .extract_first()
嘀略,這樣可以避免要提取的元素為空的時候發(fā)生 IndexError
恤溶。
除了上述方法外,我們還可以用正則表達式提取元素帜羊,用 re()
方法即可:
>>> response.css('title::text').re(r'Quotes.*')
['Quotes to Scrape']
>>> response.css('title::text').re(r'Q\w+')
['Quotes']
>>> response.css('title::text').re(r'(\w+) to (\w+)')
['Quotes', 'Scrape']
Scrapy 還能用 Xpath
來提取內(nèi)容:
>>> response.xpath('//title')
[<Selector xpath='//title' data='<title>Quotes to Scrape</title>'>]
>>> response.xpath('//title/text()').extract_first()
'Quotes to Scrape'