本章介绍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
2
3
4
c_options = Options()
c_options.add_argument('--headless')
c_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=c_options)

然后,通过driver的get方法获取网页,再通过find_elements_by_class_name方法获取class名为”co_content8”的标签内容,要注意名为”co_content8”的标签有多个,所以要使用”find_elements”复数形式的方法,代码如下:

1
2
3
4
5
6
driver.get("http://*.net")
result = driver.find_elements_by_class_name('co_content8')
if(len(result)!=0):
print(type(result))
print(len(result))
print(result[2].text)

得到的结果是一个list类型数据,使用len方法可获得list大小;如果要查看某个list元素的内容,可使用方法print(result[2].text),得到的输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
·[迅雷动漫资源]海贼王one PIECE 第900~938话
2020-08-24
·[迅雷动漫资源]名侦探柯南 第1000~1035话
2020-08-17
·[迅雷动漫资源]海贼王one PIECE 第917话
2020-01-14
·[迅雷动漫资源]名侦探柯南 第1023话
2020-01-14
·[迅雷动漫资源]火影忍者疾风传 第720话 全
2017-03-28
·[迅雷动漫资源]妖精的尾巴 FAIRY TAIL 第三部ZERO 第012/277话
2016-03-26
·[迅雷动漫资源]妖精的尾巴FAIRY TAIL 第265话2014
2015-12-26
·[迅雷动漫资源]火影忍者疾风传 第481-612话
2015-01-01
·[迅雷动漫资源]海贼王one PIECE 第601-676话
2014-12-28
·[迅雷动漫资源]名侦探柯南2小时特别篇 柯南失踪 史上最惨的两天
2014-12-27

获得包含航海王剧集更新范围和时间等信息(其中的日期信息换行),可发现目标数据就在第二行,采用换行符号’\n’对text进行切分,然后提取第2个元素,即’2020-08-24’。

1
2
str=result[2].text.split("\n", -1)
print(str[1])

三、存储数据到本地:

存储数据到本地主要两种方法:文本和数据库。本文采用日期来确定剧集是否有更新,只需要爬取最近更新的日期然后保存到本地,因为信息量很小,没必要使用数据库,所以直接使用文本来保存日期信息。当从网页爬取到日期信息后,从文本中读出保存的日期数据,对比两者的异同,发现差别,则说明网页上的剧集有更新,发送通知消息到微信端,同时将爬取到的日期更新到文本中;如果没有发现差别,则说明剧集没有更新,不需要采取操作。

无论写数据还是读数据,都需要使用open()打开文本文件,只不过写的时候采用”w+”模式,而读数据时采用”r+”模式,读和写的示例代码如下: 

1
2
3
4
5
6
7
8
9
10
def write_data(s):
    fo=open("data.txt", "w+")
    fo.write(s)
    fo.close()

def read_data():
    fo=open("data.txt", "r+")
    d=fo.read(20)
    fo.close()
    return d.strip()

其中的strip()方法默认删除读到的空格或者换行符号,为了方便后续的字符串比较。如何比较两个字符串的异同?这是python的基础内容,略。

四、实现微信端通知

当发现网页爬取的日期与文本保存的信息不一致,采用最常用的微信端实现消息推送。采用最普遍使用的微信来完成消息的推送,Server酱是微信平台的一款免费的消息推送服务,具备操作简单、实时、可靠等优点,故注册账号来实现航海王的更新通知。Server酱的注册与使用参见官方网页:http://sc.ftqq.com/3.version。使用过程相对简单,基于SCKEY构建http GET请求,就可以实现消息的推送,基于requests库的测试代码:

1
2
3
4
5
6
7
8
def info():
    r = requests.get("[https://sc.ftqq.com/SCU1034***d799cce138306658*******0b3ffb.send?text=](https://sc.ftqq.com/SCU1034***************d799cce138306658*******0b3ffb.send?text=)主人,航海王更新啦")
    if r.status_code != 200:
      num = random.sample(range(50, 100), 1)
      time.sleep(num)
      info()
    else:
      return True

因为requests.get()网络访问有可能出错,代码中增加冗余操作,即访问失败时,进程睡眠一个随机时间,然后再重新发起request。

五、简单日志系统

程序运行过程中,难免出现各种意外和问题,海贼王的python程序需要增加简单的log功能,方便日后的排错和维护。日志的核心功能就是以一定的格式输出信息到指定的log文件,此处采用logging库。下面是简单的示例代码:

1
2
3
4
5
import logging
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"
logging.basicConfig(filename='my.log', level=logging.DEBUG, format=LOG_FORMAT,datefmt=DATE_FORMAT)
logging.debug("This is a debug log.")

其中的LOG_FORMAT指定日志内容的格式,DATE_FORMAT指定日期的格式,而basicConfig对log系统做简单的配置,比如log日志文件名为my.log,报警信息敏感度等级为DEBUG,最后的logging.debug()方法会将信息输出到my.log文件。每次启动爬虫时,先调用setlog方法后,其他模块就能输出信息到日志文件。

1
2
3
4
5
def setlog():
        LOG_FORMAT="%(asctime)s - %(levelname)s - %(message)s"
        DATE_FORMAT="%m/%d/%Y %H:%M:%S %p"
        logging.basicConfig(filename='/home/example/hanghaiwang/my.log',
        level=logging.DEBUG, format=LOG_FORMAT, datefmt=DATE_FORMAT)

六、打包部署到服务器端

为程序一天24小时都能处于待命爬取数据的状态,不受制于本地机器的开关,比较理想的方式是打包并部署代码到服务器端。云服务器可自行购买,常见的如阿里云和腾讯云,此处以阿里云的Ubuntu服务器为例。简单起见,不考虑python运行环境的隔离,也不考虑自动代码上传和下拉,则只需要三个步骤:

  1. 通过Winscp上传代码、文件到服务器;
  2. 安装chrome浏览器,配置driver;
  3. 配置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
2
#PermitRootLogin   prohibit-password
PermitRootLogin      yes

然后保存配置文件,并且采用命令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
2
3
[global]
index-url = [https://pypi.tuna.tsinghua.edu.cn/simple](https://pypi.tuna.tsinghua.edu.cn/simple)
trusted-host = [pypi.tuna.tsinghua.edu.cn](http://pypi.tuna.tsinghua.edu.cn/)

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 来开启。完成上述的部署后,如果航海王有更新,那么凌晨就会收到微信端的通知: