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 相关文章推荐
关于你不想知道的所有Python3 unicode特性
Nov 28 Python
Python操作列表之List.insert()方法的使用
May 20 Python
在Python中用keys()方法返回字典键的教程
May 21 Python
Python实现全排列的打印
Aug 18 Python
使用PyCharm创建Django项目及基本配置详解
Oct 24 Python
Python+OpenCV感兴趣区域ROI提取方法
Jan 10 Python
python判断字符串或者集合是否为空的实例
Jan 23 Python
python判断文件是否存在,不存在就创建一个的实例
Feb 18 Python
Python将string转换到float的实例方法
Jul 29 Python
基于nexus3配置Python仓库过程详解
Jun 15 Python
python能否java成为主流语言吗
Jun 22 Python
使用sublime text3搭建Python编辑环境的实现
Jan 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
四月新番又没了,《Re:从零开始的异世界生活》第二季延期至7月播出
2020/05/06 日漫
如何使用PHP获取网络上文件
2006/10/09 PHP
PHP加速 eAccelerator配置和使用指南
2009/06/05 PHP
PHP采集腾讯微博的实现代码
2012/01/19 PHP
PHP 计算两个特别大的整数实例代码
2018/05/07 PHP
不错的asp中显示新闻的功能
2006/10/13 Javascript
用js得到网页中所有的div的id
2020/10/19 Javascript
JSONP之我见
2015/03/24 Javascript
js中遍历Map对象的方法
2016/07/27 Javascript
Angularjs 创建可复用组件实例代码
2016/10/09 Javascript
JS控制div跳转到指定的位置的几种解决方案总结
2016/11/05 Javascript
ng-options和ng-checked在表单中的高级运用(推荐)
2017/01/21 Javascript
Angularjs中的ui-bootstrap的使用教程
2017/02/19 Javascript
详解在 Angular 项目中添加 clean-blog 模板
2017/07/04 Javascript
使用Vue开发一个实时性时间转换指令
2018/01/17 Javascript
JS中注入eval, Function等系统函数截获动态代码
2019/04/03 Javascript
对Layer弹窗使用及返回数据接收的实例详解
2019/09/26 Javascript
countup.js实现数字动态叠加效果
2019/10/17 Javascript
Django小白教程之Django用户注册与登录
2016/04/22 Python
python实现BackPropagation算法
2017/12/14 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
2018/06/01 Python
在python中对变量判断是否为None的三种方法总结
2019/01/23 Python
对Python3 pyc 文件的使用详解
2019/02/16 Python
HTML5的download属性详细介绍和使用实例
2014/04/23 HTML / CSS
韩国著名的在线综合购物网站:Akmall
2016/08/07 全球购物
伦敦最有品味的百货:Liberty London
2016/11/12 全球购物
美国最大的家庭鞋类零售商之一:Shoe Carnival
2017/10/06 全球购物
绘画设计学生的个人自我评价
2013/09/20 职场文书
人力资源管理专业毕业生自我评价
2013/09/21 职场文书
质检员的岗位职责
2013/11/15 职场文书
房产销售经理职责
2013/12/20 职场文书
《十六年前的回忆》教学反思
2014/02/14 职场文书
企业文化标语口号
2014/06/09 职场文书
浅谈如何写好演讲稿?
2019/06/12 职场文书
超外差式晶体管收音机的组装与统调
2021/04/22 无线电
Java Lambda表达式常用的函数式接口
2022/04/07 Java/Android