不知道你们是否还有印象,以前铲屎官写过一篇『【Python实战】用Scrapy编写“1024网站种子吞噬爬虫”』的文章,广受好评,你们也纷纷拿去学习。不知道跑过代码的同窗发现没有,在那个代码里面,下载图片和种子的时候,速度很慢很慢。效率不是很高。php
通过长期的磨练,铲屎官这期专门为你们带来一篇Python爬虫框架Scrapy的高阶骚操做,和市面上97%的爬虫文章绝对不一样,由于这篇文章,属于版本迭代的产物,至关于『1024种子吞噬器v2.0』熟悉开发的同窗确定明白迭代的意义,运行效率更高,实现更多新的好用的特性。无论怎么说,看完这篇文章,你将会:html
总而言之,这篇文章给你讲述的,不是一段代码,也不是一个工程,而是一个项目,从前到后,从上到下,从开发到部署,完完整整的项目讲解。并且,项目的实现思想,多是有些人曾经的想法,他们想过,可是不知从何下手,最后就放弃了,别慌,铲屎官为大家一一实现。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
咱们仍是来拿Scrapy爬1024社区,主要就是爬那几个有下载连接的版块。服务器
1# settings.py文件中
2BLOCK_INFO = {
3 15: "亚洲骑兵",
4 2: "亚洲步兵",
5 25: "国产原创",
6 4: "欧美电影",
7 26: "中字原创"
8}
复制代码
针对每个板块的每个帖子,里面有下载种子的地址,通常还有配图,咱们能够把这些图片和种子一块儿下载下来,保存到本地。微信
同时也能够将下载下来的图片和种子,经过邮件的形式发送到指定邮箱里面。框架
整个项目思路条理清晰:scrapy
先来讲一说使用说明,源码在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
就能够了。
我是作了这个项目以后,才知道,原来我的邮箱天天发邮件是有上限的。历来都不打嘴炮,用实例和图片说话,下面就是简简单单的跑了一小部分的成果:
你们本身看就好,图片都是预览图片,种子文件都是能够点击下载的。总体程序运行起来方便快捷,当你看到console里面打印的日志的时候,简直:行云流水。发送邮箱截图也给大家看一看:
这里的技术要点,我主要挑Scrapy的骚操做来讲一下。
首先是FilesPipeline,这个东西是Scrapy内部集成好的,主要用途是下载文件或者图片。由于是集成在框架内部的,因此速度很快,调用方便。
官网相关文档参考地址:
https://doc.scrapy.org/en/latest/topics/media-pipeline.html
咱们如何使用?首先要从两个地方着手:items.py
和 pipelines.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的事儿。在上面的代码,咱们看到了有个东西叫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'))
便可。
关于发邮件,在实际运行的时候,是会打印状态码的。到时候,能够根据具体的状态吗,去百度查一下是什么状态。我这里写几点我遇到的问题:
若是要把爬虫部署到服务器上,这又须要些什么啊?下面铲屎官就和你来讲一说:
首先请参考这篇文章『【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端口就能够了。
此次的骚操做解说,如今看来就差很少完结了,咱们能够从铲屎官的文章中了解到:Scrapy能够下载文件,同时还支持发送Email,并且,能够把爬虫部署到服务器上,这样就可以解放双手,还能了解到爬网站的动向。方便的很。铲屎官就已经把这种会发email的爬虫部署到了服务器阿里云服务器,还专门给女友作了一个爬虫,大家能够经过
https://peekpa.tech/jp/
访问查看爬虫结果,我还会将重要的信息经过email的形式发送出来。
这或许就是码农该有的浪漫吧。其实这种代码模式很好,自动爬取,还能够发送邮件通知,在必定程度上很自动化。就好比,你能够爬取某个购物网站,若是一点价格发生变化,你就发邮件预警,这样玩也是能够的;再好比你能够爬取某个论坛,实时的检测论坛上帖子数量是否变化,这样玩也是能够的;爬取论坛,忽然发现有一条是你喜好的明星出演的帖子,发邮件通知,这样玩也能够。。。玩法有不少,关键的手法,这篇文章给你讲授了手法,但愿可以给你们带来帮助。
最后,再给想得到代码的同窗说一下获取途径:关注公众号『皮克啪的铲屎官』,回复『代码』便可获取。
手把手用阿里云服务器搭建袜子工具,今后再也不求人,内有福利
帮你在你的服务器上部署Nginx,域名,SSL证书,内含『阿里云百元优惠券』,速来领取
这么硬核的公众号,还不赶忙关注一波啊