Scrapy爬蟲筆記(scrapy、scrapy-redis、scrapyd部署scrapy)

寫在最前面

  • 官方文檔
  • 框架圖(不管初學還是老手這個圖不要忘記)
    scrapy框架

scrapy安裝

  pip install scrapy
windows
  • 報錯:*No moudule named ‘win32api’ *
   pip install pypiwin32
windows
  • sudo apt-get install python-dev python-pip libxml2-dev libxstl1-dev zlibiq-dev libffi-dev libssl-dev
  • pip install scrapy
   pip install pypiwin32

創建項目與運行爬蟲

  scrapy startproject 項目名稱  # 創建
  scrapy crawl 爬蟲名  # 運行一個爬蟲
  # 自定義腳本運行爬蟲
    # 項目目錄下 start.py
  from scrapy import cmdline
  cmdline.execute("scrapy crawl spiderName".split()) # 需要將命令分割才能執行

生成爬蟲

  # 項目目錄下的命令
  # 生成普通爬蟲
  scrapy genspider 爬蟲名 欲爬取網站的域名 
  # 使用模板生成爬蟲
  scrapy genspider -t crawl 爬蟲名 欲爬取網站的域名

scrapy框架目錄結構

  • demo 項目目錄
    • demo 子目錄(與項目目錄同名)
      • spiders 存放爬蟲的文件夾
        • yourSpider.py 編寫的爬蟲
        • 。。。
      • items.py 數據模型
      • middlewares.py 中間件
      • pipelines.py 處理數據、保存數據
      • settings.py 配置文件
    • scrapy.cfg 項目配置文件

settings.py常用設置

  # 無需記憶
  ROBOTSTXT_OBEY = False  # 設置不遵循robots爬蟲協議
  # 請求頭設置 User-Agent 與 Referer爲常用請求頭設置
  DEFAULT_REQUEST_HEADERS = {
    # 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    # 'Accept-Language': 'en',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/79.0.3945.130 Safari/537.36',
    'Referer': 'https://www.xxxx.com',
  }
  ITEM_PIPELINES = {
    "demo..pipelines.Mypipeline": 300 # 開啓pipeline,並設置優先級,數值越小優先級越高
  }

CrawlSpider

  scrapy genspider -t crawl demo domain.com  # 生成
 LinkExtractors  鏈接提取器 :
  - allow  滿足條件的url爬取
  - follow 跟進(True/False)
  - callback 回調處理
 Rules 規則類:
  省略  . . .

注:spider通過start_request發起請求,可重寫(比如加cookies等請求頭)

Scrapy Shell

# 項目目錄下
scrapy shell url # 可以讀取項目配置信息

Request 對象和 Response 對象

  • request 對象
參數名 介紹
url 請求的url地址
callback 請求後執行的回調函數(response)
method 請求方法
headers 請求頭
meta 常用。用於在不同的請求之間傳遞數據
encoding 編碼(默認utf-8)
dot_filter 表示不由調度器過濾,在執行多次重複的請求時常用(如:登錄驗證) = False
errback 發生錯誤時的回調函數
  • response 對象
參數名 介紹
url 本次請求的url
meta 從其他請求傳來的meta
encoding 返回當前字符串編和解碼格式
text 將返回來的數據作爲unicode字符串返回
body 將返回來的數據作爲 bytes 字符串返回
xpath xpath選擇器
css css選擇器

JsonItemExporter、JsonLinesItemExporter

from scrapy.exports import JsonItemExporter # JsonLinesItemExporter
class DemoPipeline(Object):
	def __init__(self):
		self.fp = open("test.json", "wb")
		# ex: self.exporter = JsonLinesItemExporter(self.fp, ensure_ascii=False, encoding='utf-8')
		self.exporter = JsonItemExporter(self.fp, ensure_ascii=False, encoding='utf-8')
		self.exporter.start_exporting()
	
	def process_item(self, item, spider):
		self.exporter.export_item(item)
		return item
	
	def close_spider(self,spider):
		self.exporter.finish_exporting()
		self.fp.close()

Request.FormRequest 實現POST表單提交

 ...
 # 重寫 start_requests
 def start_requests(self):
 	url = ''
 	data = {...}
 	yield scrapy.FormRequest(url, formdata=data, callback=self.parse_page)
 	# url: 請求url
 	# formdata: 表單數據
 	# callback: 回調函數
 ...

scrapy.FormRequest.form_response(response, formdata=data) # 自動從response中尋找表單(注意多表單情況)

下載文件和圖片的Pipeline(Files Pipeline、Images Pipeline)

scrapy 內置下載文件的方法

 - 優勢:去重,方便指定文件路徑,可以將下載的圖片轉換成通用格式(png、jpg)
	 	可以方便的生成縮略圖,可以方便的檢測圖片的寬高,確保他們滿足大小限制,異步下載,效率高
