皇冠體育二代信用盤帶手機版網絡爬蟲之scrapy框架詳解
twisted介紹
皇冠體育二代信用盤帶手機版 QQ2952777280
Twisted是用Python實現的基於事件驅動的網絡引擎框架,scrapy正是依賴於twisted,
它是基於事件循環的異步非阻塞網絡框架,可以實現爬蟲的並發。
twisted是什麽以及和requests的區別:
request是一個python實現的可以偽造瀏覽器發送Http請求的模塊,它封裝了socket發送請求
twisted是基於時間循環的異步非阻塞的網絡框架,它也封裝了socket發送請求,但是他可以單線程的完成並發請求。
twisted的特點是:
非阻塞:不等待
異步:回調
事件循環:一直循環去檢查狀態
這兩個文件有什麽作用
先看看我們上篇的示例:
- View Code
在這個示例中,雖然我們已經通過chouti.py一個文件中的parse方法實現了爬去抽屜網的新聞並將之保存在文件中的功能,
但是我們會發現有兩個問題:
1、在循環爬去每一頁的時候,每次都需要重新打開然後再關閉文件,如果數據量龐大的話,這對性能有很大的影響。
2、我們將解析和數據持久化都放在了同一個文件的同一個方法中,沒有做到分工明確
如果要解決這兩個問題,則需要用到scrapy自動為我們生成的pipeline文件和items文件
這兩個文件怎麽用
如果我們要使用這兩個文件從而解決問題,則需要有四部操作:
a.編寫pipeline文件中的類,格式如下:
class XXXPipeline(object):
def process_item(self, item, spider):
return item
b.編寫items文件中的類,格式如下:
class XXXItem(scrapy.Item):
href = scrapy.Field()
title = scrapy.Field()
c.配置settings文件
ITEM_PIPELINES = {
‘xxx.pipelines.XXXPipeline‘: 300,
‘xxx.pipelines.XXXPipeline2‘: 600, # 後面的數字為優先級,數字越大,優先級月底
}
d.在parse方法中yield一個Item對象
from xxx.items import XXXItem
def parse(self, response):
...
yield XXXItem(text=text,href=href)
執行流程為:
當我們在執行爬蟲中的parse方法的時候,scrapy一旦解析到有yield XXXitem的語句,就會到配置文件中找
ITEM_PIPELINES的配置項,進而找到XXXPipeline類,然後執行其中的方法,我們就可以在方法中做很多操作
當然,pipeline中不止process_item一個方法。
Pipeline中的方法詳解
class FilePipeline(object):
def __init__(self,path):
self.f = None
self.path = path
@classmethod
def from_crawler(cls, crawler):
"""
初始化時候,用於創建pipeline對象
:param crawler:
:return:
"""
# 從配置文件中獲取配置好的文件存放目錄
path = crawler.settings.get(‘HREF_FILE_PATH‘)
return cls(path)
def open_spider(self,spider):
"""
爬蟲開始執行時,調用
:param spider:
:return:
"""
self.f = open(self.path,‘a+‘)
def process_item(self, item, spider):
# 在這裏做持久化
self.f.write(item[‘href‘]+‘\n‘)
return item # 交給下一個pipeline的process_item方法
# raise DropItem()# 如果寫上這一句,後續的 pipeline的process_item方法不再執行
def close_spider(self,spider):
"""
爬蟲關閉時,被調用
:param spider:
:return:
"""
self.f.close()
去重
scrapy內部實現的去重
從上一篇的例子我們可以看出,其實scrapy內部在循環爬去頁碼的時候,已經幫我們做了去重功能的,
因為我們在首頁可以看到1,2,3,4,5,6,7,8,9,10頁的頁碼以及連接,當爬蟲爬到第二頁的時候,
還是可以看到這10個頁面及連接,然後它並沒有再重新把第一頁爬一遍。
它內部實現去重的原理是,將已爬去的網址存入一個set集合裏,每次爬取新頁面的時候就先看一下是否在集合裏面
如果在,就不再爬去,如果不在就爬取,然後再添加入到set裏。當然,這個集合存放的不是原網址,
而是將鏈接通過request_fingerprint()方法將它變成一個類似於md5的值,這樣可以節省存儲空間
自定義去重
雖然scrapy已經幫我們實現了去重,但是有時候不足以滿足我們的需求,這樣就需要我們自定義去重了
自定義去重分兩步
1、編寫DupeFilter類
from scrapy.dupefilter import BaseDupeFilter
from scrapy.utils.request import request_fingerprint
class XXXDupeFilter(BaseDupeFilter):
def __init__(self):
‘‘‘初始化一個集合,用來存放爬去過的網址‘‘‘
self.visited_fd = set()
@classmethod
def from_settings(cls, settings):
‘‘‘
如果我們自定義了DupeFilter類並且重寫了父類的該方法,
scrapy會首先執行該方法,獲取DupeFilter對象,
如果沒有定義,則會執行init方法來獲取對象
‘‘‘
return cls()
def request_seen(self, request):
‘‘‘在此方法中做操作,判斷以及添加網址到set裏‘‘‘
# 將request裏的url轉換下,然後判斷是否在set裏
fd = request_fingerprint(request=request)
# 循環set集合,如果已經在集合裏,則返回True,爬蟲將不會繼續爬取該網址
if fd in self.visited_fd:
return True
self.visited_fd.add(fd)
def open(self): # can return deferred
‘‘‘開始前執行此方法‘‘‘
print(‘開始‘)
def close(self, reason): # can return a deferred
‘‘‘結束後執行此方法‘‘‘
print(‘結束‘)
def log(self, request, spider): # log that a request has been filtered
‘‘‘在此方法中可以做日誌操作‘‘‘
print(‘日誌‘)
2.配置settings文件
1
2
3
修改默認的去重規則
DUPEFILTER_CLASS = ‘scrapy.dupefilter.RFPDupeFilter‘
DUPEFILTER_CLASS = ‘xxx.dupefilters.XXXDupeFilter‘
深度
深度就是爬蟲所要爬取的層級
限制深度只需要配置一下即可
1
2
限制深度
DEPTH_LIMIT = 3
cookie
獲取上一次請求之後獲得的cookie
from scrapy.http.cookies import CookieJar
class ChoutiSpider(scrapy.Spider):
name = ‘chouti‘
allowed_domains = [‘chouti.com‘]
start_urls = [http://hxforum.com/thread-422-1-1.html/‘]
cookie_dict = {}
def parse(self, response):
# 去響應頭中獲取cookie,cookie保存在cookie_jar對象
cookie_jar = CookieJar()
cookie_jar.extract_cookies(response, response.request)
# 去對象中將cookie解析到字典
for k, v in cookie_jar._cookies.items():
for i, j in v.items():
for m, n in j.items():
self.cookie_dict[m] = n.value
再次請求的時候攜帶cookie
yield Request(
url=‘http://hxforum.com/thread-422-1-1.html‘,
method=‘POST‘,
body="phone=861300000000&password=12345678&oneMonth=1",#
cookies=self.cookie_dict,
headers={
‘Content-Type‘: ‘application/x-www-form-urlencoded; charset=UTF-8‘
},
callback=self.check_login
)
皇冠體育二代信用盤帶手機版網絡爬蟲之scrapy框架詳解