-
Notifications
You must be signed in to change notification settings - Fork 0
Home
陈十七(15071025)
北京工业大学现阶段大部分重要的校发通知、院部通知以及活动海报等均发布在内网统一个人门户(my.bjut.edu.cn)上。许多重要的竞赛、留学通知等均包含在内。然而个人门户只能通过校内网访问,公网访问需要VPN穿透,且查看通知首先需要登录。易用性较差,极易错过时效性强的通知。 为解决上述问题,本小组拟使用爬虫技术从内网获取新闻,并使用微信、邮件和客户端等方式将内容分发给终端用户。从而避免遗漏重要通知。 其中客户端的分发为主动式,用户可以根据兴趣设置实时获取关心的通知。同时使用机器学习结合用户数据,为用户创造兴趣模型,并为用户推送高相关的内容。
看着办吧
信息门户(my.bjut.edu.cn)是工大师生获取校园通知和公告等信息的唯一入口,在师生工作、学习和生活中扮演重要角色。在信息门户的日常使用中,存在着明显的不便之处。
首先,信息门户只能在校园网范围内使用,而且要求用户必须登录网站、以“拉”的方式获取信息。
其次,全校各职能部门和教学、科研单位都在信息门户发布通知和公告,具体到一位老师或同学,必须通过浏览标题才能判断消息是否与自己有关,然后选择是否打开阅读;有时,一两天没有登录信息门户,有可能错过重要通知。
本项目的主要研究意义在于将内网不易获取的信息通过大众常用的媒介转发,使用户可以在手机端便捷地查看,从而减缓信息不对称带来的负面影响。进一步,可以用“推”的方式主动将:用户所选择的、或从用户喜好中学习到的课题,通过针对性推送的方式推荐给用户,智能帮助用户筛选所需要的关键信息。从而大大降低用户获取信息的成本。
网络爬虫技术是收集网络上公开信息的常见技术,国内外对其的研究早已十分深入。常用的搜索引擎采集页面使用的即是爬虫技术。
而微信和邮件通知是当前移动互联网时代用户被动从网络接收信息的主要途径,其方便及时,易于获取,被企业广泛采用。
本项目研究的基本内容,一是将发布于内网的零散、杂乱的信息整合,并通过大众易于接触的微信、邮件等形式分发信息。从而尽量消除因信息不对称所造成的损失。二是通过对用户的习惯学习,给用户推送其感兴趣的定制化消息通知,避免用户付出信息筛选的成本。
基于前述的各种问题点,我们构想了一种分发系统,定时自动抓取内网新通知,整理汇总后通过外网便捷渠道分发,使终端用户易于访问这些内容。
前述的分发系统中,引入了几个新的问题:
校园网登录行为本身,是对用户的校园身份进行验证。有的通知内容不宜或无需面向公网开放的,在本系统不再需要鉴权的前提下,会发生权限问题。如果要求用户输入校园网用户名密码,由于登录原因,密码必须保存原文或者可逆加密。又面临密码保存的安全问题。
如前所述,本服务是采用定时轮询抓取的方式,向校园网服务器请求通知内容,并与上次抓取内容进行比对,进而判断是否有新通知发布。每次查询会对校园网服务器和本服务器造成压力,因此如果轮询过于频繁可能导致服务器压力增加,进而影响服务可用性。
与鉴权相对应,通知的分发范围需要验证。如果对请求分发的用户无条件分发,可能导致服务压力过大。
经过研究,前述的问题可以通过一定的验证回避:
在用户首次登录本服务,要求订阅时,进行一次身份验证。要求用户输入校园网用户名与密码。此时并不保存其凭据,仅使用该凭据到校园网进行一次验证登录,如果登录成功,且该凭据没有被使用过,则判断用户为合法校园用户,将其订阅账号(微信或邮箱等)与其校园网用户名关联,进行存储。推送时按照此列表推送,防止用户数不受控制。
校园通知虽然有一定时效性,但并不需要实时通知,因此可以在轮询间隔上取得一定平衡。约半小时或一小时轮询一次即可防止服务器压力过大。
本系统主要分为抓取、存储、用户登录和分发四部分。其中抓取和存储部署于校内服务器上,登陆与分发需要配合校外公网服务器实现。因内网对外通信按流量计费,此架构可以降低内网服务器对外通信的流量消耗,减小团队的经济压力。
抓取爬虫部分,采用 Python 3 开发。Python 开发爬虫技术成熟,有数量可观的库可供使用。其部署于校内网服务器,定时进行轮询。
存储拟采用 MySQL 数据库存储。在实现过程中,又将内容数据存储和用户数据存储分离。前者无需并发访问,使用轻量的 SQLite 配合 Python 快速实现,共同部署于校内,便于快速访问,并确保数据安全。后者仍然使用 MySQL,部署于公网,与前端配合。
用户登录部分需要实现用户输入与登录验证两部分。均采用 PHP 开发,分别部署于校内校外服务器。登录页进行前端展示与用户凭据获取,使用 WeUI 风格设计,其后调用验证页面进行试登录。验证页面部署于校内服务器,验证通过后写入用户数据库,并回调公网服务器页面展示结果。
通知分发部分部署于公网,采用 PHP 开发。爬虫发现新通知时调用,其再读取订阅用户列表,逐一调用微信或邮件接口完成消息推送。
内网服务器无公网 IP,需要通过 ngrok 服务进行映射,便于通信。
内外服务器均采用 LNMP 方案,即 Linux(CentOS)、Nginx、MySQL、PHP。
爬虫抓取时采用内置的账户登录校园网,并不使用用户输入的凭据。用户凭据仅在注册时使用一次,不存储。
爬虫使用了request库,通过发送POST数据的方式,模拟用户的登录。获取到登录令牌后抓取最新的几条通知并与数据库中已有通知比对,如果发现有新的通知,则使用两种方式尝试调用 newspaper3k 库,对通知链接进行解析,尝试提取正文,去掉辅助元素,提取其主要内容后存入数据库,再调用推送模块进行推送。
校园网采用 cas 集中认证方式,因此模拟登陆时需要先访问 cas 登陆页获取 lt(login token)与execute 值,提取后与用户输入的用户名密码一起发回认证服务器,尝试登录。
登陆成功后 cas 服务器会设置 cookies,写入有效令牌。使用 requests 库的 session 对象维持会话,保持登录状态。
之后调用获取通知的 ajax 接口,请求最新的十条通知数据。此时校园网通知服务器会跳转调用 cas 服务器获取登录状态。cas 服务器检查刚才取得的令牌后返回带校园网通知服务器的登录令牌的 302 跳转,校园网通知服务器再次鉴权成功后返回 json 格式的通知数据。
使用 python 的 json 库处理数据后,调用 SQLite 数据库进行比对,确认有新通知后,通过 json 中返回的 wid 拼组出原文链接,并获取原文网页内容。调用 newspaper3k 库尝试解析html并获取正文内容。限于 newspaper3k 库的编码兼容性问题,提取部分非 my.bjut.edu.cn 网站域名下的通知有时会失败,此时只能将 HTML 全文存入,确保程序正常执行。
解析完成后将通知内容与正文存入数据库以便查阅,完成通知获取。同时调用微信通知模块。
通知模块首先确认已有 token 是否过期,如果过期则连接腾讯服务器获取新的 token。之后向腾讯服务器发送 post 请求,将新通知的内容按照预先设置的模版,逐个通知给前文所述的有效订阅用户,完成通知分发。
微信推送时,将正文内容直接显示在微信推送卡片中,达到无需点击也能查看的效果。
点击推送卡片可以查看原始链接,如果处于校内网环境,且原文发布在 my.bjut.edu.cn 站内,则登录后查看全文。如果原文链接是各院系独立站点上内容,则能否外网查看取决于该院系服务器自身。
经过小范围部署测试,该系统能够正常运行并分发新通知,延迟很小。本系统的实现大大方便了校内重要通知的获取,完全解决了前述所有问题。
但在系统主要部分开发完成后,校园网进行了一次改版,通知地址与数据格式均发生变化。我们作出了一些修正,但校园网新版在试运行中,数据格式仍然有时变化,且服务不太稳定。因此现阶段我们也无法保证服务稳定运行,待校园网状态安定后,我们将统一作出调整。
本系统开发过程中,计算机学院高红雨老师,也就是本项目的指导老师,给予了我们巨大的帮助,提供了校内 VPS 用于部署服务,也给了团队成员很多精神鼓励与支持。在需要各种复杂手续与办事流程时,牺牲休息时间与团队成员配合完成工作,付出了无数辛劳。在此团队成员向高老师致以诚挚谢意。
- 崔辉. 基于校园门户网站新闻通知推送服务的研究[J]. 南京工业职业技术学院学报, 2014, 14(2): 54-56.
- 何世亮. 基于微信公众平台的教务系统的设计与实现[J]. 电子技术与软件工程, 2016 (5): 75-75.