如何写第一个scrapy
目錄
結構
第一個scrapy的思路
代碼實現:
?核心代碼解讀
小結
結構
scrapy是一個框架,要想寫出第一個scrapy程序,那么就得先了解這個框架是由哪些組件構成的,這些組件又有什么作用。
scrapy的組件?看一下這些組件詳細的工作流程圖
?這些組件是如何配合的可以參考一下組件結構,我就不費筆墨了。
那么了解了scrapy的大致工作流程之后,如何開始寫好第一個scrapy程序呢???
第一個scrapy的思路
既然是第一個,那就寫得簡單點。不考慮太多,通過回答下面三個問題開始理清思路。
- 爬蟲從哪個或者哪些頁面開始爬取?
- 對于一個已經下載的頁面,需要提取其中哪些數據?
- 爬取完當前頁面后,接下來爬取哪些頁面?
目標頁面:http://books.toscrape.com/
爬取目標:爬取該網站所有書本的信息(具體是哪些信息自己決定,這里選取書名和庫存量)。
代碼實現:
首先創建一個scrapy項目,
輸入命令:scrapy startproject books
在spiders文件中新建一個爬蟲文件,spider.py
spiders.py?
import scrapyclass BooksSpider(scrapy.Spider):name = "start"start_urls = ["http://books.toscrape.com/"]# 解析函數def parse(self, response):for book in response.css('article.product_pod'):# 解析出書名name = book.xpath('./h3/a/@title').extract_first()yield{'name':name,}# 解析出下一頁的urlnext_url = response.css('ul.pager li.next a::attr(href)').extract_first()# 如果還有下一頁,則用Request請求發出if next_url:next_url = response.urljoin(next_url)yield scrapy.Request(next_url , callback=self.parse)如果將
?yield{
? ? ? ? ? ? ? ? 'name':name,
? ? ? ? ? ? }
改成
yield name
則會出現錯誤?
也就是yield 只能返回Request請求,Item,dict數據,或者返回None。?返回Request會被引擎發送給Downloader組件,返回Item或者dict會被引擎發送給Item pipeline組件。
?核心代碼解讀
name = 'start'
在一個scrapy中可以實現多個Spider,每個Spider需要被區分,于是Spider類的屬性name起到了標識的作用,執行scrapy crawl name時,name就告訴了scrapy用哪個Spider去實現。
?start_urls = ["http://books.toscrape.com/"]
?start_urls是Spider類里面的屬性,定義起始爬取點,它通常被實現成一個列表,其中放入所有起始爬取點的url。
可是我們都沒有發送Request請求,為什么僅僅在start_urls里面放入url就能運行呢???看一下Spider的源碼我們就明白了,
#該方法將讀取start_urls內的地址,并為每一個地址生成一個Request對象, 并返回這些對象的迭代器#該方法金調用一次def start_requests(self):for url in self.start_urls:yield self.make_requests_from_url(url)#start_requests()中調用,實際生成Request的函數。#Request對象默認的回調函數為parse(),提交的方式為getdef make_requests_from_url(self, url):return Request(url, dont_filter=True)#默認的Request對象回調函數,處理返回的response。#生成Item或者Request對象。用戶必須實現這個類def parse(self, response):raise NotImplementedErrorscrapy會自動地調用一次start_requests,僅僅只調用一次。
如果我們想為Request請求添加特定的HTTP頭部,或者指定解析函數,則可以重寫start_requests方法。
小結
name屬性:是用來標識scrapy項目中的Spider,因為一個scrapy中可能有多個Spider
start_urls屬性:是用來存放爬取起始點的url,如果使用start_urls,則不需要重寫start_requests方法。如果有特定的需求,可重? ? ? ? ? ? ? ? ? ? ? ? ? ? 寫start_requests方法
parse函數:起解析response作用,可手動實現其他解析函數。解析函數需要完成兩項任務,一是提取頁面數據,以item或者字典的形式提交給scrapy引擎;二是使用選擇器或者LinkExtractor提取頁面中的url,用提取出來的url構造新的Request并提交給引擎。
?
總結
以上是生活随笔為你收集整理的如何写第一个scrapy的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python的yield和yield f
- 下一篇: 如何使用scrapy的item来封装数据