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中处理字符串之ljust()方法的使用简介
May 19 Python
python shell根据ip获取主机名代码示例
Nov 25 Python
python导出chrome书签到markdown文件的实例代码
Dec 27 Python
python构建深度神经网络(续)
Mar 10 Python
python实现写数字文件名的递增保存文件方法
Oct 25 Python
python实现视频分帧效果
May 31 Python
通过pycharm使用git的步骤(图文详解)
Jun 13 Python
树莓派安装OpenCV3完整过程的实现
Oct 10 Python
python爬虫把url链接编码成gbk2312格式过程解析
Jun 08 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
Jul 02 Python
基于python实现计算两组数据P值
Jul 10 Python
python uuid生成唯一id或str的最简单案例
Jan 13 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
php检查页面是否被百度收录
2015/10/28 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
URL地址中的#符号使用说明
2011/02/12 Javascript
基于jquery实现的定时显示与隐藏div广告的实现代码
2013/08/22 Javascript
Google (Local) Search API的简单使用介绍
2013/11/28 Javascript
jquery live()调用不存在的解决方法
2014/02/26 Javascript
node.js中的fs.lchmodSync方法使用说明
2014/12/16 Javascript
Node.js编程中客户端Session的使用详解
2015/06/23 Javascript
jQuery实现的指纹扫描效果实例(附演示与demo源码下载)
2016/01/26 Javascript
js改变透明度实现轮播图的算法
2020/08/24 Javascript
ThinkJS中如何使用MongoDB的CURD操作
2016/12/13 Javascript
js实现延迟加载的几种方法
2017/04/24 Javascript
Angular2.js实现表单验证详解
2017/06/23 Javascript
JS删除数组里的某个元素方法
2018/02/03 Javascript
JS调用安卓手机摄像头扫描二维码
2018/10/16 Javascript
JS highcharts实现动态曲线代码示例
2020/10/16 Javascript
python网络编程学习笔记(三):socket网络服务器
2014/06/09 Python
Python正则表达式经典入门教程
2017/05/22 Python
Python闭包思想与用法浅析
2018/12/27 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
python numpy之np.random的随机数函数使用介绍
2019/10/06 Python
numpy.linalg.eig() 计算矩阵特征向量方式
2019/11/29 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
设置jupyter中DataFrame的显示限制方式
2020/04/12 Python
IntelliJ 中配置 Anaconda的过程图解
2020/06/01 Python
Joules官网:女士、男士和儿童服装和鞋类
2018/10/23 全球购物
介绍java中初始化块的使用
2012/09/11 面试题
GC是什么?为什么要有GC?
2013/12/08 面试题
成人毕业生自我鉴定
2013/10/18 职场文书
销售员岗位职责范本
2014/02/03 职场文书
毕业生自荐书
2014/02/03 职场文书
幼儿园小班见习报告
2014/10/31 职场文书
行政主管岗位职责
2015/02/03 职场文书
教师反邪教心得体会
2016/01/15 职场文书
教你怎么用PyCharm为同一服务器配置多个python解释器
2021/05/31 Python
instantclient客户端 连接oracle数据库
2022/04/26 Oracle