这是 Python Knowledge Weekly(PKW)第 3 期。
'一个人可以失败很多次,但是只要他没有开始责怪旁人,他还不是一个失败者。' "A man can fail many times, but he isn't a failure until he begins to blame somebody else."
一、googletrans 库简介
二、Python 定时任务的几种方式
很多时候,我们会遇到不同的语言之间的翻译问题,最常见的就是英译汉和汉译英了。一般的做法就是打开 Google 翻译来处理,但是很多时候,这种手动的方式既缓慢,又蛮烦,那么使用 googletrans 这个库就是最佳的选择啦。
首先就是先用 pip 下载安装之
1pip install googletrans
下面做一个简单的调用
1from googletrans import Translator
2source = '今天真是个好天气'
3translator = Translator()
4text = translator.translate(source, src='zh-cn', dest='en').text
5print(text)
有木有感觉很简单,接下来就进行实战演练下!
我这里选择的是一个金庸小说网站,准备抓取一篇小说,然后翻译成英文。 网站地址:http://www.jinyongwang.com 我准备抓取的就是《飞狐外传》的第一章节,http://www.jinyongwang.com/fei/484.html。
1def test():
2 baseurl = 'http://www.jinyongwang.com/fei/484.html'
3 text_list = []
4 res = requests.get(baseurl).text # 请求网页
5 content = BeautifulSoup(res, "html.parser") # 使用 bs4 来解析网页
6 div = content.find('div', attrs={'class': 'vcon'}).find_all('p')
7 details = []
8 for p in div:
9 de = p.text
10 details.append(de)
11 print(details)
12 print(len(details))
13 translator = Translator()
14 for t in details: # 每一个列表元素,分别翻译
15 text = translator.translate(t, src='zh-cn', dest='en').text
16 text_list.append(text)
17 print(text_list)
18 return text_list
其实还是继续上面的实战,如果我想定时的去抓取金庸的某些小说然后翻译的,那么这个定时任务就排上用场了。下面就介绍几种处理定时任务的方法
这种方式的核心就是启动一个无限循环,然后用 sleep 来触发操作,详见代码:
1import time
2
3
4def dingshi1():
5 while True:
6 print("time", time.localtime())
7 time.sleep(3)
结果
1time time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=12, tm_sec=51, tm_wday=5, tm_yday=82, tm_isdst=0)
2time time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=12, tm_sec=54, tm_wday=5, tm_yday=82, tm_isdst=0)
3time time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=12, tm_sec=57, tm_wday=5, tm_yday=82, tm_isdst=0)
4time time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=13, tm_sec=0, tm_wday=5, tm_yday=82, tm_isdst=0)
可以看到,每间隔 3 秒,程序执行一次。
Timer 本质上还是调用线程来异步执行程序,所以多个程序之间可以同时执行,不需要等待
1def dingshi2_1():
2 print("2-1 time: ", time.localtime())
3 t = Timer(3, dingshi2_1)
4 t.start()
5
6
7def dingshi2_2():
8 print("2-2 time: ", time.localtime())
9 t = Timer(1, dingshi2_2)
10 t.start()
11
12
13if __name__ == "__main__":
14 dingshi2_1()
15 dingshi2_2()
执行结果
12-1 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=22, tm_sec=57, tm_wday=5, tm_yday=82, tm_isdst=0)
22-2 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=22, tm_sec=57, tm_wday=5, tm_yday=82, tm_isdst=0)
32-2 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=22, tm_sec=58, tm_wday=5, tm_yday=82, tm_isdst=0)
42-2 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=22, tm_sec=59, tm_wday=5, tm_yday=82, tm_isdst=0)
52-1 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=23, tm_sec=0, tm_wday=5, tm_yday=82, tm_isdst=0)
62-2 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=23, tm_sec=0, tm_wday=5, tm_yday=82, tm_isdst=0)
72-2 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=23, tm_sec=1, tm_wday=5, tm_yday=82, tm_isdst=0)
82-2 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=23, tm_sec=2, tm_wday=5, tm_yday=82, tm_isdst=0)
92-1 time: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=23, tm_sec=3, tm_wday=5, tm_yday=82, tm_isdst=0)
可以看到,当 2-2 执行 3 次的时候,2-1 才会执行一次,即 2-2 每 1 秒执行一次,而 2-1 每 3 秒执行一次。
其实对于一些简单的定时任务,上面两种方式已经完全可以实现了,但是如何我们还需要维护一些重量级的,需要持久化的任务,那么这个任务框架的优势就很明显了。
APScheduler 是基于 Quartz 的一个 Python 定时任务框架,实现了Quartz 的所有功能,使用起来十分方便。提供了基于日期、固定时间间隔以及 crontab 类型的任务,并且可以持久化任务。基于这些功能,我们可以很方便的实现一个 Python 定时任务系统。 APScheduler 由四部分组成
包含调度逻辑,每一个作业有它自己的触发器,用于决定接下来哪一个作业会运行。除了他们自己初始配置意外,触发器完全是无状态的。
存储被调度的作业,默认的作业存储是简单地把作业保存在内存中,其他的作业存储是将作业保存在数据库中。一个作业的数据讲在保存在持久化作业存储时被序列化,并在加载时被反序列化。调度器不能分享同一个作业存储。
处理作业的运行,他们通常通过在作业中提交制定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。
是其他的组成部分。你通常在应用只有一个调度器,应用的开发者通常不会直接处理作业存储、调度器和触发器,相反,调度器提供了处理这些的合适的接口。配置作业存储和执行器可以在调度器中完成,例如添加、修改和移除作业。
首先需要使用 pip 来安装
1pip install apscheduler
一个简单的例子:
1def nowtime1():
2 print('time-1: ', time.localtime())
3
4
5def nowtime2():
6 print('time-2: ', time.localtime())
7
8
9def dingshi3():
10 scheduler = BlockingScheduler()
11 scheduler.add_job(nowtime1, 'interval', seconds=3, id='job-1')
12 scheduler.add_job(nowtime2, 'interval', seconds=1, id='job-2')
13 scheduler.start()
14
15
16if __name__ == "__main__":
17 dingshi3()
结果
1time-2: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=34, tm_sec=54, tm_wday=5, tm_yday=82, tm_isdst=0)
2time-2: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=34, tm_sec=55, tm_wday=5, tm_yday=82, tm_isdst=0)
3time-1: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=34, tm_sec=56, tm_wday=5, tm_yday=82, tm_isdst=0)
4time-2: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=34, tm_sec=56, tm_wday=5, tm_yday=82, tm_isdst=0)
5time-2: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=34, tm_sec=57, tm_wday=5, tm_yday=82, tm_isdst=0)
6time-2: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=34, tm_sec=58, tm_wday=5, tm_yday=82, tm_isdst=0)
7time-1: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=34, tm_sec=59, tm_wday=5, tm_yday=82, tm_isdst=0)
8time-2: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=34, tm_sec=59, tm_wday=5, tm_yday=82, tm_isdst=0)
9time-2: time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=35, tm_sec=0, tm_wday=5, tm_yday=82, tm_isdst=0)
这里只是简单的例子,具体还要很多强大的功能,可以查阅官方的文档来学习。
最后,再使用 sleep 来实现延时调用
1def test():
2 baseurl = 'http://www.jinyongwang.com'
3 uri = ['/fei/484.html', '/fei/485.html', '/fei/486.html']
4 text_list = []
5 for i in uri:
6 url = baseurl + i
7 res = requests.get(url).text # 请求网页
8 content = BeautifulSoup(res, "html.parser") # 使用 bs4 来解析网页
9 div = content.find('div', attrs={'class': 'vcon'}).find_all('p')
10 details = []
11 for p in div:
12 de = p.text
13 details.append(de)
14 print('call', i)
15 print(time.localtime())
16 time.sleep(10)
17 return text_list
结果为
call /fei/484.html
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=51, tm_sec=57, tm_wday=5, tm_yday=82, tm_isdst=0)
call /fei/485.html
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=52, tm_sec=7, tm_wday=5, tm_yday=82, tm_isdst=0)
call /fei/486.html
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=13, tm_min=52, tm_sec=17, tm_wday=5, tm_yday=82, tm_isdst=0)