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连接字符串的方法小结
Jul 13 Python
Python实现将DOC文档转换为PDF的方法
Jul 25 Python
利用Python如何生成随机密码
Apr 20 Python
Python中格式化format()方法详解
Apr 01 Python
详解Python实现多进程异步事件驱动引擎
Aug 25 Python
浅谈Python对内存的使用(深浅拷贝)
Jan 17 Python
Pycharm 设置默认头的图文教程
Jan 17 Python
如何利用python给图片添加半透明水印
Sep 06 Python
python3 使用Opencv打开USB摄像头,配置1080P分辨率的操作
Dec 11 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
Jun 27 Python
使用keras框架cnn+ctc_loss识别不定长字符图片操作
Jun 29 Python
Python基础之hashlib模块详解
May 06 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
使用 laravel sms 构建短信验证码发送校验功能
2017/11/06 PHP
Javascript 判断Flash是否加载完成的代码
2010/04/12 Javascript
JavaScript实现维吉尼亚(Vigenere)密码算法实例
2013/11/22 Javascript
利用JQuery制作符合Web标准的QQ弹出消息
2014/01/14 Javascript
javascript操作字符串的原生方法
2014/12/22 Javascript
angularjs在ng-repeat中使用ng-model遇到的问题
2016/01/21 Javascript
简介BootStrap model弹出框的使用
2016/04/27 Javascript
onclick和onblur冲突问题的快速解决方法
2016/04/28 Javascript
Vue.js学习示例分享
2017/02/05 Javascript
vue.js事件处理器是什么
2017/03/20 Javascript
jQuery实现对网页节点的增删改查功能示例
2017/09/18 jQuery
使用原生js封装的ajax实例(兼容jsonp)
2017/10/12 Javascript
vue自定义过滤器创建和使用方法详解
2017/11/06 Javascript
简单的Vue异步组件实例Demo
2017/12/27 Javascript
bing Map 在vue项目中的使用详解
2018/04/09 Javascript
JS 数组随机洗牌的实例代码
2018/09/12 Javascript
微信小程序实现时间进度条功能
2020/11/17 Javascript
jquery实现烟花效果(面向对象)
2020/03/10 jQuery
Python+Django在windows下的开发环境配置图解
2009/11/11 Python
Python smallseg分词用法实例分析
2015/05/28 Python
Python语言描述连续子数组的最大和
2018/01/04 Python
全面分析Python的优点和缺点
2018/02/07 Python
pandas的object对象转时间对象的方法
2018/04/11 Python
Python基础之字典常见操作经典实例详解
2020/02/26 Python
Python基于unittest实现测试用例执行
2020/11/25 Python
基于zepto的插件之移动端无缝向上滚动并上下触摸滑动实例代码
2016/12/20 HTML / CSS
Html5页面内使用JSON动画的实现
2019/01/29 HTML / CSS
七一表彰活动方案
2014/01/18 职场文书
金融与证券专业求职信
2014/06/22 职场文书
工作散漫检讨书
2014/09/16 职场文书
软件研发工程师岗位职责
2014/09/30 职场文书
给上级领导的感谢信
2015/01/22 职场文书
Python中json.dumps()函数的使用解析
2021/05/17 Python
详解Oracle块修改跟踪功能
2021/11/07 Oracle
分析Python list操作为什么会错误
2021/11/17 Python
一级电子管军用接收机测评
2022/04/05 无线电