首页 » PHP教程 » 公车及时查询php技巧_公交闹钟

公车及时查询php技巧_公交闹钟

访客 2024-11-09 0

扫一扫用手机浏览

文章目录 [+]

既然能从网站上查询到公交实时信息,是否可以用爬虫帮忙呢? 该当没问题,然后让程序不断的跑,并且设置一个提醒韶光段,比如上班时或者放工时,创造公交离站不远了,提醒自己出发,觉得挺好。

措辞选用强大的 Python,为了避免忘却启动,最好做成做事,Linux 最为方便,不过得有台 Linux 主机,由于平时办公用 Windows,以是选用了做成 Windows 做事。
其余,虽然也可以用操持任务中实行,但设置提醒韶光段不足灵巧

公车及时查询php技巧_公交闹钟

确定了方案,就开始行动吧

公车及时查询php技巧_公交闹钟
(图片来自网络侵删)
实践

只有大略的想法,没有大略的项目,将韶光过程拆分为 获取到站韶光、发送关照、制作做事 和 完善几个部分

获取到站韶光

很多城市都有实时公交的查询网站,例如北京的北京公交集团网站 http://www.bjbus.com,可以查询实时公交信息,选择线路,形式方向,上车站点,就可以得到实时公交的信息。

在浏览其上点击 F12,打开网络选项卡,在网上上点击查询,找到查询要求

可以看到时 GET 要求,网址是:http://www.bjbus.com/home/ajax_rtbus_data.php?act=busTime&selBLine=1&selBDir=5276138694316562750&selBStop=2

要求参数含义为:

act: 查询类型,固定值是 busTimeselBLine: 线路,值表示线路名,例如 1 表示 1 路车selBDir: 行驶方向,值比较繁芜,须要通过实际查询得到selBStop: 上车站点,值为线路在形式方向上的序号,从 1 开始,例如 2 表示第二站

用 httpx, 测试一下

httpx 是基于经典库 requests 实现的,接口更简洁高效,通过 pip install httpx 安装

在 python 环境下,实行

>>> import httpx>>> url = "http://www.bjbus.com/home/ajax_rtbus_data.php?act=busTime&selBLine=1&selBDir=5276138694316562750&selBStop=2">>> r = httpx.get(url)>>> print(r.status_code)200>>> print(r.text)'{"html":"<div class=\"inquiry_header\"><div class=\"left fixed\"> ...

httpx.get 可以发送一个 GET 要求,返回相应工具,status_code 为要求状态编码,text 为相应内容

可以看到,返回的是 JSON 格式数据,通过 httpx 相应工具的 json 方法,可以知道将结果转换为 Python 的词典工具:

