運行環(huán)境:
* Python 2.7.12
* Scrapy 1.2.2
* Mac OS X 10.10.3 Yosemite
繼續(xù)爬取Scrapy 1.2.2文檔提供的練習(xí)網(wǎng)址:
可以暫時不用考慮爬蟲被封的情況是复,用于初級爬蟲練習(xí)裕菠。
目標(biāo)
爬取該網(wǎng)站所有頁的名言(quote)咬清、作者(author)以及標(biāo)簽(tag)。
增加內(nèi)容
- response.urljoin():將相對網(wǎng)址拼接成絕對網(wǎng)址。
- scrapy.Request():發(fā)出請求旧烧∮岸ぃ可以用參數(shù)(callback=),對返回的響應(yīng)(response)進(jìn)行解析掘剪。
步驟1:增加爬蟲代碼
繼續(xù)使用極簡爬蟲中的代碼平委,增加三行內(nèi)容即可。但是更改了爬蟲的名字(name)夺谁,變成name = 'quotes_2_2'
廉赔,用以區(qū)分第一個爬蟲。
next_page = response.css('li.next a::attr("href")').extract_first()
next_full_url = response.urljoin(next_page)
yield scrapy.Request(next_full_url, callback=self.parse)
完整代碼如下:
import scrapy
class QuotesSpider(scrapy.Spider):
name = 'quotes_2_2'
start_urls = [
'http://quotes.toscrape.com',
]
allowed_domains = [
'toscrape.com',
]
def parse(self,response):
for quote in response.css('div.quote'):
yield{
'quote': quote.css('span.text::text').extract_first(),
'author': quote.css('small.author::text').extract_first(),
'tags': quote.css('div.tags a.tag::text').extract(),
}
next_page = response.css('li.next a::attr("href")').extract_first()
next_full_url = response.urljoin(next_page)
yield scrapy.Request(next_full_url, callback=self.parse)
分析
首先予权,需要找到下一頁的入口網(wǎng)址昂勉。使用Chrome或者firefox的firebug對網(wǎng)頁進(jìn)行分析,找到下一頁的圖標(biāo)“next —>“的標(biāo)簽中扫腺,有下一頁的網(wǎng)址岗照。具體網(wǎng)頁html片段如下:
<ul class="pager">
<li class="next">
<a href="/page/2/">Next <span aria-hidden="true">→</span></a>
</li>
</ul>
只需要通過Scrapy的CSS選擇器定位到li.next a
位置即可,意思是類名是next的li標(biāo)簽笆环,下面的a標(biāo)簽攒至。
再把這個a標(biāo)簽中的網(wǎng)址提取出來。網(wǎng)址是其中href="/page/2/"
這一段躁劣,使用a::attr("href")
來提取迫吐。(注:如果是文本就是::attr(text)提取账忘;如果是圖片的src鏈接志膀,就是::attr(src)來提取)鳖擒,然后賦值到next_page變量上溉浙。
next_page = response.css('li.next a::attr("href")').extract_first()
這里只能得到一個相對網(wǎng)址/page/2/。Scrapy并不能爬取相對網(wǎng)址蒋荚,因此需要使用response.urljoin()來轉(zhuǎn)化成相對網(wǎng)址戳稽。
next_full_url = response.urljoin(next_page)
最后,對這個下一頁的網(wǎng)址期升,再發(fā)出一個請求惊奇,使用yield scrapy.Request(),但是在Request()的參數(shù)中播赁,使用callback=self.parse颂郎,表示繼續(xù)調(diào)用parse()函數(shù)進(jìn)行解析,提取其中需要的內(nèi)容
yield scrapy.Request(next_full_url, callback=self.parse)
步驟2:運行爬蟲
使用運行命令scrapy crawl運行爬蟲:
$ scrapy crawl quotes_2_2 -o results_2_2_01.json
最后可以得到100條名言容为。
改進(jìn)
因為下一頁可能并不存在祖秒,所以也可以加入一個判斷語句诞吱,判斷下一頁存在的話才去爬取舟奠。
只需要在上面的代碼增加一行判斷語句的代碼即可竭缝。
next_page = response.css('li.next a::attr("href")').extract_first()
if next_page is not None:
next_full_url = response.urljoin(next_page)
yield scrapy.Request(next_full_url, callback=self.parse)
如果“next_page”這個網(wǎng)址存在,才向服務(wù)器發(fā)請求沼瘫。