# 普通方式
from urllib import request
...
 request.urlretrieve(url,path)
...
步驟 Files Pipeline Images Pipeline
1.定義Item file_urls,files #=#=#=# image_urls,images
2.spider中使用 from demo.items import DemoItem; yield DemoItem([args])
3.配置settings.py FILES_STORE #=#=#=# IMAGES_STORE
4.啓動Pipeline ITEM_PIPELINES中設置scrapy.pipelines.Images.ImagesPipeline:1

進階完善

重寫ImagesPipeline

from scrapy.pipelines.images import ImagesPipeline

class MyPipeline(ImagesPipeline):
	def file_path(self, request, response=None, info=None):
		path = super(MyPipeline,self).file_path(request, response, info)
		category = request.item.get('category')
		images_store = settings.IMAGES_STORE
		category_path ...
		image_name = path.replace('full/',"")
		return os.path.join(category_path,image_name)
		
	# 方法重寫,爲了傳遞item(傳值)
	def get_media_requests(self, item, info):
		request_objs = super(MyPipeline,self).get_media_requests(item, info)
		for request_obj in request_objs:
			request_obj.item = item
		return request_objs

下載器中間件 Downloader Middlewares

寫在middlewares.py中

  • process_request(self,request,spider)
    • 參數:request spider
    • 返回值
      • 返回None:scrapy將繼續處理該request,執行其他中間件中的相應的方法,直到合適的下載器處理函數被調用
      • 返回response對象
      • 返回request對象:不再使用之間的request對象去下載數據,而是根據現在返回的request對象返回數據
      • 異常:則會調用process_exception方法
  • process_response(self, request, response, spider)
    • 參數:request response spider
    • 返回值:
      • 返回response對象
      • 返回request對象:下載器鍵被切斷,返回的request會重新被下載器調度下載
      • 異常:調用request的errback方法,如果沒有指定這個方法會拋出一個異常

隨機請求頭中間件(事例)

settings.py中設置
DOWNLOADER_MIDDLEWARES={‘相對路徑’: 543} # 權值

import random
class UserAgentDownloadMiddleware(Object):
	USER_AGENTS={..,..,..,..}
	def process_request(self,request,spider):
		user_agent = random.choice(self.USER_AGENTS)
		request.headers['User-Agent'] = user_agent

ip代理池中間件

import random
class IPProxyDownloadMiddleware(Object):
	PROXIES = [..,..,..,..,..,'ip:port']
	def process_request(self,request,spider):
	proxy = random.choice(self,PROXIES)
	request.meta['proxy'] = proxy  # 注意

獨享代理(用密碼的)

import base64
...
proxy = 'xxx.xxx.xxx.xx:xxx'
user = '1465465415:asdfasdf'
request.meta['proxy'] = proxy
b64_user = base64.b64encode(user.encode('utf-8'))
request.header['Proxy-Authorization'] = 'Basic' + b64_user.decode('utf-8')
...

selenium

此處省略

Scrapy-redis

pip install scrapy-redis

框架圖(同scrapy框架圖要熟記):
在這裏插入圖片描述

settings.py

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.scheduler"
SCHEDULER_PERSIST = True  # 持久化

# pipeline
...
{
	'scrapy_redis.pipelines.RedisPipeline':400 # 開啓pipeline。權值而已
}
# REDIS_URL = 'redis://127.0.0.1:6379'
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379
REDIS_PARAMS = {
				'password':'yourpassword'
				}

scrapyd部署scrapy項目

pip install scrapyd
pip install scrapyd-client   # 客戶端工具

windows端的額外工作:
scrapyd-deploy.bat

@echo off
"path\to\python.exe" "path\to\Scripts\scrapyd-deploy" %1 %2 %3 %4 %5 %6 %7 %8 %9
  • scrapy.cfg的配置

[deploy:app] # :app 別名 項目別名
url = http://127.0.0.1:6800/ # scrapyd服務端url
project = tgod # 真正的項目名

  • 啓動scrapyd服務端 scrapyd配置文件
  • 項目目錄下運行 scrapyd-deploy app -p tgod
  • 到此部署成功

命令(建議直接手冊,別處都不是標準):scrapyd手冊

注意:

  • scrapyd web頁面:http://127.0.0.1:6800
  • 啓動爬蟲的curl中 … -d spider=demo # demo 是你要啓動的爬蟲name,對應你的單個爬蟲
  • Ubuntu用戶用ufw設置防火牆允許網段或ip

寫在最後

歡迎留言私信討論;
文章有知識性錯誤請立馬聯繫博主,博主將非常感謝;
無需經過允許即可隨意使用轉載,知識本來就是被廣泛用來學習的。
非常感謝您能看到此處,本文爲博主學習筆記,如有不同見解,請不吝賜教;

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