【Python】這就是程序員的浪漫,Scrapy的高階騷操做,帶郵件功能的「1024種子吞噬器2.0」版本,更高更快更強!有福利可領取

不知道你們是否還有印象,以前鏟屎官寫過一篇『【Python實戰】用Scrapy編寫「1024網站種子吞噬爬蟲」』的文章,廣受好評,你們也紛紛拿去學習。不知道跑過代碼的同窗發現沒有,在那個代碼裏面,下載圖片和種子的時候,速度很慢很慢。效率不是很高。php

通過長期的磨練,鏟屎官這期專門爲你們帶來一篇Python爬蟲框架Scrapy的高階騷操做,和市面上97%的爬蟲文章絕對不一樣,由於這篇文章,屬於版本迭代的產物,至關於『1024種子吞噬器v2.0』熟悉開發的同窗確定明白迭代的意義,運行效率更高,實現更多新的好用的特性。無論怎麼說,看完這篇文章,你將會:html

  • 熟悉Scrapy的基本操做
  • 掌握Scrapy的高階騷操做
  • 學會拿着Scrapy的FilesPipeline來搞事情
  • 會使用Python來發Email
  • 以及在服務器上面部署爬蟲的小知識點
  • 當別人留下郵箱說好人一輩子平安的時候,你知道怎麼作了

總而言之,這篇文章給你講述的,不是一段代碼,也不是一個工程,而是一個項目,從前到後,從上到下,從開發到部署,完完整整的項目講解。並且,項目的實現思想,多是有些人曾經的想法,他們想過,可是不知從何下手,最後就放棄了,別慌,鏟屎官爲大家一一實現。git

看鏟屎官的文章,要知道鏟屎官講的都是項目開發的思路,而不是項目自己。由於項目代碼是死的,而你的思惟方式是活的。c#

整套項目我都部署到了阿里雲服務器上,超級好用,萌新能夠經過下面的連接領取阿里雲和騰訊雲的優惠券,優惠力度大約一年300元的服務器,安全

能便宜120元
。反正這兩個比Amazon的AWS好用,速度快並且鏈接穩定。
阿里雲(總價值千元代金券)

https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=nrkmbo9q

騰訊雲(總價值高達2775元代金券)

https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=b351b2fc50b15866ff9d19b58a5df0f5

廢話很少說,快來看看咱們此次迭代的東西究竟是什麼。bash

INTROCDUCTION

咱們仍是來拿Scrapy爬1024社區,主要就是爬那幾個有下載連接的版塊。服務器

1# settings.py文件中
2BLOCK_INFO = {
3    15: "亞洲騎兵",
4    2: "亞洲步兵",
5    25: "國產原創",
6    4: "歐美電影",
7    26: "中字原創"
8}
複製代碼

針對每個板塊的每個帖子,裏面有下載種子的地址,通常還有配圖,咱們能夠把這些圖片和種子一塊兒下載下來,保存到本地。微信

同時也能夠將下載下來的圖片和種子,經過郵件的形式發送到指定郵箱裏面。框架

整個項目思路條理清晰:scrapy

爬取
分析
下載
保存
發送
。可是咱們能夠玩出一些花活兒。好比,我經過Scrapyd能夠將爬蟲部署到服務器上面,這樣就能夠定時定點去爬,而後能夠將結果狀況發送到郵箱裏,方便管理員管理查看。

HOW TO USE

先來講一說使用說明,源碼在Github上已經共享出來了,以前關注過我Github的小夥伴能夠在上面找到,項目叫『SESpider1024』,不知道地址的小夥伴不要緊,關注微信公衆號『皮克啪的鏟屎官』,回覆『代碼』便可獲取下載地址。

將工程git到本地以後,推薦用PyCharm打開,在跑程序以前,須要在setting.py裏面下面的這些變量設置一下:

