本章介绍Python实现的爬虫,定时爬取航海王动画的最新集的时间信息,从而实现网站上的航海王动画更新,一旦发生更新,则以微信消息通知到用户。
一、目标站点分析;
二、爬取并提取网页数据;
三、存储数据到本地;
四、实现微信端通知;
五、简单日志系统;
六、打包部署到服务器端;
主要内容:
一、目标站点分析:
从浏览器中可见,最新的航海王更新条目位于”最新动漫资源”的第一个条目,后面的条目虽然也有包含航海王的标签,但不是最近更新,不需要关注。
航海王的更新条目位于class名为’co_content8’下的tr标签,每个tr标签里又包含两个td标签:前者表示更新的集数,后者表示最近更新的时间。如何确定是否有更新?主要两个信息,第一个是剧集”900~938”后一个数字,比如数字从”938”变为”939”,就说明剧集有更新;第二个是更新的日期信息,如果日期从当前的”2020-08-24”变为”2020-09-01”,表示剧集有更新。
基于日期变化来确定剧集更新,又有两种方法:1、采用正则表达式提取;2、直接采用换行符切割文本,提取日期信息。结合网页特点及难以程度,后文采用基于日期变化的方法2来判断剧集是否有更新。
二、爬取并提取网页数据:
因为网页中有js渲染,所以采用selenium驱动headless(无头) chrome浏览器实现数据的获取。对chrome浏览器实现headless设置,具体代码如下:
1 | c_options = Options() |
然后,通过driver的get方法获取网页,再通过find_elements_by_class_name方法获取class名为”co_content8”的标签内容,要注意名为”co_content8”的标签有多个,所以要使用”find_elements”复数形式的方法,代码如下:
1 | driver.get("http://*.net") |
得到的结果是一个list类型数据,使用len方法可获得list大小;如果要查看某个list元素的内容,可使用方法print(result[2].text),得到的输出如下:
1 | ·[迅雷动漫资源]海贼王one PIECE 第900~938话 |
获得包含航海王剧集更新范围和时间等信息(其中的日期信息换行),可发现目标数据就在第二行,采用换行符号’\n’对text进行切分,然后提取第2个元素,即’2020-08-24’。
1 | str=result[2].text.split("\n", -1) |
三、存储数据到本地:
存储数据到本地主要两种方法:文本和数据库。本文采用日期来确定剧集是否有更新,只需要爬取最近更新的日期然后保存到本地,因为信息量很小,没必要使用数据库,所以直接使用文本来保存日期信息。当从网页爬取到日期信息后,从文本中读出保存的日期数据,对比两者的异同,发现差别,则说明网页上的剧集有更新,发送通知消息到微信端,同时将爬取到的日期更新到文本中;如果没有发现差别,则说明剧集没有更新,不需要采取操作。
无论写数据还是读数据,都需要使用open()打开文本文件,只不过写的时候采用”w+”模式,而读数据时采用”r+”模式,读和写的示例代码如下:
1 | def write_data(s): |
其中的strip()方法默认删除读到的空格或者换行符号,为了方便后续的字符串比较。如何比较两个字符串的异同?这是python的基础内容,略。
四、实现微信端通知
当发现网页爬取的日期与文本保存的信息不一致,采用最常用的微信端实现消息推送。采用最普遍使用的微信来完成消息的推送,Server酱是微信平台的一款免费的消息推送服务,具备操作简单、实时、可靠等优点,故注册账号来实现航海王的更新通知。Server酱的注册与使用参见官方网页:http://sc.ftqq.com/3.version。使用过程相对简单,基于SCKEY构建http GET请求,就可以实现消息的推送,基于requests库的测试代码:
1 | def info(): |
因为requests.get()网络访问有可能出错,代码中增加冗余操作,即访问失败时,进程睡眠一个随机时间,然后再重新发起request。
五、简单日志系统
程序运行过程中,难免出现各种意外和问题,海贼王的python程序需要增加简单的log功能,方便日后的排错和维护。日志的核心功能就是以一定的格式输出信息到指定的log文件,此处采用logging库。下面是简单的示例代码:
1 | import logging |
其中的LOG_FORMAT指定日志内容的格式,DATE_FORMAT指定日期的格式,而basicConfig对log系统做简单的配置,比如log日志文件名为my.log,报警信息敏感度等级为DEBUG,最后的logging.debug()方法会将信息输出到my.log文件。每次启动爬虫时,先调用setlog方法后,其他模块就能输出信息到日志文件。
1 | def setlog(): |
六、打包部署到服务器端
为程序一天24小时都能处于待命爬取数据的状态,不受制于本地机器的开关,比较理想的方式是打包并部署代码到服务器端。云服务器可自行购买,常见的如阿里云和腾讯云,此处以阿里云的Ubuntu服务器为例。简单起见,不考虑python运行环境的隔离,也不考虑自动代码上传和下拉,则只需要三个步骤:
- 通过Winscp上传代码、文件到服务器;
- 安装chrome浏览器,配置driver;
- 配置crontab定时运行python程序;
1.通过Winscp上传代码、文件到服务器:
因为Winscp是windows平台下的程序,有简单易用的界面,所以此处不再介绍其使用,重点说下,使用Winscp上传到云端(阿里云)服务器时,遇到的权限问题:
主要是普通用户的权限问题,解决方法是使用root用户来登录Winscp(虽然会带来安全问题,但只是临时使用,问题不大)。怎么实现呢?
a.使用sudo passwd root给root用户设置密码;
b.修改ssh的配置文件使得允许root用户登录;
其中的第1步,因为ubuntu系统中root用户默认没有密码,所以要设置下;
其中的第2步,采用vim /etc/ssh/sshd_config打开ssh的配置文件,主要的修改包括注释一行和增加一行:
1 | #PermitRootLogin prohibit-password |
然后保存配置文件,并且采用命令service ssh restart来重启ssh服务,使得新配置生效。完成上述两个步骤,启动Winscp新的会话,并且以root用户和密码登录,即可实现代码和文件的上传。
阿里云上默认同时安装有python2和python3,在终端敲入python默认使用python2.7版本,敲入python3时,才会使用python3.5版本。如果常用的是python3,那么可以修改软链接,使得python默认使用python3.5版本。阿里云Ubuntu默认没有安装pip,所以使用如下的命令安装pip:
1 | sudo apt-get install python3-pip |
使用pip3 –V命令可以看到pip并不是最新版本,可以使用sudo pip3 install –upgrade pip来更新pip到最新版本。安装完成pip后,再更新下源:
a.在当前用户的工作目录下创建.pip文件夹:mkdir ~/.pip
b.再在.pip文件夹中创建pip.conf文件:touch ~/.pip/pip.conf
c.配置pip.conf文件,添加如下内容:
1 | [global] |
2.安装chrome浏览器,配置driver:
Ubuntu系统默认是没有安装Chrome浏览器的,所以要自己安装,可以去google官网下载:https://www.google.cn/chrome/,默认是Windows版本,选择”其他平台”->”Linux”->”64位.deb”版本
其他平台->linux
选择64位.deb,.deb文件的安装过程:sudo dpkg –i +安装文件在安装过程,依赖于各种包,先安装各种依赖包才可以继续chrome的安装:sudo apt-get –f install
成功完成chrome的安装。
因为python要操作chrome,所以还要安装对应的driver,可以去官网下载:
https://sites.google.com/a/chromium.org/chromedriver/downloads
不能访问的话,需要科学上网。先确定chrome的具体版本,再找到driver的对应版本。在终端输入命令:google-chrome –version
version前面是两个短行:
上图最后一行显示当前chrome的版本是84.0.4147.125,根据84这个数字下载linux版本的driver,并且放置于PATH变量中的某个路径,使得终端能找到即可。
3.配置crontab定时运行python程序:
cron是Ubuntu系统中定时周期性执行给定命令的服务(service),安装命令为: sudo apt-get install cron。可以通过命令service –status-all来查看当前系统中是否已经启动cron服务,如果没有发现cron服务,使用命令sudo service cron start来启动该服务。怎么样向cron中增加新的定时执行的命令呢?可参考如下的视频:https://www.bilibili.com/video/BV1bT4y1J7s8/
主要使用命令:crontab –e。并且在表格中增加一个新的条目,如果希望爬虫在每日的凌晨爬取一次,则按如下方式设定:
1 | 0 0 * * * /usr/bin/python3 /home/haizeiwang/main.py |
表示每天的0:0,调用命令python3 main.py,注意此处要给出文件的绝对路径,所以代码中的my.log和date.txt两个文件,也要给绝对路径。为了便于调试,可以打开cron的日志文件,cron日志功能默认不打开,可以参照博文https://blog.csdn.net/panyox/article/details/79157046 来开启。完成上述的部署后,如果航海王有更新,那么凌晨就会收到微信端的通知: