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过滤函数filter()使用自定义函数过滤序列实例
Aug 26 Python
详解Python中的各种函数的使用
May 24 Python
Python实现获取域名所用服务器的真实IP
Oct 25 Python
Python之os操作方法(详解)
Jun 15 Python
使用python中的in ,not in来检查元素是不是在列表中的方法
Jul 06 Python
Python Cookie 读取和保存方法
Dec 28 Python
Python字符串逆序的实现方法【一题多解】
Feb 18 Python
一篇文章弄懂Python中所有数组数据类型
Jun 23 Python
python删除列表元素的三种方法(remove,pop,del)
Jul 22 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
Dec 18 Python
Python hashlib加密模块常用方法解析
Dec 18 Python
Python flask框架实现浏览器点击自定义跳转页面
Jun 04 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
解析Extjs与php数据交互(增删查改)
2013/06/25 PHP
php计算当前程序执行时间示例
2014/04/24 PHP
yii2.0之GridView自定义按钮和链接用法
2014/12/15 PHP
PHP文字转图片功能原理与实现方法分析
2017/08/31 PHP
基于jQuery的淡入淡出可自动切换的幻灯插件打包下载
2010/09/15 Javascript
页面回到顶部的三种实现(锚标记,js)
2012/10/01 Javascript
Node.js刷新session过期时间的实现方法推荐
2016/05/18 Javascript
JavaScript数组的定义及数字操作技巧
2016/06/06 Javascript
浅谈javascript运算符——条件,逗号,赋值,()和void运算符
2016/07/15 Javascript
浅谈js中的引用和复制(传值和传址)
2016/09/18 Javascript
vue Element-ui input 远程搜索与修改建议显示模版的示例代码
2017/10/19 Javascript
Node.js引入UIBootstrap的方法示例
2018/05/11 Javascript
vue登录页面cookie的使用及页面跳转代码
2019/07/10 Javascript
webpack 最佳配置指北(推荐)
2020/01/07 Javascript
vue 在methods中调用mounted的实现操作
2020/08/07 Javascript
JS实现选项卡插件的两种写法(jQuery和class)
2020/12/30 jQuery
Python 用户登录验证的小例子
2013/03/06 Python
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
Python三级目录展示的实现方法
2016/09/28 Python
Python 25行代码实现的RSA算法详解
2018/04/10 Python
PyCharm代码回滚,恢复历史版本的解决方法
2018/10/22 Python
pytorch中torch.max和Tensor.view函数用法详解
2020/01/03 Python
python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)
2020/02/09 Python
Python celery原理及运行流程解析
2020/06/13 Python
html5中为audio标签增加停止按钮动作实现方法
2013/01/04 HTML / CSS
美国时尚孕妇装品牌:A Pea in the Pod
2017/07/16 全球购物
英国珠宝钟表和家居礼品精品店:David Shuttle
2018/02/24 全球购物
时尚孕妇装:HATCH Collection
2019/09/24 全球购物
一道输出判断型Java面试题
2014/10/01 面试题
社区中秋节活动方案
2014/01/29 职场文书
满月酒主持词
2014/03/27 职场文书
自愿离婚协议书范本
2014/09/13 职场文书
2014年财务工作总结与计划
2014/12/08 职场文书
新郎结婚保证书
2015/02/26 职场文书
Python几种酷炫的进度条的方式
2022/04/11 Python
windows系统搭建WEB服务器详细教程
2022/08/05 Servers