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使用clear方法清除字典内全部数据实例
Jul 11 Python
Python中的异常处理相关语句基础学习笔记
Jul 11 Python
PyTorch上实现卷积神经网络CNN的方法
Apr 28 Python
使用Python监视指定目录下文件变更的方法
Oct 15 Python
在IPython中进行Python程序执行时间的测量方法
Nov 01 Python
python3实现钉钉消息推送的方法示例
Mar 14 Python
Python代码太长换行的实现
Jul 05 Python
python树的同构学习笔记
Sep 14 Python
numpy 声明空数组详解
Dec 05 Python
python 获取字典键值对的实现
Nov 12 Python
Python监听键盘和鼠标事件的示例代码
Nov 18 Python
tensorboard 可视化之localhost:6006不显示的解决方案
May 22 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
基于HTTP长连接的"服务器推"技术的php 简易聊天室
2009/10/31 PHP
php存储过程调用实例代码
2013/02/03 PHP
php制作基于xml的RSS订阅源功能示例
2017/02/08 PHP
浅谈Laravel队列实现原理解决问题记录
2017/08/19 PHP
laravel利用中间件做防非法登录和权限控制示例
2019/10/21 PHP
laravel 解决paginate查询多个字段报错的问题
2019/10/22 PHP
“不能执行已释放的Script代码”错误的原因及解决办法
2007/09/09 Javascript
JQuery实现自定义对话框的代码
2008/06/15 Javascript
基于jQuery的消息提示插件之旅 DivAlert(三)
2010/04/01 Javascript
修改jquery.lazyload.js实现页面延迟载入
2010/12/22 Javascript
JavaScript之编码规范 推荐
2012/05/23 Javascript
JavaScript在for循环中绑定事件解决事件参数不同的情况
2014/01/20 Javascript
JavaScript中的包装对象介绍
2015/01/27 Javascript
神级程序员JavaScript300行代码搞定汉字转拼音
2017/05/20 Javascript
Kindeditor单独调用多图上传实例
2017/07/31 Javascript
深入理解ES7的async/await的用法
2017/09/09 Javascript
浅谈react 同构之样式直出
2017/11/07 Javascript
微信小程序实现简单评论功能
2018/11/28 Javascript
vue 的 solt 子组件过滤过程解析
2019/09/07 Javascript
js实现表格单列按字母排序
2020/08/12 Javascript
Jquery+javascript实现支付网页数字键盘
2020/12/21 jQuery
[01:45]2014DOTA2 TI预选赛预选赛 大神专访第二弹!
2014/05/20 DOTA
python脚本实现数据导出excel格式的简单方法(推荐)
2016/12/30 Python
python 调用win32pai 操作cmd的方法
2017/05/28 Python
python中Switch/Case实现的示例代码
2017/11/09 Python
Python解决两个整数相除只得到整数部分的实例
2018/11/10 Python
导入tensorflow:ImportError: libcublas.so.9.0 报错
2020/01/06 Python
意大利单身交友网站:Meetic
2020/07/12 全球购物
医药工作岗位求职信分享
2013/12/31 职场文书
《我爱祖国》演讲稿1000字
2014/09/26 职场文书
结婚保证书(三从四德)
2015/02/26 职场文书
工作失职自我检讨书
2015/05/05 职场文书
幸福来敲门观后感
2015/06/04 职场文书
餐馆开业致辞
2015/08/01 职场文书
MySQL常见优化方案汇总
2022/01/18 MySQL
uni-app 微信小程序授权登录的实现步骤
2022/02/18 Javascript