我想監(jiān)控爬蟲(chóng)狀況怎么辦?Scrapy郵件發(fā)送功能及爬蟲(chóng)停止信息 。

一、需求

郵件發(fā)送功能,作為一個(gè)【通知】或者說(shuō)【知曉】的方式,在實(shí)際應(yīng)用中會(huì)經(jīng)常使用的,試想一個(gè)場(chǎng)景:

你掌握著公司半數(shù)以上的爬蟲(chóng),并且你每天都要監(jiān)控它們(他們?cè)诜?wù)器上),你作為一個(gè)爬蟲(chóng)技術(shù)從業(yè)者,你肯定會(huì)想(偷懶),因?yàn)椴煌祽械墓こ處煵粫?huì)進(jìn)步。你希望當(dāng)它們觸發(fā)某個(gè)狀況的時(shí)候,你的郵箱會(huì)收到對(duì)應(yīng)的提醒,這樣你可以及時(shí)的處理這些狀況,當(dāng)然你也可以集成微信來(lái)開(kāi)發(fā),讓通知發(fā)送到你的微信,但是互聯(lián)網(wǎng)行業(yè),郵箱還是經(jīng)常用的。

可以根據(jù)實(shí)際需求,在不同的時(shí)機(jī)發(fā)送不同的提醒郵件,以對(duì)爬蟲(chóng)狀態(tài)進(jìn)行監(jiān)控。

這里我以監(jiān)控爬蟲(chóng)的停止信息來(lái)作為示例。

timg (1).jpg

二、scrapy文檔

scrapy官網(wǎng)文檔有提供郵件發(fā)送的資料:

發(fā)送email

雖然Python通過(guò) smtplib 庫(kù)使得發(fā)送email變得很簡(jiǎn)單,Scrapy仍然提供了自己的實(shí)現(xiàn)。 該功能十分易用,同時(shí)由于采用了 Twisted非阻塞式(non-blocking)IO ,其避免了對(duì)爬蟲(chóng)的非阻塞式IO的影響。 另外,其也提供了簡(jiǎn)單的API來(lái)發(fā)送附件。 通過(guò)一些 settings 設(shè)置,您可以很簡(jiǎn)單的進(jìn)行配置。

簡(jiǎn)單例子

有兩種方法可以創(chuàng)建郵件發(fā)送器(mail sender)。 您可以通過(guò)標(biāo)準(zhǔn)構(gòu)造器(constructor)創(chuàng)建:

fromscrapy.mailimportMailSendermailer = MailSender()

或者您可以傳遞一個(gè)Scrapy設(shè)置對(duì)象,其會(huì)參考 settings:

mailer= MailSender.from_settings(settings)

這是如何來(lái)發(fā)送郵件(不包括附件):

mailer.send(to=["someone@example.com"], subject="Some subject", body="Some body", cc=["another@example.com"])

MailSender類(lèi)參考手冊(cè)

在Scrapy中發(fā)送email推薦使用MailSender。其同框架中其他的部分一樣,使用了 Twisted非阻塞式(non-blocking)IO 。

classscrapy.mail.MailSender(smtphost=None, mailfrom=None, smtpuser=None, smtppass=None, smtpport=None)

參數(shù)由以下組成:

smtphost (str) – 發(fā)送email的SMTP主機(jī)(host)。如果忽略,則使用 MAIL_HOST 。
  mailfrom (str) – 用于發(fā)送email的地址(address)(填入 From:) 。 如果忽略,則使用 MAIL_FROM 。
  smtpuser – SMTP用戶(hù)。如果忽略,則使用 MAIL_USER 。 如果未給定,則將不會(huì)進(jìn)行SMTP認(rèn)證(authentication)。
  smtppass (str) – SMTP認(rèn)證的密碼      
  smtpport (int) – SMTP連接的端口     
  smtptls – 強(qiáng)制使用STARTTLS
  smtpssl(boolean)– 強(qiáng)制使用SSL連接

classmethodfrom_settings(settings)

使用Scrapy設(shè)置對(duì)象來(lái)初始化對(duì)象。其會(huì)參考 這些Scrapy設(shè)置.

參數(shù): settings (scrapy.settings.Settings object) – the e-mail recipients

send(to, subject, body, cc=None, attachs=(), mimetype='text/plain')

發(fā)送email到給定的接收者。 參數(shù):

to (list) – email接收者
subject (str) – email內(nèi)容
cc (list) – 抄送的人
body (str) – email的內(nèi)容
attachs (iterable) – 可迭代的元組 (attach_name, mimetype, file_object)。 attach_name 是一個(gè)在email
  的附件中顯示的名字的字符串, mimetype 是附件的mime類(lèi)型, file_object 是包含附件內(nèi)容的可讀的文件對(duì)象。
mimetype (str) – email的mime類(lèi)型

三、實(shí)際寫(xiě)法