1ROOT_URL = "https://XX.XXXX.XX/"        # 這裏須要更新到最新的地址
2                                    # 這裏是用126郵箱作例子,並不侷限126郵箱
3SMTP_HOST = "smtp.126.com"          # 發送郵件的smtp服務器
4SMTP_USER = "XXXXXX@126.com"       # 用於登陸smtp服務器的用戶名,也就是發送者的郵箱
5SMTP_PWD = "XXXXXXX"             # 受權碼,和用戶名user一塊兒,用於登陸smtp, 非郵箱密碼
6SMTP_PORT = 25                      # smtp服務器SSL端口號,默認是465,具體是什麼,網上一搜郵箱域名和他的smtp就知道了
7SMTP_SENDER = "XXXXXX@126.com"      # 發送方的郵箱
8SMTP_TO_LIST = ["YYYYYY@126.com", "ZZZZZZ@126.com"]     # 發送目標郵箱地址,是個list
複製代碼

設置成功以後,直接運行/Email1024/Run.py文件便可。

這裏會涉及到發郵件的問題,這裏鏟屎官要多說一點,可能有的小夥伴不知道這個是什麼,因此這裏鏟屎官手把手的來叫大家如何打開大家郵箱的SMTP設置。

鏟屎官這裏就以126郵箱爲例,其實郵箱都差很少的,萬變不離其宗。

註冊郵箱的過程,我就很少說了,這個應該你們都會的。

而後登陸郵箱,在最上面一行找到『設置』,選擇『POP3/SMTP/IMAP』:

點擊以後,須要將下面的幾個打鉤選擇開通便可:

這裏咱們看到,針對126郵箱的SMTP服務器地址是:smtp.126.com,這個東西就是咱們上面須要在settings.py裏面設置的。

端口號怎麼找?直接百度126 smtp,就會出來官方的幫助中心,裏面咱們打開,就能看到端口號列表了。

咱們就把25填寫到上面settings.py裏面的端口號就能夠。

這裏就設置完畢了,若是設置QQ郵箱,163郵箱,步驟都是差很少的,打開郵箱的SMTP服務便可。

一切都搞好以後,運行Run.py就能夠了。

OUTCOME

我是作了這個項目以後,才知道,原來我的郵箱天天發郵件是有上限的。歷來都不打嘴炮,用實例和圖片說話,下面就是簡簡單單的跑了一小部分的成果:

你們本身看就好,圖片都是預覽圖片,種子文件都是能夠點擊下載的。總體程序運行起來方便快捷,當你看到console裏面打印的日誌的時候,簡直:行雲流水。發送郵箱截圖也給大家看一看:

TECH DETAIL

這裏的技術要點,我主要挑Scrapy的騷操做來講一下。

騷操做之FilesPipeline

首先是FilesPipeline,這個東西是Scrapy內部集成好的,主要用途是下載文件或者圖片。由於是集成在框架內部的,因此速度很快,調用方便。

官網相關文檔參考地址:

https://doc.scrapy.org/en/latest/topics/media-pipeline.html

咱們如何使用?首先要從兩個地方着手:items.pypipelines.py

1    ``` 
 2    items.py
 3    ```
 4class Email1024Item(scrapy.Item):
 5    topic_id = scrapy.Field()
 6    topic_url = scrapy.Field()
 7    topic_title = scrapy.Field()
 8    topic_img_url = scrapy.Field()
 9    block_name = scrapy.Field()
10    file_urls = scrapy.Field()
11    file = scrapy.Field()   # 這個須要建立出來,爲下載文件提供使用
複製代碼

items.py文件裏面,咱們須要建立item的各個變量,如果須要使用FilesPipeline的話,須要在建一個file=scrapy.Field()的變量。

下一步就是關鍵的pipelines.py文件

1    ```
 2    pipelines.py
 3    ```
 4class Email1024FilePipeline(FilesPipeline):
 5    def get_media_requests(self, item, info):
 6        for index, image_url in enumerate(item['file_urls']):
 7            if 'gif' in image_url:
 8                continue
 9            yield Request(image_url, meta={'name': item['topic_title'], 'index': str(index), 'block_name': item['block_name']})
