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中的super()方法使用简介
Aug 14 Python
不同版本中Python matplotlib.pyplot.draw()界面绘制异常问题的解决
Sep 24 Python
详解重置Django migration的常见方式
Feb 15 Python
Python基础之文件读取的讲解
Feb 16 Python
Django学习笔记之为Model添加Action
Apr 30 Python
Python搭建代理IP池实现获取IP的方法
Oct 27 Python
浅谈Pycharm最有必要改的几个默认设置项
Feb 14 Python
150行Python代码实现带界面的数独游戏
Apr 04 Python
基于Python+QT的gui程序开发实现
Jul 03 Python
django 将自带的数据库sqlite3改成mysql实例
Jul 09 Python
使用Python提取文本中含有特定字符串的方法示例
Dec 09 Python
Python 解决空列表.append() 输出为None的问题
May 23 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
MYSQL环境变量设置方法
2007/01/15 PHP
php中使用preg_match_all匹配文章中的图片
2013/02/06 PHP
PHP中使用cURL实现Get和Post请求的方法
2013/03/13 PHP
PHP 循环删除无限分类子节点的实现代码
2013/06/21 PHP
Javascript 写的简单进度条控件
2008/01/22 Javascript
javascript onmouseout 解决办法
2010/07/17 Javascript
动态加载JS文件的三种方法
2013/11/08 Javascript
JavaScript阻止事件冒泡示例分享
2014/12/28 Javascript
数据结构中的各种排序方法小结(JS实现)
2016/07/23 Javascript
js实现PC端和移动端刮卡效果
2020/03/27 Javascript
jQuery中ajax获取数据赋值给页面的实例
2017/12/31 jQuery
JS实现访问DOM对象指定节点的方法示例
2018/04/04 Javascript
vue单页面应用打开新窗口显示跳转页面的实例
2018/09/21 Javascript
vuejs+element UI点击编辑表格某一行时获取内容填入表单的示例
2018/10/31 Javascript
微信小程序使用swiper组件实现层叠轮播图
2018/11/04 Javascript
微信小程序实现随机验证码功能
2018/12/20 Javascript
JS实现li标签的删除
2019/04/12 Javascript
JavaScript运行机制实例分析
2020/04/11 Javascript
微信小程序自定义modal弹窗组件的方法详解
2020/12/20 Javascript
[51:17]Mski vs VGJ.S Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
[00:43]魔廷新尊——痛苦女王至宝捆绑包
2020/06/12 DOTA
解决python2.7 查询mysql时出现中文乱码
2016/10/09 Python
Python多重继承的方法解析执行顺序实例分析
2018/05/26 Python
使用python进行文本预处理和提取特征的实例
2018/06/05 Python
Python基于Opencv来快速实现人脸识别过程详解(完整版)
2019/07/11 Python
如何使用Flask-Migrate拓展数据库表结构
2019/07/24 Python
Windows 平台做 Python 开发的最佳组合(推荐)
2020/07/27 Python
骆驼官方商城:CAMEL
2016/11/22 全球购物
销售高级职员求职信
2013/10/29 职场文书
最新大学职业规划书范文
2013/12/30 职场文书
一年级学生期末评语
2014/04/21 职场文书
党的群众路线教育实践活动个人对照检查材料(四风)
2014/11/05 职场文书
2014年结对帮扶工作总结
2014/12/17 职场文书
委托书范本格式
2019/04/18 职场文书
sql字段解析器的实现示例
2021/06/23 SQL Server
通过Qt连接OpenGauss数据库的详细教程
2021/06/23 PostgreSQL