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实现服务器中只重载被修改的进程的方法
Apr 30 Python
python追加元素到列表的方法
Jul 28 Python
Python 专题一 函数的基础知识
Mar 16 Python
详解Python文本操作相关模块
Jun 22 Python
python opencv设置摄像头分辨率以及各个参数的方法
Apr 02 Python
Python之dict(或对象)与json之间的互相转化实例
Jun 05 Python
Python中GIL的使用详解
Oct 03 Python
python2 中 unicode 和 str 之间的转换及与python3 str 的区别
Jul 25 Python
python如何安装下载后的模块
Jul 03 Python
Python3以GitHub为例来实现模拟登录和爬取的实例讲解
Jul 30 Python
Python+OpenCV图像处理——图像二值化的实现
Oct 24 Python
Python内置类型集合set和frozenset的使用详解
Apr 26 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 在线导入mysql大数据程序
2015/06/11 PHP
PHP递归遍历指定文件夹内的文件实现方法
2016/11/15 PHP
DWZ+ThinkPHP开发时遇到的问题分析
2016/12/12 PHP
PHP常用的类封装小结【4个工具类】
2019/06/28 PHP
PHP简单实现图片格式转换(jpg转png,gif转png等)
2019/10/30 PHP
js控制分页打印、打印分页示例
2014/02/08 Javascript
JavaScript strike方法入门实例(给字符串加上删除线)
2014/10/17 Javascript
jQuery与getJson结合的用法实例
2015/08/07 Javascript
JS鼠标拖拽实例分析
2015/11/23 Javascript
Angularjs 实现一个幻灯片示例代码
2016/09/08 Javascript
jQuery中on方法使用注意事项详解
2017/02/15 Javascript
Bootstrap fileinput组件封装及使用详解
2017/03/10 Javascript
限时抢购-倒计时的完整实例(分享)
2017/09/17 Javascript
详解关于Vue2.0路由开启keep-alive时需要注意的地方
2018/09/18 Javascript
在小程序Canvas中使用measureText的方法示例
2018/10/19 Javascript
trackingjs+websocket+百度人脸识别API实现人脸签到
2018/11/26 Javascript
原生JavaScript实现轮播图
2021/01/10 Javascript
[49:35]LGD vs OG 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
python笔记(2)
2012/10/24 Python
Python压缩和解压缩zip文件
2015/02/14 Python
python妹子图简单爬虫实例
2015/07/07 Python
Python使用Redis实现作业调度系统(超简单)
2016/03/22 Python
Python 类的继承实例详解
2017/03/25 Python
学习python中matplotlib绘图设置坐标轴刻度、文本
2018/02/07 Python
Python内置函数reversed()用法分析
2018/03/20 Python
一百多行python代码实现抢票助手
2018/09/25 Python
Python多进程写入同一文件的方法
2019/01/14 Python
顶岗实习接收函
2014/01/09 职场文书
家长给老师的道歉信
2014/01/13 职场文书
关于护士节的演讲稿
2014/05/26 职场文书
机关作风建设心得体会
2014/10/22 职场文书
幽灵公主观后感
2015/06/09 职场文书
企业法人任命书
2015/09/21 职场文书
股权投资协议书
2016/03/23 职场文书
《思路决定出路》读后感3篇
2019/12/11 职场文书
Nginx搭建rtmp直播服务器实现代码
2021/03/31 Servers