Scrapy爬蟲筆記
- 寫在最前面
- scrapy安裝
- 創建項目與運行爬蟲
- 生成爬蟲
- scrapy框架目錄結構
- settings.py常用設置
- CrawlSpider
- Scrapy Shell
- Request 對象和 Response 對象
- JsonItemExporter、JsonLinesItemExporter
- Request.FormRequest 實現POST表單提交
- 下載文件和圖片的Pipeline(Files Pipeline、Images Pipeline)
- 下載器中間件 Downloader Middlewares
- 隨機請求頭中間件(事例)
- ip代理池中間件
- selenium
- Scrapy-redis
- scrapyd部署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
編寫的爬蟲
- 。。。
- yourSpider.py
- items.py
數據模型
- middlewares.py
中間件
- pipelines.py
處理數據、保存數據
- settings.py
配置文件
- spiders
- scrapy.cfg
項目配置文件
- demo
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
寫在最後
歡迎留言私信討論;
文章有知識性錯誤請立馬聯繫博主,博主將非常感謝;
無需經過允許即可隨意使用轉載,知識本來就是被廣泛用來學習的。
非常感謝您能看到此處,本文爲博主學習筆記,如有不同見解,請不吝賜教;