10
11    def file_path(self, request, response=None, info=None):
12        # 由於'/'字符會在路徑中轉換成文件夾,因此要替換掉
13        name = request.meta['name'].strip().replace('/', '-')
14        if request.meta['index'] == '0':
15            return request.meta['block_name'] + "/" + name + "/" + name + ".torrent"
16        else:
17            return request.meta['block_name'] + "/" + name + "/" + name + "-" + request.meta['index'] + ".jpg"
18
19    def item_completed(self, results, item, info):
20        emailHelper = EmailHelper()
21        emailHelper.sendEmailWithAttr(results, item)
22        return item
複製代碼

這裏我要着重解釋一下:

首先是get_media_requests()方法。這個方法的用途是:當item生成好,傳入的時候,須要在這個方法裏面發起文件下載的請求。即調用 scrapy.Request() 方法。

在這裏,咱們作法就是將file_urls裏面的每個url請求一遍。注意,這裏的file_urls就是上面item中的 file_urls=scrapy.Field(),這個東西是一個list()

接着,是方法 file_path() ,這個方法的用途主要是要返回一個合法的string做爲下載文件的保存路徑名字。我這裏作了特殊處理,由於request請求回來的其實都是字節流,將這些東西保存下來,若是想要打開,還須要添加相對於的合法後綴才行。因此,我固定的將種子文件放在file_urls列表中第一個,而且將它的請求文件保存後綴改爲.torrent,其餘的則保存成.jpg若是最後返回的文件路徑不合法或者錯誤,運行Spider結束以後,是不會有任何下載保存動做的,因此這裏須要調試的時候特別用心,多多注意一下。

最後是item_completed()方法,這個方法的調用時機是在item裏面的全部url下載完畢以後,會有一個result返回。result是一個集合,裏面記錄了各個url的下載狀況和路徑。咱們能夠根據result的結果,來對item作處理。在這裏,個人處理是將結果發送出去。

OK,這就是FilesPipeline的玩法。這個東西不光能下載文件,還能下載圖片,我這裏的例子就是包含了種子和圖片兩種。因此,多實踐,多采坑。

最後還要注意一步,就是寫了Pipeline,必定要在settings.py文件裏面去設置一下:

1ITEM_PIPELINES = {
2   'Email1024.pipelines.Email1024FilePipeline': 1,
3}
複製代碼
騷操做之Email

接着,咱們來講說發送email的事兒。在上面的代碼,咱們看到了有個東西叫EmailHelper()的東西。這個東西就在emailUtil.py裏面。這個文件主要做用就是用來發郵件的。其實Scrapy內部就已經集成了MailSender,可是,這個東西我沒找到他發送附件的功能,只能發送一些簡單的文字類東西。因此,我放棄了。轉頭開始用Python的email庫。這個庫在Python3以後就是自帶的了,用起來還算挺方便的。這裏就簡單來講一下關鍵的技術點:

1    def sendEmailWithAttr(self, result, item):
 2        message = MIMEMultipart()
 3        message['From'] = self.sender               # 發件人
 4        message['To'] = ",".join(self.toLst)                 # 收件人列表
 5        message['Subject'] = item['topic_title']                # 郵件標題
 6        message.attach(MIMEText(item['topic_title'], 'plain', 'utf-8'))
 7
 8        for downItem in result:
 9            if downItem[0] == True:
10                filename = './' + FILES_STORE + '/' + downItem[1]['path']
11                with open(filename, 'rb') as f:
12                    attachfile = MIMEApplication(f.read())
13                filename = downItem[1]['path'].split('/')[-1]
14                attachfile.add_header('Content-Disposition', 'attachment', filename=filename)
15                encoders.encode_base64(attachfile)
16                message.attach(attachfile)
17
18        try:
19            smtpSSLClient = smtplib.SMTP(self.smtp_host, self.smtp_port)
20            loginRes = smtpSSLClient.login(self.smtp_user, self.smtp_pwd)
21            print(f"登陸結果:loginRes = {loginRes}")
22            if loginRes and loginRes[0] == 235:
23                print(f"登陸成功,code = {loginRes[0]}")
24                smtpSSLClient.sendmail(self.sender, self.toLst, message.as_string())
25                print(f"發送成功. message:{message.as_string()}")
26            else:
27                print(f"登錄失敗,code = {loginRes[0]}")
28        except Exception as e:
29            print(f"發送失敗,Exception: e={e}")
複製代碼

