BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / python / #4487同步于 2014/12/4
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖

【不知道该起什么题目了】基于图书馆的定时任务爬虫

WTF
2014/12/4镜像同步1 回复
背景: 啦啦啦啦,之所以有这个想法,是因为经常用学校的图书馆管理系统(大学经典毕设题目),使用的过程中,发现用户体验特别不好(好吧,我不是产品经理),有下面几个痛点(我不是产品经理too) 1:这酸爽的界面风格,真心也是醉了 2:在搜索引擎中搜索“北京邮电大学图书馆”,给出的链接是http://lib.bupt.edu.cn/ (话说界面很漂亮啊,喂),然后我们搜索一本python书籍,发现给出的连接是以这个开头的http://211.68.68.197/opac_two/search2/searchout.jsp? 截止到现在,是访问不了的,前段时间还是能够访问的,但是请求一本书的状态的响应时间非常长,简直不能忍,能够到达1分钟49秒(没图你说个pp,因为访问不了,所以没图) 3:在图书馆借书,一般情况,我们是有目标的,比如我就想借《python基础编程》,所以我不care描述啊,豆瓣作者简介啊,豆瓣内容简介啊,载体形态啊,借阅次数啊,收藏次数啊,参看次数啊,balabala……,我只关心有没有书在架子上,我要借书啊,而且图书馆基本上每周都有新书上架,我要知道新书什么时候能借 好了,针对上面的痛点,下面是解决方案: 解决方案: 针对痛点1:重新去设计界面,我前端不大好喂,所以也请大牛来共同开发 针对痛点2:偶然的机会,在图书馆用那个终端,瞄了一眼地址栏,发现了新网址:http://10.106.0.4/opac_two/search2/search.jsp,所以同学们还是用这个网址吧 针对痛点3:劝你能不去借书就别去借书了,还是自己买书吧(有钱就是任性),但是对于我这种没钱的屌丝(没钱就得任命吗?)还是每个月都会光临图书馆的(书非借不读也,啦啦啦),然后我只需要知道当前我关心的书籍能不能借,凑巧有个接口:http://10.106.0.4/opac_two/guancang.do?rec_ctrl_id=01h0290668 我只需要把书的id传进去即可,就一目了然了,然后再写个定时任务每小时爬一次状态,然后如果书可借了,就发邮件通知我,这就够了。啦啦啦 所以我想设计一个基于图书馆的demo(有兴趣的一起搞啊) demo目标(我不是pm,所以表达起来有点混乱,不知道合不合你的胃口): 1:前台界面初定采用bootstrap(虽然我现在还不会用) 2:提供搜索功能(接口都是现成的) 3:提供预约功能(接口现成的,但是需要提供账户和密码,这个可以放在最后设计) 4:提供针对每个用户添加自己感兴趣的书到任务队列,任务队列中会去每天10点到19点每个小时去查询书的状态,如果在架可借,则邮件通知此人,任务队列中的任务的定时设置可以更加灵活,因为周二上新书,每天中午和下午吃饭的时候是大家还书的集中期,所以可以设置频繁的去查询(例如每5分钟) 3:欢迎你来补充 现在实现的部分: 定时任务查询,查询数据库,然后查询每本书的状态,如果状态可借,则发邮件通知我自己(话说离着目标好远啊,喂,骚年继续努力啊) 下面奉上实现的代码,说了这么多,提供点建议呗,谢谢 #coding: utf-8 import sys,urllib,urllib2,re,sched,json,time,copy reload(sys) sys.setdefaultencoding('utf-8') from sqlalchemy import create_engine db=create_engine('mysql+mysqldb://root:root@127.0.0.1:3306/buptlib?charset=utf8',echo=True) from sqlalchemy.ext.declarative import declarative_base Base=declarative_base() from sqlalchemy import Column,Integer,String class Book(Base): __tablename__='book' sid=Column(String(10),primary_key=True) title=Column(String(200)) searchno=Column(String(20)) status=Column(String(10)) def __init__(self,sid,title,searchno=None,status=u'不可借'):#暂不考虑预约人数,后加 self.sid=sid self.title=title self.searchno=searchno self.status=status def __unicode__(self): return self.title+"--"+self.searchno+"--"+self.status def __repr__(self): return self.__unicode__() # Base.metadata.create_all(db) from sqlalchemy.orm import sessionmaker Session=sessionmaker(bind=db) session=Session() import urllib2,urllib,re,smtplib,sys,base64 from email.mime.text import MIMEText def send_mail(book):#发邮件 mail_server='smtp.qq.com' user_name='********' pwd='********' from_addr='*******' to_addr=['****@126.com'] subject='《'+book.title+'》已在架可借,请速速去借!' text='您好,您关注的书:《'+book.title+'》已在架可借,请速速去借!索引号是:'+book.searchno msg=MIMEText(text,_charset='utf-8') msg['Subject']=subject smtp=smtplib.SMTP() smtp.connect(mail_server) smtp.login(user_name,pwd) smtp.sendmail(from_addr,to_addr,msg.as_string()) smtp.quit() def is_on_the_shelf(book):#是否在架可借 guan_cang_url='http://10.106.0.4/opac_two/guancang.do?rec_ctrl_id=%s'%book.sid url_open=urllib2.urlopen(guan_cang_url,data=None,timeout=60) guan_cang_result=url_open.read() #可能会有异常,暂时不处理 """类似这样的返回结果""" #guan_cang_result='[{"A":[{"accessno":"1568714","book_barcode":"21113002714053","circul_id":"90","circul_status":"库本","department_id":"64","due_date":"","fujian":"","guancang_dept":"样本书阅览室","searchno":"TP311.56/H331=2"},{"accessno":"1568715","book_barcode":"21113002714054","circul_id":"11","circul_status":"在架可借","department_id":"60","due_date":"2014/12/22","fujian":"","guancang_dept":"新书借阅室","searchno":"TP311.56/H331=2"},{"accessno":"1568716","book_barcode":"21113002714055","circul_id":"11","circul_status":"本馆借出","department_id":"60","due_date":"2014/12/20","fujian":"","guancang_dept":"新书借阅室","searchno":"TP311.56/H331=2"},{"accessno":"1568717","book_barcode":"21113002714056","circul_id":"11","circul_status":"本馆借出","department_id":"60","due_date":"2014/12/03","fujian":"","guancang_dept":"新书借阅室","searchno":"TP311.56/H331=2"},{"accessno":"1568718","book_barcode":"21113002714057","circul_id":"11","circul_status":"本馆借出","department_id":"60","due_date":"2014/11/27","fujian":"","guancang_dept":"新书借阅室","searchno":"TP311.56/H331=2"}]}]@<a href=hold.jsp?rec_ctrl_id=01h0289272&library_id=A target=_blank>预约此书</a>@' guan_cang_result= guan_cang_result[0:guan_cang_result.find('@')] #处理返回结果 json_result=json.loads(guan_cang_result) guan_cang_list= json_result[0]["A"] origin_status=book.status#记录之前的状态 book.status=u'不可借' for bk in guan_cang_list: if bk['circul_status']=='在架可借': book.searchno=bk['searchno'] #只有在架可借的时候统计索引号就ok,其他情况下索引号没用 book.status=u'可借' send_mail(book) break print book if origin_status!=book.status: #应该减少数据库的操作,如果现在的book状态和刚才的状态不一样,就更新数据库 session.commit() def schedule_job(): book_list=session.query(Book).all() for book in book_list: is_on_the_shelf(book) from apscheduler.schedulers.background import BackgroundScheduler def main(): scheduler=BackgroundScheduler()#话说apscheduler真好用 scheduler._daemon=False scheduler.add_job(schedule_job,trigger='cron',minute='*/1') scheduler.start() try: while True: time.sleep(1) except (KeyboardInterrupt,SystemError): scheduler.shutdown() if __name__=='__main__': main()
订阅后,新回复会通过你的通知中心匿名送达。
1 条回复
reverland机器人#1 · 2014/12/5
图书馆界面也真是醉了 来自「北邮人论坛手机版」