根據(jù)上面官網(wǎng)文檔的一些介紹和語(yǔ)法(更多語(yǔ)法請(qǐng)上官網(wǎng)翻閱)

這里編寫(xiě)一段示例代碼(結(jié)合信號(hào)量)

3.1 設(shè)置郵箱pop

登錄QQ郵箱 找到設(shè)置-賬戶(hù)

然后生成授權(quán)碼(以前是生成密碼,現(xiàn)在用授權(quán)碼)

3.2 編碼

在具體的爬蟲(chóng)文件中編寫(xiě):

from scrapy.mail import MailSender
from scrapy.xlib.pydispatch import dispatcher
from scrapy import signals

接著在class類(lèi)的上方編寫(xiě)emial的鏈接配置信息:

mailers= MailSender(smtphost="smtp.qq.com",  # 發(fā)送郵件的服務(wù)器    
mailfrom="abcdefg@qq.com",  # 郵件發(fā)送者
smtpuser="abcdefg@qq.com",  # 用戶(hù)名
smtppass="qtpzvxxyyxxyyxxyyxde",  # 發(fā)送郵箱的密碼不是你注冊(cè)時(shí)的密碼,而是授權(quán)碼?。?!切記!
smtpport=25 # 端口號(hào)
)  #初始化郵件模塊

然后再到class類(lèi)中編寫(xiě)信號(hào)量監(jiān)聽(tīng)和具體的郵件發(fā)送代碼:

 def  __init__(self):
    """ 監(jiān)聽(tīng)信號(hào)量 """
    super(YoutubeapiSpider, self).__init__()
    # 當(dāng)收到spider_closed信號(hào)的時(shí)候,調(diào)用下面的close方法來(lái)發(fā)送通知郵件    
    dispatcher.connect(self.close, signals.spider_closed)

 def  close(spider, reason):
   """ 執(zhí)行郵件發(fā)送操作 """
  body ="爬蟲(chóng)[%s]已經(jīng)關(guān)閉,原因是: %s"% (spider.name, reason)        
  subject ="[%s]爬蟲(chóng)關(guān)閉提醒"% spider.name        
  mailers.send(to={"admin@qq.com","quinns@aliyun.com"}, 
  subject=subject,                   
  body=body)

這樣就會(huì)在收到爬蟲(chóng)關(guān)閉信號(hào)的時(shí)候,通過(guò)abgdefg@qq.com給指定的admin@qq.comquinns@aliyun.com發(fā)送郵件(實(shí)際應(yīng)用的時(shí)候可以考慮給1個(gè)或多個(gè)郵箱發(fā)送),郵件內(nèi)容是body,郵件標(biāo)題是subject。

3.3 在郵件里添加爬蟲(chóng)停止信息

畢竟停止信息里面對(duì)爬蟲(chóng)狀態(tài)和記錄比較詳細(xì),所以郵件中應(yīng)當(dāng)發(fā)送停止信息。

當(dāng)然了,寫(xiě)法很多,除了def close 還可以:

def __init__(self):
  """ 監(jiān)聽(tīng)信號(hào)量 """
  super(YoutubeapiSpider, self).__init__()# 當(dāng)收到spider_closed信號(hào)的時(shí)候,調(diào)用下面的close方法來(lái)發(fā)送通知郵件
  dispatcher.connect(self.spider_closed, signals.spider_closed)
def spider_closed(self, spider, reason):
      # 上方的信號(hào)量觸發(fā)這個(gè)方法
      stats_info = self.crawler.stats._stats  # 爬蟲(chóng)結(jié)束時(shí)控制臺(tái)信息
      body = "爬蟲(chóng)[%s]已經(jīng)關(guān)閉,原因是: %s.\n以下為運(yùn)行信息:\n %s" % (spider.name, reason, stats_info)
      subject = "[%s]爬蟲(chóng)關(guān)閉提醒" % spider.name
      mailers.send(to={"513720453@qq.com"},
                   subject=subject,
                   body=body)

只要滿足觸發(fā)條件,就可以發(fā)送指定內(nèi)容的郵件。
然后收到的郵件是這樣的:


收到的郵件

3.4 郵件配置的坑

在使用過(guò)程中,如果發(fā)送郵件后,scrapy報(bào)出如下錯(cuò)誤信息:


報(bào)錯(cuò)

通過(guò)多方排查,依舊沒(méi)有資料信息。

后來(lái)無(wú)意中改動(dòng)了郵件發(fā)送配置中的端口,就解決了這個(gè)問(wèn)題


25-465.png

只要將原來(lái)的25端口改成465即可。(猜測(cè)跟郵件服務(wù)器pop3的ssl有關(guān),未親自確認(rèn))
這里雖然只是以爬蟲(chóng)關(guān)閉來(lái)舉例,實(shí)際上可以監(jiān)控更多的行為操作,比如百度翻譯的接口超量、捕獲一些特殊的異常等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容