Python-- Scrapy

scrapy爬蟲框架

中文學習文檔:https://scrapy-chs.readthedocs.io/zh_CN/0.24/index.html 

1、爬蟲框架有哪些:

  • scrapy 
  • pyspider
  • crawley

2、scrapy框架介紹

3、安裝

(這裏安裝會遇到很多錯誤,這裏不再介紹,可以自己根據自己遇到的錯誤進行搜素解決方法)

4、scrapy包含的部件

  1. Engine:引擎負責控制系統所有組件之間的數據流,並在發生某些操作時觸發事件。
  2. Scheduler:調度程序接收來自引擎的請求,並將它們排入隊列,並在之後,當Engine需要的時候,將requests發送給engine。
  3. Downloader:下載器負責提取網頁並將它們饋送到引擎,然後引擎將其發送給spider。
  4. Spiders:蜘蛛是Scrapy用戶編寫的自定義類,用於解析響應並從中提取item項目(也稱爲抓取的項目)或追加的其他請求。(負責把下載器得到的網頁/結果進行分解,分解成數據+鏈接。)
  5. Item Pipeline:Item Pipeline負責處理被蜘蛛提取的item, 典型的任務包括清理,驗證和持久性(如將項目存儲在數據庫中)。 這一部分在上一篇文章中也詳細的介紹過了。
  6. Downloader middlewares:下載中間件,自定義下載的功能擴展組件。下載器中間件是位於引擎和下載器之間的特定的鉤子,當它們從引擎傳遞到下載器時處理請求,以及從下載器傳遞到引擎的響應。使用下載中間件可以達成如下的目的:
    1. 在將請求發送到下載器之前處理請求(即在Scrapy將請求發送到網站之前)。在傳遞給蜘蛛之前改變接收到的響應;在傳遞給蜘蛛之前改變接收到的響應;
    2. 發送新的請求,而不是將接收到的響應傳遞給蜘蛛;
    3. 發送新的請求,而不是將接收到的響應傳遞給蜘蛛;向蜘蛛傳遞響應而不需要獲取網頁;
  7. SpiderMiddleware爬蟲中間件(功能擴展組件):對spider進行功能擴展 

5、爬蟲項目大概流程

  • 新建項目:scrapy startproject xxx
  • 明確需要目標/產出:  編寫item.py
  • 製作爬蟲:地址 spider/xxspider.py
  • 存儲內容:pipelines.py,   

6、部件介紹

1、ItemPipeline

  • 對應的是pipelines文件
  • 爬蟲提取出數據存入item後,item中保存的數據需要進一步處理,比如清洗,去重,存儲等
  • process_item:
    • spider提取出來的item作爲參數傳入,同時傳入的還有spider
    • 此方法必須實現
    • 必須返回一個Item對象,被丟棄的item不會被之後的pipeline處理
  • __init__:構造函數:進行一些必要的參數初始化     
  • open_spider(spider):spider對象被開啓的時候調用
  • close_spider(spider):當spider對象被關閉的時候調用 

2、Spider

  • 對應的是文件夾spiders下的文件
  •  __init__: 初始化爬蟲名稱,start_urls列表
  • start_requests:生成Requests對象交給Scrapy下載並返回response
  • parse: 根據返回的response解析出相應的item,item自動進入pipeline; 如果需要,解析出url,url自動交給requests塊,一直循環下去
  • start_request: 此方法僅能被調用一次,讀取start_urls內容並啓動循環過程
  • name:設置爬蟲名稱
  • start_urls:  設置開始第一批爬取的url
  • allow_domains:spider允許爬去的域名列表
  • start_request(self): 只被調用一次
  • parse
  • log:日誌記錄

3、中間件(DownloaderMiddlewares)

  • 中間件是處於引擎和下載器中間的一層組件
  • 可以有很多個,被按順序加載執行
  • 作用是對發出的請求和返回的結果進行預處理
  • 在middlewares文件中
  • 需要在settings中設置以便生效
  • 一般一箇中間件完成一項功能
  • 必須實現以下一個或者多個方法
    • process_request(self, request, spider)
      • 在request通過的時候被調用
      • 必須返回None或Response或Request或raise IgnoreRequest
      • None: scrapy將繼續處理該request
      • Request: scrapy會停止調用process_request並沖洗調度返回的reqeust
      • Response: scrapy不會調用其他的process_request或者process_exception,直接講該response作爲結果返回
      • 同時會調用process_response函數
    • process_response(self, request, response,  spider)
      • 跟process_request大同小異
      • 每次返回結果的時候會自動調用
      • 可以有多個,按順序調用

案例代碼:

import random
import base64

# 從settings設置文件中導入值
from settings import USER_AGENTS
from settings import PROXIES

#  隨機的 User-Agent
class RandomUserAgent(object):
	def process_request(self, request, spider):
		useragent = random.choice(USER_AGENTS)
		request.headers.setdefault("User-Agent", useragent)
		
class RandomProxy(object):
	def process_request(self, request, spider):
		proxy = random.choice(PROXIES)
		if proxy['user_passwd'] is None:
			#  沒有代理賬戶驗證的代理使用方式
			request.meta['proxy'] = "http://" + proxy['ip_port']
		else:
			#  對賬戶密碼進行 base64 編碼轉換
			base64_userpasswd = base64.b64encode(proxy['user_passwd'])
			#  對應到代理服務器的信令格式裏
			request.headers['Proxy-Authorization'] = 'Basic ' + base64_userpasswd
			request.meta['proxy'] = "http://" + proxy['ip_port']

7、設置settings的相關代碼 

USER_AGENTS = [
			"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR
			3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
			"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0;
			SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET
			CLR 1.1.4322)",
			"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR
			2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
			"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko,
			Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
			"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3)
			Arora/0.6",
			"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-
			Ninja/2.1.1",
			"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0
			Kapiko/3.0",
			"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"
			]           

PROXIES = [
		{'ip_port': '111.8.60.9:8123', 'user_passwd': 'user1:pass1'},
		{'ip_port': '101.71.27.120:80', 'user_passwd': 'user2:pass2'},
		{'ip_port': '122.96.59.104:80', 'user_passwd': 'user3:pass3'},
		{'ip_port': '122.224.249.122:8088', 'user_passwd': 'user4:pass4'},
		]

8、去重

  • 爲了放置爬蟲陷入死循環,需要去重
  • 即在spider中的parse函數中,返回Request的時候加上dont_filter=False參數
myspeder(scrapy.Spider):
	def parse(.....):
	
		......
		
		yield  scrapy.Request(url=url, callback=self.parse, dont_filter=False)                

9、如何在scrapy使用selenium

  • 可以放入中間件中的process_request函數中
  • 在函數中調用selenium,完成爬取後返回Response 
calss MyMiddleWare(object):
	def process_request(.....):
		
		driver = webdriver.Chrome()
		html = driver.page_source
		driver.quit()
		
		return HtmlResponse(url=request.url, encoding='utf-8', body=html, request=request)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章