一.遞歸爬取解析多頁頁面數據框架
- 需求:將糗事百科全部頁碼的做者和段子內容數據進行爬取切持久化存儲dom
- 需求分析:每個頁面對應一個url,則scrapy工程須要對每個頁碼對應的url依次發起請求,而後經過對應的解析方法進行做者和段子內容的解析。異步
實現方案:scrapy
1.將每個頁碼對應的url存放到爬蟲文件的起始url列表(start_urls)中。(不推薦)ide
2.使用Request方法手動發起請求。(推薦)函數
代碼:post
1 import scrapy 2 from qiushibaike.items import QiushibaikeItem 3 4 # scrapy.http import Request 5 class QiushiSpider(scrapy.Spider): 6 name = 'qiushi' 7 allowed_domains = ['www.qiushibaike.com'] 8 start_urls = ['https://www.qiushibaike.com/text/'] 9 10 11 #爬取多頁 12 pageNum = 1#起始頁碼 13 url = 'https://www.qiushibaike.com/text/page/%s/' #每頁的url 14 15 def parse(self,response): 16 div_list = response.xpath('//*[@id="content-left"]/div') 17 for div in div_list: 18 author=div.xpath('.//div[@class="author clearfix"]//h2/text()').extract_first() 19 author=author.strip('\n') 20 content=div.xpath('.//div[@class="content"]/span/text()').extract_first() 21 content=content.strip('\n') 22 item=QiushibaikeItem() 23 item['author']=author 24 item['content']=content 25 26 yield item #提交item到管道進行持久化 27 28 29 #爬取全部頁碼數據 30 if self.pageNum <= 13: #一共爬取13頁(共13頁) 31 self.pageNum += 1 32 url = format(self.url % self.pageNum) 33 34 #遞歸爬取數據:callback參數的值爲回調函數(將url請求後,獲得的相應數據繼續進行parse解析),遞歸調用parse函數 35 yield scrapy.Request(url=url,callback=self.parse)
二.五大核心組件工做流程url
。引擎(Scrapy)spa
用來處理整個系統的數據流處理,觸發事務(框架核心)code
。調度器(Scheduler)
用來接受引擎發過來的請求,壓入隊列中,並在引擎再次請求的時候返回. 能夠想像成一個URL(抓取網頁的網址或者說是連接)的優先隊列, 由它來決定下一個要抓取的網址是什麼, 同時去除重複的網址。
。下載器(Downloader)
用於下載網頁內容,並將網頁內容返回給蜘蛛(Scrapy下載器是創建在twisted這個高效的異步模型上的)
。爬蟲(Spiders)
爬蟲是主要幹活的,用於從特定的網頁中提取本身須要的信息,所謂的實體(item)。用戶也能夠從中提取出連接,讓Scrapy繼續抓取下一個頁面
。項目管道(Pipeline)
負責處理爬蟲從網頁中抽取的實體,主要功能是持久化實體、驗證明體的有效性、清除不須要的信息。當頁面被爬蟲解析後,被髮送到項目管道,通過幾個特定的次序處理數據。
三. Post請求的發送
- 在以前的代碼中,咱們歷來沒有手動的對start_urls列表中的起始url進行請求的發送,可是起始url的確是進行請求的發送,如何實現的呢?
-- 實際上是由於爬蟲文件中的爬蟲類繼承到了Spider父類中的start_requests(self)這個方法,該方法就能夠對start_urls列表中的url發起請求:
1 def start_requests(self): 2 for u in self.start_urls: 3 yield scrapy.Request(url=u,callback=self.parse)
該方法默認的實現,是對起始的url發起get請求,若是想發起post請求,則須要子類重寫該方法。
方法: 重寫start_requests方法,讓其發起post請求:
1 def start_requests(self): 2 #請求的url 3 post_url = 'http://fanyi.baidu.com/sug' 4 # post請求參數 5 formdata = { 6 'kw': 'wolf', 7 } 8 # 發送post請求 9 yield scrapy.FormRequest(url=post_url, formdata=formdata, callback=self.parse)