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 ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
Jun 10 Python
使用Python脚本对Linux服务器进行监控的教程
Apr 02 Python
Python模拟登录验证码(代码简单)
Feb 06 Python
Python 使用os.remove删除文件夹时报错的解决方法
Jan 13 Python
Django admin实现图书管理系统菜鸟级教程完整实例
Dec 12 Python
matplotlib作图添加表格实例代码
Jan 23 Python
对matplotlib改变colorbar位置和方向的方法详解
Dec 13 Python
nohup后台启动Python脚本,log不刷新的解决方法
Jan 14 Python
python自定义线程池控制线程数量的示例
Feb 22 Python
Python request操作步骤及代码实例
Apr 13 Python
使用python实现微信小程序自动签到功能
Apr 27 Python
python db类用法说明
Jul 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
解析argc argv在php中的应用
2013/06/24 PHP
PHP生成图片验证码、点击切换实例
2014/06/25 PHP
PHP中文乱码解决方案
2015/03/05 PHP
破解Session cookie的方法
2006/07/28 Javascript
创建一个复制UBB软件信息的链接或按钮的js代码
2008/01/06 Javascript
Prototype Selector对象学习
2009/07/23 Javascript
jQuery EasyUI API 中文文档 - Pagination分页
2011/09/29 Javascript
jquery阻止冒泡事件使用模拟事件
2013/09/06 Javascript
javascript实现依次输入input自动定焦
2014/12/23 Javascript
javascript实现根据时间段显示问候语的方法
2015/06/18 Javascript
JavaScript实现跨浏览器的添加及删除事件绑定函数实例
2015/08/04 Javascript
js判断手机号运营商的方法
2015/10/23 Javascript
浅析BootStrap模态框的使用(经典)
2016/04/29 Javascript
react-native 封装选择弹出框示例(试用ios&android)
2017/07/11 Javascript
JS实现点击下拉菜单把选择的内容同步到input输入框内的实例
2018/01/23 Javascript
JavaScript fetch接口案例解析
2018/08/30 Javascript
angularjs使用div模拟textarea文本框的方法
2018/10/02 Javascript
vue实现的双向数据绑定操作示例
2018/12/04 Javascript
详解一次Vue低版本安卓白屏问题的解决过程
2019/05/30 Javascript
vue前后分离调起微信支付
2019/07/29 Javascript
微信小程序 调用远程接口 给全局数组赋值代码实例
2019/08/13 Javascript
JS实现的定时器展示简单秒表、页面弹框及跳转操作完整示例
2020/01/26 Javascript
微信小程序实现分页加载效果
2020/11/19 Javascript
JavaScript实现打字游戏
2021/02/19 Javascript
Python六大开源框架对比
2015/10/19 Python
简单了解django文件下载方式
2020/02/10 Python
python批量修改xml属性的实现方式
2020/03/05 Python
英国布鲁姆精品店:Bloom Boutique
2018/03/01 全球购物
瑜伽国际:Yoga International
2018/04/18 全球购物
加拿大时装零售商:Influence U
2018/12/22 全球购物
华为菲律宾官方网站:HUAWEI Philippines
2021/02/23 全球购物
课堂教学改革实施方案
2014/03/17 职场文书
计算机专业应届生求职信
2014/04/06 职场文书
2014年五四青年节活动策划书
2014/04/22 职场文书
2014小学教师年度考核工作总结
2014/12/03 职场文书
2015年个人实习工作总结
2014/12/12 职场文书