python实现的一个火车票转让信息采集器


Posted in Python onJuly 09, 2014

好吧,我承认我是对晚上看到一张合适的票转让但打过电话去说已经被搞走了这件事情感到蛋疼。直接上文件吧。

#coding: utf-8
'''
春运查询火车票转让信息
Author: piglei2007@gmail.com
Date: 2011.01.25
'''
import re
import os
import time
import urlparse
import datetime
import traceback
import urllib2
import socket
socket.setdefaulttimeout(20)

BLANK_RE = re.compile(r"\s+")

opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
opener.addheaders = [
  ("User-agent", "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.1) Gecko/20090704 Firefox/3.5"),
  ("Accept", "*/*"),
]
urllib2.install_opener(opener)

from BeautifulSoup import BeautifulSoup

SOURCE = {
  "58": "http://bj.58.com/huochepiao/?Num=%(train)s&StartTime=%(date)s00",
  "ganji": "http://bj.ganji.com/piao/cc_%(train)s/%(date)s/",
}
RECORD_FILE = "/tmp/ticket_records.txt"

def parse_record():
  try:
    return set([x.strip() for x in open(RECORD_FILE, "r").readlines()])
  except IOError:
    open(RECORD_FILE, "w")
    return set()

def flush_record(records):
  open(RECORD_FILE, "w").write("\n".join(records))

def main(config):
  """
  开始抓取
  """
  existed = parse_record()
  to_email = []

  for train in config["trains"]:
    for date in config["dates"]:
      for type, _url in SOURCE.items():
        url = _url % dict(train=train, date=date)
        content = urllib2.urlopen(url).read()
        soup = BeautifulSoup(content)
        result = parse_content(type, soup, train)
        for url, text in result:
          url = urlparse.urljoin(_url, url)
          # 只要卧铺!
          if url not in existed and u"卧" in text:
            to_email.append([text, url])
          existed.add(url)
  if to_email:
    content = "".join(
      [x for x in [" | ".join(y) for y in to_email]]
    ).encode("utf-8")
    simple_mail(config["people"], content)
  flush_record(existed)

def parse_content(type, soup, train):
  """
  获得车次信息
  """
  result = []
  if type == "58":
    info_table = soup.find("table", id="infolist")
    if info_table:
      for x in info_table.findAll("tr", text=re.compile(ur"%s(?!时刻表)" % train, re.I)):
        a = x.parent
        _text = BLANK_RE.sub("", a.text)
        result.append([a["href"], _text])
  if type == "ganji":
    for x in soup.findAll("dl", {"class": "list_piao"}):
      a = x.dt.a
      result.append([a["href"], a.text])
  return result

EMAIL_HOST = 'smtp.sohu.com'
EMAIL_HOST_USER = 'yourname@sohu.com'
EMAIL_HOST_PASSWORD = 'yourpassword'
EMAIL_PORT = 25

def simple_mail(to, content):
  """
  发送邮件
  """
  import smtplib
  from email.mime.text import MIMEText

  msgRoot = MIMEText(content, 'html', 'UTF-8')
  msgRoot['Subject'] = "[%s]有票来啦!!!!" % datetime.datetime.today().isoformat(" ")
  msgRoot['From'] = EMAIL_HOST_USER
  msgRoot['To'] = ", ".join(to)

  s = smtplib.SMTP(EMAIL_HOST, EMAIL_PORT)
  s.login(EMAIL_HOST_USER, EMAIL_HOST_PASSWORD)
  s.sendmail(EMAIL_HOST_USER, to, msgRoot.as_string())
  s.close()

def switch_time_zone():
  """
  切换时区
  """
  os.environ["TZ"] = "Asia/Shanghai"
  time.tzset()

switch_time_zone()

if __name__ == '__main__':
  config = {
    "trains": ("k471",),
    "dates": ("20110129",),
    "people": (
      "youremail@sohu.com",
    )
  }
  try:
    main(config)
    print "%s: ok" % datetime.datetime.today()
  except Exception, e:
    print traceback.format_exc()

然后放入cron,你懂的。

