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 文件和输入输出小结
Oct 09 Python
在Django的通用视图中处理Context的方法
Jul 21 Python
python中根据字符串调用函数的实现方法
Jun 12 Python
Python学习笔记之解析json的方法分析
Apr 21 Python
Win8下python3.5.1安装教程
Jul 29 Python
Python列表(List)知识点总结
Feb 18 Python
python批量识别图片指定区域文字内容
Apr 30 Python
简单了解Pandas缺失值处理方法
Nov 16 Python
TensorFlow中如何确定张量的形状实例
Jun 23 Python
Python的logging模块基本用法
Dec 24 Python
Python-OpenCV教程之图像的位运算详解
Jun 21 Python
Python内置包对JSON文件数据进行编码和解码
Apr 12 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采集腾讯微博的实现代码
2012/01/19 PHP
PHP获取浏览器信息类和客户端地理位置的2个方法
2014/04/24 PHP
php获取URL中带#号等特殊符号参数的解决方法
2014/09/02 PHP
Yii框架登录流程分析
2014/12/03 PHP
yii2使用gridView实现下拉列表筛选数据
2017/04/10 PHP
CSS中一些@规则的用法小结
2021/03/09 HTML / CSS
点击文章内容处弹出页面代码
2009/10/01 Javascript
基于jquery的多彩百分比 动态进度条 投票效果显示效果实现代码
2011/08/28 Javascript
javascript(js)的小数点乘法除法问题详解
2014/03/07 Javascript
innerHTML在IE中报错解决方案
2014/12/15 Javascript
JS获取时间的方法
2015/01/21 Javascript
js完整倒计时代码分享
2016/09/18 Javascript
Angular-Touch库用法示例
2016/12/22 Javascript
bootstrap实现二级下拉菜单效果
2017/11/23 Javascript
JavaScript的数据类型转换原则(干货)
2018/03/15 Javascript
微信小程序实现分享到朋友圈功能
2018/07/19 Javascript
Vue2.0生命周期的理解
2018/08/20 Javascript
vuejs中监听窗口关闭和窗口刷新事件的方法
2018/09/21 Javascript
通过cordova将vue项目打包为webapp的方法
2019/02/02 Javascript
vue实现多条件和模糊搜索功能
2019/05/28 Javascript
深入了解query和params的使用区别
2019/06/24 Javascript
Vue.js组件实现选项卡以及切换特效
2019/07/24 Javascript
机器学习python实战之决策树
2017/11/01 Python
用tensorflow搭建CNN的方法
2018/03/05 Python
Python3获取电脑IP、主机名、Mac地址的方法示例
2019/04/11 Python
Python for循环与getitem的关系详解
2020/01/02 Python
Python 实现自动完成A4标签排版打印功能
2020/04/09 Python
android面试问题与答案
2016/12/27 面试题
超市开店计划书
2014/09/15 职场文书
基层党组织整改方案
2014/10/25 职场文书
会计岗位职责范本
2015/04/02 职场文书
2015迎新晚会开场白
2015/07/17 职场文书
给numpy.array增加维度的超简单方法
2021/06/02 Python
dubbo服务整合zipkin详解
2021/07/26 Java/Android
2022年四月新番
2022/03/15 日漫
Nginx反向代理、重定向
2022/04/13 Servers