讓我們討論一下市咆,你希望獲得整個網(wǎng)站的語錄而不是僅僅的爬取開始http://quotes.toscrape.com汉操,給的兩個網(wǎng)頁。
現(xiàn)在你理解了如何從網(wǎng)頁中提取數(shù)據(jù)蒙兰,讓我們了解如何從開始的鏈接來追蹤后續(xù)鏈接磷瘤。
首先是從網(wǎng)頁中提取我們想要追蹤的鏈接。檢查測試我們的網(wǎng)頁搜变,我們可以看到下一頁的鏈接采缚,以HTML標(biāo)記:
<ul class = "pager">
<li class = "next">
<a href = "/page/2/">Next <span aria-hidden = "true">→</span></a>
</li>
</ul>
我們可以嘗試在shell中提取它:
>>>response.css('li.next a').extract_first()
'<a href = "/page/2/">Next <span aria-hidden = "true">→</span></a>'
我們提取了標(biāo)簽元素,但是我們想要其中屬性的href值挠他。為此扳抽,Scarpy提供CSS的擴展應(yīng)用讓我們提取屬性中的內(nèi)容,像這樣:
>>>response.css('li.next a::attr(href)').extract_first()
'/page/2/'
現(xiàn)在修改我們的爬蟲來遞歸下一頁的功能殖侵,從網(wǎng)頁中提取數(shù)據(jù):
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
]
def parse(self, response):
for quote in response.css('div.quote'):
yield{
'text':quote.css('span.text::text').extract_first(),
'author':quote.css('span.text:text').extract_first(),
'tags':quote.css('div.tags a.tag::text').extract(),
}
next_page = response.css('li.next a::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page, callback = self.parse)
現(xiàn)在提取數(shù)據(jù)后贸呢,parse()方法查找下一頁的鏈接,以urljoin()方法建立網(wǎng)站完整的URL拢军,向下一頁生成新請求楞陷,為下一頁的鏈接提取數(shù)據(jù)注冊它本身為返回函數(shù)同時保持爬取整個網(wǎng)站。
你看到的是Scrapy追蹤鏈接的機制:當(dāng)你在返回函數(shù)中生成請求茉唉,Scrapy將會安排請求被發(fā)送和注冊返回函數(shù)被執(zhí)行固蛾,直到請求結(jié)束。
使用這方法赌渣,你可以搭建復(fù)雜的爬蟲來追蹤你需要的深度魏铅,同時在你訪問的網(wǎng)頁中提取數(shù)據(jù)。
在我們的例子中坚芜,它創(chuàng)建了一個循環(huán)览芳,追蹤所有網(wǎng)頁的鏈接——讓我們來爬取具有標(biāo)記頁數(shù)的博客、論壇和其他網(wǎng)站鸿竖。