第五章 網絡爬蟲之Scrapy架構
● Scrapy爬蟲架構
-
Scrapy爬蟲架構介紹
1、Scrapy安裝:cmd-> pip install scrapy
2、Scrapy不是一個函數功能庫而是一個爬蟲架構。
爬蟲架構:
1)爬蟲架構是實作爬蟲功能的一個軟體結構和功能元件集合。
2)爬蟲架構是一個半成品,能夠幫助使用者實作專業網絡爬蟲。
3、Scrapy爬蟲架構結構(5主要子產品+2中間鍵)
資料流的三個路徑
路徑1:
1)Engine從 Spider處獲得爬取請求( Request);
2)Engine将爬取請求轉發給 Scheduler,用于排程;
路徑2:
3)Engine從 Scheduler處獲得下一個要爬取的請求;
4)Engine将爬取請求通過中間件發送給 Downloader;
5)爬取網頁後, Downloader形成響應( Response),通過中間件發給 Engine;
6)Engine将收到的響應通過中間件發送給 Spider處理;
路徑3:
7)Spider處理響應後産生爬取項(scraped Item)和新的爬取請求( Requests)給Engine;
8)Engine将爬取項發送給Item Pipeline(架構出口);
9)Engine将爬取請求發送給Scheduler。
資料流的出入口
Engine控制各子產品資料流,不間斷從 Scheduler處獲得爬取請求,直至請求為空。
架構入口: Spider的初始爬取請求
架構出口: Item Pipeline
ENGINE、SCHEDULER、DOWNLOAD子產品功能已有實作,SPIDERS、ITEM PIPELINES子產品有使用者編寫(配置)。
-
Scrapy爬蟲架構解析
1、Engine子產品(不需要使用者修改)—核心
1)控制所有子產品之間的資料流;
2)根據條件觸發事件;
2、Downloader子產品(不需要使用者修改:根據請求下載下傳網頁;
3、Scheduler子產品(不需要使用者修改:對所有爬取請求進行排程管理;
4、Spider子產品(需使用者編寫配置代碼)
1)解析Downloader傳回的響應(Response);
2)産生爬取項(scraped item);
3)産生額外的爬取請求(Request);
5、Item Pipelines子產品(需使用者編寫配置代碼)
1)以流水線方式處理 Spider産生的抓取項;
2)由一組操作順序組成,類似流水線,每個操作是一個Item Pipeline類型;
3)可能操作包括:清理、檢驗和查重爬取項中的HTML資料、将資料存儲到資料庫;
6、Downloader Middleware中間鍵(使用者可編寫配置代碼)
目的:實施 Engine、Scheduler和Downloader間進使用者可配置的控制;
功能:修改、丟棄、新增請求或響應;
7)Spider middleware中間鍵(使用者可編寫配置代碼)
目的:對請求和爬取項的再處理;
功能:修改、丢棄、新增請求或爬取項。
-
requests庫和Scrapy爬蟲比較
1、相同點
1)兩者都可以進行頁面請求和爬取, Python爬蟲的兩個重要技術路線;
2)兩者可用性都好,文檔豐富,入門簡單;
3)兩者都沒有處理js、送出表單、應對驗證碼等功能(可擴充)。
2、不同點
3、開發爬蟲技術路線選擇
1)非常小的需求, requests庫。
2)不太小的需求, Scrapy架構。
3)定制程度很高的需求(不考慮規模),自搭架構,requests>Scrapy。
-
Scrapy爬蟲常用指令
1、Scrapy指令行:Scrapy是為持續運作設計的專業爬蟲架構,提供操作的Scrap指令行,打開指令行操作:CMD視窗->scrapy -h。
2、Scrapy指令行格式
3、Scrapy常用指令
最常用:startproject、genspider、crawl
4、為什麼 Scrapy采用指令行建立和運作爬蟲?
1)指令行(不是圖形界面)更容易自動化,适合腳本控制;
2)本質上,Scrapy是給程式員用的,功能(而不是界面)更重要。
● Scrapy爬蟲基本使用
-
Scrapy爬蟲案列講解
應用Scrapy爬蟲架構主要是編寫配置型代碼
1、産生步驟
步驟1:建立一個Scrapy爬蟲工程
選取一個目錄(F:\pycodes\),然後執行如下指令:
F:\pycodes>scrapy startprojrct python123demo
Scrapy 1.6.0 - no active project
Unknown command: startprojrct
Use "scrapy" to see available commands
F:\pycodes>scrapy startproject python123demo
New Scrapy project 'python123demo', using template directory 'c:\users\hp\appdata\local\programs\python\python37-32\lib\site-packages\scrapy\templates\project', created in:
F:\pycodes\python123demo
You can start your first spider with:
cd python123demo
scrapy genspider example example.com
步驟2:在工程中産生一個Scrapy爬蟲
進入工程目錄(F:\pycodes\python123demo),然後執行如下指令:
F:\pycodes\python123demo>scrapy genspider demo python123.io
Spider 'demo' already exists in module:
python123demo.spiders.demo
該指令作用:
1)生成一個名稱為demo的spider;
2)在spiders目錄下增加代碼檔案 demo.py;
該指令僅用于生成 demo.py,該檔案也可以手工生成。
步驟3:配置産生的spider爬蟲
配置:1)初始URL位址;2)擷取頁面後的解析方式
import scrapy
class DemoSpider(scrapy.Spider):
name = "demo"
#allowed_domains = ["python123.io"]
start_urls = ['https://python123.io/ws/demo.html']
def parse(self, response):
fname = response.url.split('/')[-1]
with open(fname, 'wb') as f:
f.write(response.body)
self.log('Saved file %s.' % name)
步驟4:運作爬蟲,擷取網頁
在指令行下,執行如下指令:demo爬蟲被執行,捕獲頁面存儲在demo.html
F:\pycodes\python123demo>scrapy crawl demo
2、生成的工程目錄結構
python123demo/ --------------→外層目錄
scrap.cfg --------→部署 Scrapy爬蟲的配置檔案(将爬蟲放在特定的伺服器,并在伺服器配置相關的操作接口)
python 123demo/--------→Scrapy架構的使用者自定義 Python代碼
_init_.py -------→初始化腳本
items.py -------→Items代碼模闆(繼承類)(一般不需要編寫)
middlewares.py----→Middlewares代碼模闆(繼承類)(擴充middlewares功能時編寫)
pipelines.py -----→pipelines代碼模闆(繼承類)
settings.py ------→scrap爬蟲的配置檔案(優化爬蟲功能,需修改對應的配置項)
spiders/ -------→Spiders代碼模闆目錄(繼承類)(存放工程爬蟲,要求其中爬蟲符合爬蟲模闆的限制)
_init_.py —→初始檔案,無需修改
_pycache_.py →緩存目錄,無需修改
(内層目錄結構 使用者自定義的spider代碼增加在此處)
3、工程爬蟲模闆
1)類必須繼承于scrapy.Spider子類;
2)name為目前爬蟲名;
3)allowed_domains為送出給指令行的域名,爬蟲在爬取網站隻能爬取這個域名以下的相關連結;
4) start_urls以清單形式包含的一個或多個url,為scrapy架構最初爬取網址;
5)parse()用于處理響應,解析内容形成字典,發現新的URL爬取請求。
-
yield關鍵字的使用
1、yield←→ 生成器
1)生成器是一個不斷産生值的函數;
2)包含yield語句的函數是一個生成器;
3)生成器每次産生一個值(yield語句),函數被當機,被喚醒後再産生一個值。
2、生成器相比一次列出所有内容的優勢:
1)更節省存儲空間;
2)響應更迅速;
3)使用更靈活。
-
Scrapy爬蟲基本使用
1、Scrapy爬蟲的使用步驟
步驟1:建立一個工程和Spider模闆;
步驟2:編寫Spider;
步驟3:編寫Item Pipeline;
步驟4:優化配置政策。
2、Scrapy爬蟲的資料類型
Request類:class scrapy.http.Request()
Request類介紹:
1)Request對象表示一個HTTP請求;
2)由Spider生成,由Downloader執行。
Request類方法
Response類:class scrapy.http.Response()
Response類介紹:
1)Response對象表示一個HTTP響應;
2)由Downloader生成,由Spider處理。
Response類方法
Item類:class scrapy.item.Item()
Item類介紹:
1)Item對象表示一個從HTML頁面中提取的資訊内容;
2)由Spider生成,由Item Pipeline處理;
3)Item類似字典類型,可以按照字典類型操作。
3、Scrapy爬蟲支援多種HTML資訊提取方法:
• Beautiful Soup
• lxml
• re
• XPath Selector
• CSS Selector
CSS Selector的基本使用
1)格式:
2)CSS Selector由W3C組織維護并規範
● Scrapy爬蟲執行個體
-
股票資料 Scrape爬中執行個體介紹
1、功能描述
目标:擷取上交所和深交所所有股票的名稱和交易資訊
輸出:儲存到檔案中
技術路線:scrapy
2、資料網站的确定
擷取股票清單:
東方财富網:http://quote.eastmoney.com/stocklist.html
擷取個股資訊:
百度股票:https://gupiao.baidu.com/stock/
單個股票:https://gupiao.baidu.com/stock/sz002439.html
3、程式架構:編寫spider處理連結爬取和頁面解析,編寫pipelines處理資訊存儲。
-
“股票資料 Scrap爬蟲執行個體編寫(僅供參考)
步驟
步驟1:建立工程和Spider模闆
1)>scrapy startproject BaiduStocks
2)>cd BaiduStocks
3)>scrapy genspider stocks baidu.com
4)進一步修改spiders/stocks.py檔案
步驟2:編寫Spider
1)配置stocks.py檔案
2)對傳回頁面的處理
3)修改對新增URL爬取請求的處理
stocks.py檔案源代碼
import scrapy
import re
class StocksSpider(scrapy.Spider):
name = "stocks"
start_urls = ['https://quote.eastmoney.com/stocklist.html']
def parse(self, response):
for href in response.css('a::attr(href)').extract():
try:
stock = re.findall(r"[s][hz]\d{6}", href)[0]
url = 'https://gupiao.baidu.com/stock/' + stock + '.html'
yield scrapy.Request(url, callback=self.parse_stock)
except:
continue
def parse_stock(self, response):
infoDict = {}
stockInfo = response.css('.stock-bets')
name = stockInfo.css('.bets-name').extract()[0]
keyList = stockInfo.css('dt').extract()
valueList = stockInfo.css('dd').extract()
for i in range(len(keyList)):
key = re.findall(r'>.*</dt>', keyList[i])[0][1:-5]
try:
val = re.findall(r'\d+\.?.*</dd>', valueList[i])[0][0:-5]
except:
val = '--'
infoDict[key]=val
infoDict.update(
{'股票名稱': re.findall('\s.*\(',name)[0].split()[0] + \
re.findall('\>.*\<', name)[0][1:-1]})
yield infoDict
步驟3:編寫ITEM Pipelines
1)配置pipelines.py檔案
pipelines.py檔案源代碼
class BaidustocksPipeline(object):
def process_item(self, item, spider):
return item
class BaidustocksInfoPipeline(object):
def open_spider(self, spider):
self.f = open('BaiduStockInfo.txt', 'w')
def close_spider(self, spider):
self.f.close()
def process_item(self, item, spider):
try:
line = str(dict(item)) + '\n'
self.f.write(line)
except:
pass
return item
2)定義對爬取項(Scraped Item)的處理類
3)配置ITEM_PIPELINES選項
settings.py檔案中被修改的區域
ITEM_PIPELINES = {
'BaiduStocks.pipelines.BaidustocksInfoPipeline': 300,
}
步驟4:程式的執行:>scrapy crawl stocks
-
“股票資料 Scrap爬蟲執行個體優化
配置并發連接配接選項——settings.py檔案