皮爷不知道大家有多少人是喜欢看美剧?
反正皮爷是个美剧迷,不能说狂,但是看美剧的时间也有差不多10年了。硬生生的把好多部剧都追到了完结。
最早以前,网上资源还不是很严的时候,找个美剧是十分简单的。可是最近几年,网络资源越来越严格,寻找美剧确实不容易,而且,新出的美剧,比如《生活大爆炸》S12E11集,如果刚出来,你下载是完全没问题的。可是,比如你最近很忙,过了几周,你想起来你还有3集《生活大爆炸》没有看,心中暗自窃喜,一下子看3集,是很爽的事儿。当你打开网页,复制网页资源链接到迅雷里,迅雷过一会儿给你弹出个提示:“网络资源已经下架”。你是不是很蛋疼?这种情况一般就发生在新出的美剧,隔了几周之后,就会有这种资源下架的问题。
还有一种情况比较烦恼,就是,如果你同时追着很多剧,你是不是每天都得查看这个剧是不是更新了?或者这个剧一般是周二更新,但是你想看熟肉(熟肉就是有中文字幕的意思)资源,可是熟肉资源并不是周二更新之后立刻更新,最快也得周三,但也有可能周四周五。那么这三天,你是谁不也得天天网站看一遍是否更新啊?如果你有15部美剧更新,那么你是不是得每天还少打开5个网页来查看呢?浏览网页会不会需要费时间?一周浏览这种网页的时间会不会很多?其实你只是需要一个下载地址而已,并不需要看其他无关的消息。
那么今天,既然皮爷会用Python,会写爬虫,而且这种每天追美剧的工作,其实是一种机械的重复劳动,不值得投入大量时间重复浪费在检查美剧是否更新上。所以,皮爷用Scrapy写了一个爬虫,将自己追的美剧,每天定期的用代码扫描以下,然后将结果发送到皮爷的邮箱里。然后每天只要检查自己邮箱里面是否有美剧的更新就可以了。
这样搞起来,是不是很方便??是不是很省时间???啊哈哈哈哈。别着急,今天这篇文章讲的只是爬虫相关部分,还有一篇文章,专门讲皮爷怎么讲这个爬虫放到网上,然后让大家自己填写配置信息,然后供大家使用,到时候只需要填写,你要接受美剧更新信息的邮箱,还有你要追的美剧就可以了。到时候会放到 https://peekpa.tech 网站里面。
LETS DO IT
首先,皮爷现在一直在用的一个美剧网站:
http://www.ttmeiju.vip/
就是『天天美剧』,这里更新的比较快。苦于之前的人人美剧被强制关停了,现在的人人影视又总是打一枪换个地方,而电影天堂的跟新又太慢,所以,皮爷就一直在这个网站追美剧。不过有一点,这个网站的美剧熟肉和生肉资源都有,而且随着美剧资源注解被收拢,可能有些片子就没有熟肉资源,但是这是个联系听力学习英语的好机会啊。
废话不多说,我们就先拿《生活大爆炸》这个美剧来分析吧。
进入到《生活大爆炸》的页面:
http://www.ttmeiju.vip/meiju/The.Big.Bang.Theory.html
可以看到关键信息有这么几点:
- 网页的URL
- 剧集列表的基本信息
- 剧集的季数
- 最关键的下载地址
我们一条一条来分析:
首先是网页的URL,
像这种信息类的网页,他的URL不可能太特别,应该是个别规整的。为了分析出规则,我们在拿几个美剧的URL对比一下:
http://www.ttmeiju.vip/meiju/Supergirl.html
http://www.ttmeiju.vip/meiju/The.Blacklist.html
http://www.ttmeiju.vip/meiju/S.W.A.T.html
上面不难看出,URL前面的格式都一样,是http://www.ttmeiju.vip/meiju/
,然后跟着就是美剧的英文名字,中间空格用.
来连接,最后再加一个html
就可以了。
为什么要知道这个?目的就是如果我同事追着好几个美剧,那么我只需要把英文名字告诉爬虫就可以了,然后爬虫会根据URL的规则,来访问对应的网页,从而爬取美剧信息。
接着来看剧集基本信息
这个地方,在网页里面,是一个class=seedlink
的 div
标签里面的东西。
为什么要知道这个?这里面,最主要的东西我个人认为是更新日
,状态
还有更新日期
这几个变量。我们可以根据更新日期来判断我的爬虫是否需要继续寻找下面的下载链接。如果当前爬虫运行的时候,发现上回运行时间要晚于更新日期,那么这次爬取就可以直接放弃,因为没有更新。
所以这里的变量我们得要获取。用来判断爬虫是否爬取当前页面。
剧集的季数
因为一部美剧,可能有好几季,那么如果他更新了,出了最新的集,我们是不是得按照季来爬取?
而且,当你点击这几个标签的时候,
你就会发现上面的URL其实悄悄的发生了变化。就是在原来的 .html
之前,多了一个/
加数字,这个数字就是当前的季数。所以,如果想要复杂一点,爬取指定季的美剧,那么我们就得想办法获得当前是哪一季,对不对?
这个也很简单啊,这个美剧打开的网页,首先默认显示的是当前季,只不过在URL里面没有加当前季的数字而已,想要获取数字,只需要在一个h3
的标签,class=curseason
里面的文本信息就好。
但是这里,我们拿到的文本信息比如是下面的:
text = "第12季"复制代码
我们想要获取数字,只需要用正则表达式取一下就可以:
seacon_num = re.findall("\d{1,3}",text)[0]复制代码
这里我们主要是去取数字,长度为1位,2位或者3位的数字。一般来说,一部美剧的季数,最多也就不可能超过三位数了。
最后一个就是下载地址了
这个我们可以看到每一集美剧中间都有几个按钮,他们分别是不同的下载方式。
这里我们看到,主要有这么几点:
- 这里是名称,
- 这里就是下载地址的图标,其实,每个图标都对应的是一个下载链接。
- 这个则是文件的大小
- 这里显示的是规格,是否有字幕
- 这里是很重要的部分,更新时间!!我们拿美剧更新时间和上回爬虫访问时间做对比,来判断是否需要处理数据。
OK,有了这五点,我们就就可以写爬虫来爬取数据了。爬虫写起来没什么难度,关键是下载地址那块,这里要把对应的文件地址都整理好。每一个图标都对应的是一个下载链接,如下图:
这里,我们的代码就是整合成这样:
tbody_list = soup.find_all(name="tbody", attrs={ "id":"seedlist"})if len(tbody_list) != 0: tr_list = tbody_list[0].find_all(name="tr") for item in tr_list: td_list = item.find_all(name="td") item_time = td_list[-1].text.strip() item_time_cur = datetime.datetime.strptime(item_time, "%Y-%m-%d") diff_day = (item_time_cur - play_last_update_day).days if diff_day >= 0 or play_last_update_day is "": item_name = td_list[1].text.strip() name_list = item_name.split(" ") title_ch = name_list[0] s_and_e_list = re.findall("S\d{2}E\d{2}", item_name) video_clarity = re.findall("\d{3,4}p", item_name) video_season_episode = s_and_e_list[0] video_season = video_season_episode[1:3] video_episode = video_season_episode[4:6] item_download_td = td_list[2] item_download_url = item_download_td.find_all(name="a") item_download_ed2k = str() item_download_magnet = str() item_download_bt = str() item_download_baidu = str() for download_item in item_download_url: if "magnet:" in download_item['href']: item_download_magnet = download_item['href'] if "ed2k:" in download_item['href']: item_download_ed2k = download_item['href'] if ".torrent" in download_item['href']: item_download_bt = download_item['href'] if "pan.baidu" in download_item['href']: item_download_baidu = download_item['href'] item_size = td_list[-4].text.strip() item_subscribe = td_list[-3].text.strip()复制代码
最后,只需要生成一个Scrapy Item
,然后 yield
出来就可以了:
class TtmjVideoItem(scrapy.Item): video_title_ch = scrapy.Field() video_title_en = scrapy.Field() video_title_total = scrapy.Field() video_season = scrapy.Field() video_episode = scrapy.Field() video_season_episode = scrapy.Field() video_clarity = scrapy.Field() video_size = scrapy.Field() video_has_subscribe = scrapy.Field() video_publish_time = scrapy.Field() video_create_time = scrapy.Field() video_download_magnet = scrapy.Field() video_download_ed2k = scrapy.Field() video_download_baidu = scrapy.Field() video_download_bt = scrapy.Field()复制代码
这里穿插一下,在云服务器部署 MongoDB 的操作,在皮爷自己的公众号『皮爷撸码』里面就有专门的详细的手把手的教学文章,让你从小白到王者,征服部署MongoDB到云服务器上的骚操作,具体参考以下文章:
这些都是每个人必须掌握的骚操作。
倒数第二步我们就是发送Email了
之前的步骤,我们通过 yield TtmjVideoItem
已经把这个 Item 交到了我们的pipeline里面。
在 Pipeline
里面,我们需要在 def process_item(self, item, spider):
函数里面执行存入数据库的操作,同时,在 def close_spider(self, spider):
函数里面,执行发送操作,因为这个时候,我们的爬虫即将关闭,我们此时的数据就是现成的,所以选择在这个时候发送 Email 来会比较好。
发送 Email 这里我就不多说了,因为在之前的文章里面已经说过了,感兴趣的可以关注微信公众号『皮爷撸码』,查看往期精选,关于 Email 的文章,请查看这篇:
这篇文章里面有很详细的配置说明。皮爷在这里,把发送的邮件,封装成了 html
格式的文本。这样做就是方便在邮件里面,直接点击链接就可以下载了。
最后一步,就是将爬虫部署到你的云服务器上
Scrapy爬虫都是可以部署到云服务器上的。 为啥要这么搞? 因为这样很方便啊,你可以利用linux的固定执行命令,每天定点执行你的Scrapy爬虫就可以了,而且,还很省心,不再需要每天为了看电影而打开 IDE 或者 终端,去输入运行 Python 程序的命令。简单的一步到位,从此解放双手,何乐而不为呢。
关于部署 Scrapy 爬虫到云服务器上的文章,皮爷之前也很详细的写过,详情可以参考以下文章,这篇文章也在皮爷的公众号里面,查看『皮爷撸码』公众号的文章历史里面就有:
『【压岁钱来买服务器玩云爬虫】把Scrapy爬虫一步一步通过Scrapyd部署到腾讯云上(阿里云同理)』
最后成果展示
最后,给大家看一下皮爷的成果,在皮爷邮箱里面:
打开之后,邮件长这个样子:
如果想下载的话,就直接点击链接就可以了。这样就不需要再每天抽时间去网站上看是否更新了,是否有熟肉资源啥的。每天爬虫定点执行,就会将没有更新的资源统统发送到你的邮箱里。你每天只需要做,打开邮箱,点击下载就可以了。
『代码改变生活,这话不假』
不算结语的结语
获取文章代码,只需要关注『皮爷撸码』,回复『代码』,即可找到你想要的代码。这么硬核的公众号,我自己从内心喜欢。
这篇文章还有个『下』篇,下回在写,主要就是怎样将这个爬虫部署到:https://peekpa.tech
上,然后服务更多的同学。当然了,皮爷也有一个想法,就是结合小程序来做美剧的追剧。这个点子很不错,凭借『六十四卦』小程序的经验,我觉得这个软件不难。以后给大家搞出来。
『皮爷撸码』是个很硬核的公众号,我写了很多爬虫的文章,我会慢慢分享给大家,而且和大家说一点,如果写爬虫写的好,是真的能赚到钱的,因为现在是信息时代,网络信息纷繁复杂,每天我们耳朵听的,眼睛看到的信息就成千上万,古代都说学富五车,其实远远没有我们现在面临的信息量大。如何高效的处理信息,抓住重点,避免重复阅读或者重复操作而浪费时间,这个是很需要技术的。而且,现在社会,对于个人而言什么最值钱?当然是时间。你每天刷抖音,逛微博,看点知乎,以为知道了些常识,就认为自己学习了东西,其实不是的。写爬虫的目的其实有一部分就是可以过滤信息,节省时间。所以,身为一个程序员,我是从内心真真切切的感觉到,写代码是一件很有意思的事儿。
后续皮爷还会有更多的东西给大家分享,点子有很多,而且都很有意思,很具有实战性。不多说了,如果觉得皮爷这里干货很多,那就麻烦转发,分享,点击个好看呗。皮爷谢谢大家了。
关注『皮爷撸码』,你,不吃亏。