>>> ret.json(){'html': '<div class="inquiry_header"><div class="left fixed"><h3 id="lh">1路</h3>< ...

剖析返回的结果,创造在开始部分,就有较为详细的公交实时信息,例如:

<p>最近一辆车间隔此还有 3 站, <span>589</span> 米,估量到站韶光 <span>1</span> 分钟</p>

如果没有车辆信息为:

<p>车辆均已过站</p>

以是只要提取到估量到站韶光数值就可以了

利用 BeautifulSoup 对 html 解析,得到到站韶光:

import httpxfrom bs4 import BeautifulSoup as bs4url = "http://www.bjbus.com/home/ajax_rtbus_data.php?act=busTime&selBLine=1&selBDir=5276138694316562750&selBStop=2"r = httpx.get(url).json()b = bs4(r.get('html'), 'html.parser')info = b.find('article')i = info.find_all('p')[1]ret = re.search(r'\d+(?=\s分钟)', i.text)

BeautifulSoup 可以通过 pip install beautifulsoup4 来安装

引入 BeautifulSoup 库,起个别名 bs4获取要求相应,并转换为词典工具提取词典中的 html 属性,将其转为 BeautifulSoup 工具 b,利用 Python 自带的 html.parser 解析器,其他解析器可能须要安装通过剖析 html 内容,可知有效信息在 article 标签中,通过 find 来获取只包含 article 标签的 BeautifulSoup 工具 info将 info 中的 p 标签提取出来,个中第 2 个(列表第一个元素索引为 0 )元素,便是须要提取的内容,放入 i从 i 中的文本中,利用正则表达式,提取车辆到达分钟数,正则表达式的意思是:匹配有一个或者多个 数字 组成的后面是 空格 和字符 分钟 的数字部分匹配到,返回车辆到达分钟数,返回 None,表示车辆还未发车

上述方法实际上便是一个大略爬虫,反复实行,直到创造得当的韶光,发出提醒,就完成了核心任务

发送关照

发送关照有多种方法,例如 Windows 下弹窗或者,不过在实践中碰着不少困难,以是选用了邮件关照,不仅实现大略,如果在手机上配置了邮件客户端,收到邮件会给出提醒,更加方便

用 Python 很随意马虎发邮件,直接看代码:

import smtplibfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextmsg = MIMEMultipart('alternative') # 实例化email工具msg['from'] = 'tom@example.com' # 对应发件人邮箱昵称、发件人邮箱账号msg['to'] = ';'.join(['lily@example.com']) # 对应收件人邮箱昵称、收件人邮箱账号msg['subject'] = '你好' # 邮件的主题msg.attach(MIMEText('你好,很高兴认识你...', 'html')) # 附加正文SMTP_SERVER = 'smtp.example.com' # 邮箱做事器SSL_PORT = '465' # 端口USER_NAME = 'username' # 邮箱用户名USER_PWD = 'password' # 密码smtp = smtplib.SMTP_SSL(SMTP_SERVER, SSL_PORT) # 邮件做事器地址和端口smtp.ehlo() # 用户认证smtp.login(USER_NAME, USER_PWD) # 括号中对应的是发件人邮箱账号、邮箱密码smtp.sendmail(FROM_MAIL, TO_MAIL, str(msg)) # 收件人邮箱账号、发送邮件smtp.quit() # 等同 smtp.close() ,关闭连接

例如,我收到的一个邮件关照:

制作做事

万事俱备,只欠东风,接下了,须要将脚本做成可实行程序,注册为 Windows 做事

Windows 做事脚本

用 Python 写 须要借助于 win32api 库

安装 win32api 库

pip install pywin32

这是做事脚本框架:

import win32apiimport win32eventimport win32serviceimport win32serviceutilimport servicemanagerclass MyService(win32serviceutil.ServiceFramework): _svc_name_ = "做事名称" _svc_display_name_ = "在做事列表中显示的名称" _svc_description_ = "做事描述" def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.stop_event = win32event.CreateEvent(None, 0, 0, None) def SvcDoRun(self): self.ReportServiceStatus(win32service.SERVICE_START_PENDING) # 这里写做事启动后的业务逻辑 win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) # 这里写做事即将停滞时的业务逻辑 win32event.SetEvent(self.stop_event) self.ReportServiceStatus(win32service.SERVICE_STOPPED)if __name__ == "__main__": if len(sys.argv) == 1: servicemanager.Initialize() servicemanager.PrepareToHostSingle(MyService) servicemanager.StartServiceCtrlDispatcher() else: win32serviceutil.HandleCommandLine(MyService)引入做事干系包定义继续自 win32serviceutil.ServiceFramework 的做事类_svc_name_,_svc_display_name_,_svc_description_ 为做事声明属性做事类初始化 __init__ 方法中, 定义做事停滞事宜,实际运用中可以初始化业务干系的属性SvcDoRun 为做事启动时的回调方法,可以写做事实行中的处理逻辑SvcStop 为做事结束时的回调方法,可以写做事结束时的处理逻辑ReportServiceStatus 为做事状态关照方法,以便做事管理器及时获取到做事状态当脚本实行时,如果没有参数,表示做事在启动,如果有参数,将运行做事管理方法,例如 install(安装)、start(启动)等打包

写好做事代码之后,须要将其打包为 EXE

虽然 上述做事脚本可以不用打包为 EXE 也能注册为做事,但是常常会由于环境、组件引用问题导致注册的做事失落败

Pyinstaller 工具可以将 Python 脚本打包成 Windows 的可实行文件

安装:

pip install pyinstaller

然后可以在命令行中直策应用,例如将 service.py 打包为 EXE:

pyinstaller service.py

打包过程较慢,会有大量信息输出,如果没有报错信息,即为打包成功。

打包成后,会在脚步所在目录创建 build 和 dist 目录,dist 目录下会有打包好的 EXE,名称与脚本名一样

把稳: 打包好的程序,注册做事后,启动时可能会报 win32timezone 找不到的缺点,这时须要加一个参数: –hiddenimport win32timezone 打包命令换成:pyinstaller --hiddenimport win32timezone -F service.py 重新打包即可

注册做事

做好了可实行文件,就可以注册为做事了

首先须要用管理员权限运行命令行

注册做事

service.exe install

注册后,可以在打算机管理的做事,或者从任务管理的做事列表中看到,名称为 脚本中 做事类 _svc_display_name_ 所定义的名称

启动做事

service.exe start

也可以在做事列表中启动

停滞做事

service.exe stop

也可以在做事列表中停滞

注销做事

service.exe remove

注销做事时,须要先停滞做事,不然会有个做事尸体在做事列表中

除了通过 install、start 参数管理做事外,还可以利用 Windows 命令 sc 来操作,有兴趣可以理解下

如果启动做事报错,可以在 Windows 的事宜管理器中查看缺点日志,以便得到详细信息:

完善

从构建公交实时信息爬虫,到启动 Windows 做事,紧张的事情已经完成了,整体跑一遍,至少可以确定方案是可行。

如果要实际运用,还有很多细节问题须要处理

设置提醒韶光段

作为 Windows 做事运行的话,会永劫光处于运行状态,公交提醒功能,只须要在特定事宜段有效就行,以是须要判断当前韶光是否进入提醒韶光窗口, onTime 方法可以做到这一点:

import datetimedef onTime(begin, end): d_time = datetime.datetime.strptime( str(datetime.datetime.now().date())+begin, '%Y-%m-%d%H:%M') d_time1 = datetime.datetime.strptime( str(datetime.datetime.now().date())+end, '%Y-%m-%d%H:%M') n_time = datetime.datetime.now() if n_time > d_time and n_time < d_time1: return True else: return False引入 datetime 经办法接管两个参数,开始韶光和结束韶光,例如”18:00”,”18:30”如果当前韶光段在开始韶光和结束韶光之内,返回 True,否则返回 False

在做事的启动方法中,写一个循环,每次循环判断一下当前韶光,如果 onTime 返回 True 就进入到提醒业务代码中

支持多条线路

同一路车,但是不同方向须要算作不同的线路,以是在提醒方法 run 中,须要同时对多条线路进行判断:

def run(self): for line in self.config.lines: if self.onTime(line['begin'], line['end']): if line.get('needSentMail', True): bustime = self.getBusTime(line) if bustime is not None: if int(bustime) <= int(line.get('latestLeaveMinute', self.config.latestLeaveMinute)): self.mailClient.send_mail(self.config.alertMail, '班车提醒: '+line['line'], '车辆即将到站,现在出发正当时') line['needSentMail'] = False # 发送关照后,不必再发了 else: line['needSentMail'] = True

个中 needSentMail 表示是否须要发送关照,当在韶光窗口中发送了关照,就不必再发了,如果过了韶光窗口,须要将其设置为须要发送

线路配置为列表:

lines = [{ "line": "835快", "dir": "5066222788346588777", "stop": "13", "begin": "08:00", "end": "08:30"}, { "line": "835快", "dir": "4997908670784162973", "stop": "3", "begin": "19:00", "end": "20:30"}]配置

将业务干系信息写去世在代码中不是个好主张,以是须要将关照邮件的配置,线路信息等写到配置中,这样如果业务发生变革时,只需修正下配置文件就可以了,我利用 json 格式的配置文件 config.json:

{ "loopWaitSeconds": 60, "spurtWaitSeconds": 10, "latestLeaveMinute": 5, "mailConfig": { "FROM": "tom@example.com", "HOST": "smtp.example.com", "PORT": "465", "USER": "tom", "PASS": "password", "SSL": true }, "alertMail": "lily@example.com", "lines": [{ "line": "835快", "dir": "5066222788346588777", "stop": "13", "begin": "08:00", "end": "08:30" }, { "line": "835快", "dir": "4997908670784162973", "stop": "3", "begin": "19:00", "end": "20:30" }]}

配置字段比较大略,下面这些须要阐明下:

loopWaitSeconds: 空循环时的等待秒数spurtWaitSeconds: 进入提醒韶光窗口的等待秒数latestLeaveMinute: 可以出发的韶光,即具车辆到站还有多久时,须要发出关照

Python 可以方便的读取 json 配置文件,读取之后,将其转换为一个类,在代码中利用更方便:

class Config: def __init__(self, config): self.loopWaitSeconds = config.get("loopWaitSeconds", 60) self.spurtWaitSeconds = config.get("spurtWaitSeconds", 10) self.mailConfig = config.get("mailConfig", None) self.latestLeaveMinute = config.get("latestLeaveTime", 5) self.lines = config.get("lines", {})import jsonwith open(r"C:\config.json", "r", encoding='UTF-8') as config_file: config = Config(json.load(config_file)) # 整体配置

这里须要把稳的是,配置文件的位置,当程序以做事的形式运行时,当前路径是个临时目录,因此写绝对路径比较方便

总结

虽然办理了问题,不过想要同很多 app 那样优雅,还须要做很多事情。
通过这次实践,可以理解了 Python 打包,Windows 做事,大略爬虫,邮件发送 等功能,为日后做其他运用奠定了根本,比如基于这个框架,可以做一个打卡签到功能,让自己更自由很多时候舒适让我们

标签:

相关文章

今日头条算法岗位面试核心方法与必备知识

大数据、人工智能等技术在各行各业得到了广泛应用。今日头条作为中国领先的资讯平台,其算法技术更是备受关注。今日头条算法岗位面试成为了...

PHP教程 2025-01-31 阅读1 评论0

今日头条算法推送如何打造个化阅读体验

在互联网时代,信息爆炸成为常态,用户获取信息的渠道越来越多,而时间却愈发有限。如何让用户在海量信息中快速找到感兴趣的内容,成为了各...

PHP教程 2025-01-31 阅读1 评论0