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与Redis的连接教程
Apr 22 Python
详细介绍Python的鸭子类型
Sep 12 Python
python音频处理用到的操作的示例代码
Oct 27 Python
Python实现统计给定字符串中重复模式最高子串功能示例
May 16 Python
Python 比较文本相似性的方法(difflib,Levenshtein)
Oct 15 Python
Pandas过滤dataframe中包含特定字符串的数据方法
Nov 07 Python
python 多线程将大文件分开下载后在合并的实例
Nov 09 Python
在pandas多重索引multiIndex中选定指定索引的行方法
Nov 16 Python
python 实现返回一个列表中出现次数最多的元素方法
Jun 11 Python
Python有参函数使用代码实例
Jan 06 Python
python+selenium+PhantomJS抓取网页动态加载内容
Feb 25 Python
Python卷积神经网络图片分类框架详解分析
Nov 07 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和XSL stylesheets转换XML文档
2006/10/09 PHP
php中$this->含义分析
2009/11/29 PHP
phpmyadmin导入(import)文件限制的解决办法
2009/12/11 PHP
php中HTTP_REFERER函数用法实例
2014/11/21 PHP
yii2.0数据库迁移教程【多个数据库同时同步数据】
2016/10/08 PHP
PHP设计模式概论【概念、分类、原则等】
2020/05/01 PHP
一个加密JavaScript的开源工具PACKER2.0.2
2006/11/04 Javascript
通过DOM脚本去设置样式信息
2010/09/19 Javascript
javascript内置对象arguments详解
2014/03/16 Javascript
node.js中watch机制详解
2014/11/17 Javascript
jQuery菜单插件用法实例
2015/07/25 Javascript
探讨JavaScript中的Rest参数和参数默认值
2015/07/29 Javascript
Jquery 全选反选实例代码
2015/11/19 Javascript
js跨浏览器的事件侦听器和事件对象的使用方法
2015/12/17 Javascript
JavaScript学习笔记之数组去重
2016/03/23 Javascript
JQuery EasyUI Layout 在from布局自适应窗口大小的实现方法
2016/05/28 Javascript
ionic实现可滑动的tab选项卡切换效果
2020/04/15 Javascript
详解webpack+es6+angular1.x项目构建
2017/05/02 Javascript
JS自定义函数实现时间戳转换成date的方法示例
2017/08/27 Javascript
vue-router 路由基础的详解
2017/10/17 Javascript
利用Node.js批量抓取高清妹子图片实例教程
2018/08/02 Javascript
js的继承方法小结(prototype、call、apply)(推荐)
2019/04/17 Javascript
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
[01:25]DOTA2超级联赛专访iG 将调整状态找回自己
2013/06/05 DOTA
基于python绘制科赫雪花
2018/06/22 Python
python+numpy+matplotalib实现梯度下降法
2018/08/31 Python
flask-restful使用总结
2018/12/04 Python
自荐信怎么写好
2013/11/11 职场文书
清正廉洁演讲稿
2014/05/22 职场文书
技校毕业生自荐信
2014/06/03 职场文书
离婚协议书怎么写
2014/09/12 职场文书
纪念九一八事变83周年国旗下讲话稿
2014/09/15 职场文书
2015年工会工作总结范文
2015/07/23 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
解决tk mapper 通用mapper的bug问题
2021/06/16 Java/Android
ubuntu安装jupyter并设置远程访问的实现
2022/03/31 Python