這裏比較關鍵的點就是那段添加附件的代碼,這裏須要找到已經下載好的文件路徑,而後讀取文件,而且調用message.attach(attachfile)加入到附件裏就可有。郵件的內容,我這裏是發送的是帖子的標題。其實郵件內容能夠發送html格式的東西,寫法:message.attach(MIMEText(htmlBody, 'html', 'utf-8'))便可。

關於發郵件,在實際運行的時候,是會打印狀態碼的。到時候,能夠根據具體的狀態嗎,去百度查一下是什麼狀態。我這裏寫幾點我遇到的問題:

  • 我的郵箱每日都有郵件上限
  • 若是把程序佈置到服務器上,是須要調用SSL發送的。
  • 郵件內容若是附帶一些url,會被郵件系統誤判爲垃圾郵件或者病毒郵件而發送不出去。
  • 最好把發送郵箱地址添加到白名單裏面。

WHAT ABOUT ON SERVER

若是要把爬蟲部署到服務器上,這又須要些什麼啊?下面鏟屎官就和你來講一說:

首先請參考這篇文章『【Python實戰】用Scrapyd把Scrapy爬蟲一步一步部署到騰訊雲上』,裏面講述了詳細的部署方法和週期運行方法。

而後,若是你不修改任何代碼就將程序部署到服務器上,郵件功能是跑不通的。就好比我本身輕身經歷,將爬蟲部署到阿里雲服務器,我須要修改主要是emailUtil.py,地方以下:

1#將
2self.smtp_port = 25
3# 改成
4self.smtp_port = 465
5
6#將
7smtpSSLClient = smtplib.SMTP(self.smtp_host, self.smtp_port)
8#改成
9smtpSSLClient = smtplib.SMTP_SSL(self.smtp_host, self.smtp_port)
複製代碼

而後再將服務器的安全組裏面,打開465端口就能夠了。

CONCLUSION

此次的騷操做解說,如今看來就差很少完結了,咱們能夠從鏟屎官的文章中瞭解到:Scrapy能夠下載文件,同時還支持發送Email,並且,能夠把爬蟲部署到服務器上,這樣就可以解放雙手,還能瞭解到爬網站的動向。方便的很。鏟屎官就已經把這種會發email的爬蟲部署到了服務器阿里雲服務器,還專門給女友作了一個爬蟲,大家能夠經過

https://peekpa.tech/jp/

訪問查看爬蟲結果,我還會將重要的信息經過email的形式發送出來。

這或許就是碼農該有的浪漫吧。其實這種代碼模式很好,自動爬取,還能夠發送郵件通知,在必定程度上很自動化。就好比,你能夠爬取某個購物網站,若是一點價格發生變化,你就發郵件預警,這樣玩也是能夠的;再好比你能夠爬取某個論壇,實時的檢測論壇上帖子數量是否變化,這樣玩也是能夠的;爬取論壇,忽然發現有一條是你喜好的明星出演的帖子,發郵件通知,這樣玩也能夠。。。玩法有不少,關鍵的手法,這篇文章給你講授了手法,但願可以給你們帶來幫助。

最後,再給想得到代碼的同窗說一下獲取途徑:關注公衆號『皮克啪的鏟屎官』,回覆『代碼』便可獲取。

推薦閱讀

手把手用阿里雲服務器搭建襪子工具,今後再也不求人,內有福利
幫你在你的服務器上部署Nginx,域名,SSL證書,內含『阿里雲百元優惠券』,速來領取

這麼硬核的公衆號,還不趕忙關注一波啊

相關文章
相關標籤/搜索