Python 相关文章推荐
python多线程threading.Lock锁用法实例
Nov 01 Python
使用Python对IP进行转换的一些操作技巧小结
Nov 09 Python
Python+Opencv识别两张相似图片
Mar 23 Python
Ubuntu 下 vim 搭建python 环境 配置
Jun 12 Python
python中Pycharm 输出中文或打印中文乱码现象的解决办法
Jun 16 Python
详谈Python高阶函数与函数装饰器(推荐)
Sep 30 Python
对python同一个文件夹里面不同.py文件的交叉引用方法详解
Dec 15 Python
让你Python到很爽的加速递归函数的装饰器
May 26 Python
python实现拉普拉斯特征图降维示例
Nov 25 Python
python3 assert 断言的使用详解 (区别于python2)
Nov 27 Python
用Python做一个久坐提醒小助手的示例代码
Feb 10 Python
Python3监控windows,linux系统的CPU、硬盘、内存使用率和各个端口的开启情况详细代码实例
Mar 18 Python
python的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享
Jul 09 #Python
Python中__init__和__new__的区别详解
Jul 09 #Python
Python中使用logging模块代替print(logging简明指南)
Jul 09 #Python
Python中的魔法方法深入理解
Jul 09 #Python
gearman的安装启动及python API使用实例
Jul 08 #Python
python实现跨文件全局变量的方法
Jul 07 #Python
Python中的并发编程实例
Jul 07 #Python
You might like
ThinkPHP跳转页success及error模板实例教程
2014/07/17 PHP
浅谈PHP链表数据结构(单链表)
2016/06/08 PHP
php强制下载文件函数
2016/08/24 PHP
使用jQuery Ajax功能时需要注意的一个问题(内存溢出)
2012/05/30 Javascript
用js判断页面刷新或关闭的方法(onbeforeunload与onunload事件)
2012/06/22 Javascript
jsvascript图像处理—(计算机视觉应用)图像金字塔
2013/01/15 Javascript
Javascript 垃圾收集机制介绍理解
2013/05/14 Javascript
JS操作Cookie写入和读取实例代码
2013/10/20 Javascript
javascript loadScript异步加载脚本示例讲解
2013/11/14 Javascript
jQuery获取对象简单实现方法小结
2014/10/30 Javascript
javascript实现全局匹配并替换的方法
2015/04/27 Javascript
javascript数组随机排序实例分析
2015/07/22 Javascript
小议JavaScript中Generator和Iterator的使用
2015/07/29 Javascript
js实现页面a向页面b传参的方法
2016/05/29 Javascript
JS实现将数字金额转换为大写人民币汉字的方法
2016/08/02 Javascript
jQuery实现圣诞节礼物传送(花式轮播)
2016/12/25 Javascript
js仿网易表单及时验证功能
2017/03/07 Javascript
[03:49]显微镜下的DOTA2第十五期—VG登基之路完美团
2014/06/24 DOTA
Python高级应用实例对比:高效计算大文件中的最长行的长度
2014/06/08 Python
浅谈pycharm出现卡顿的解决方法
2018/12/03 Python
对python:print打印时加u的含义详解
2018/12/15 Python
对python使用telnet实现弱密码登录的方法详解
2019/01/26 Python
Python实现的微信支付方式总结【三种方式】
2019/04/13 Python
Django使用redis缓存服务器的实现代码示例
2019/04/28 Python
解决安装python3.7.4报错Can''t connect to HTTPS URL because the SSL module is not available
2019/07/31 Python
如何理解Python中包的引入
2020/05/29 Python
python 实现压缩和解压缩的示例
2020/09/22 Python
体育专业学生自我评价范文
2014/01/17 职场文书
小区文明倡议书
2014/05/16 职场文书
教师节活动总结
2014/08/29 职场文书
2015公务员试用期工作总结
2014/12/12 职场文书
英文感谢信范文
2015/01/21 职场文书
2015年秋季小班开学寄语
2015/05/27 职场文书
利用python做数据拟合详情
2021/11/17 Python
分析SQL窗口函数之排名窗口函数
2022/04/21 Oracle
Android开发手册自定义Switch开关按钮控件
2022/06/10 Java/Android