Python实现新浪博客备份的方法


Posted in Python onApril 27, 2016

本文实例讲述了Python实现新浪博客备份的方法。分享给大家供大家参考,具体如下:

Python2.7.2版本实现,推荐在IDE中运行。

# -*- coding:UTF-8 -*- #
'''
Created on 2011-12-18
@author: Ahan
'''
import re
import sys
import os
import time
import socket
import locale
import datetime
import codecs
from urllib import urlopen
#正则表达式定义
#匹配博文目录链接
pattern1=u"""<a href="(http:.*?)">博文目录</a>"""
prog1 = re.compile(pattern1)
#匹配博文标题链接
pattern2=u"""<a title="(.*?)" target="_blank" href="(.*?)">.*?</a>"""
prog2=re.compile(pattern2)
#匹配下一页链接
pattern3=u"""<a href="([^"]+)" title="[^"]+">下一页"""
prog3=re.compile(pattern3)
#匹配正文部分
pattern4=u"""<!--博文正文 begin -->[\\s\\S]*?<!-- 正文结束 -->"""
prog4=re.compile(pattern4)
#匹配正文图片链接
pattern5=u"""(src="[^"]+"( real_src ="([^"]+)"))"""
prog5=re.compile(pattern5)
def read_date_from_url(url):
  """以Unicode形式返回从url上读取的所有数据
  """
  try:
    data = ""
    request = urlopen(url)
    while True:
      s = request.read(1024)
      if not s:
        break
      data += s
    return unicode(data)
  except:
    print '读取数据时出错'
    print "Unexpected error:", sys.exc_info()[0],sys.exc_info()[1]
    return None
  finally:
    if request:
      request.close()
def save_to_file(url,filename,blog_address):
  """url为博文地址,filename为要保存的文件名,默认后缀为html
  """
  #如果文件夹不存在则创建文件夹
  if os.path.exists(blog_address)==False:
    os.makedirs(blog_address)
  #去掉文件名中的非法字符
  filename=ReplaceBadCharOfFileName(filename)
  file_no=0
  while os.path.isfile(blog_address+'/'+filename+'.html')==True:
    filename=filename+'('+file_no.__str__()+')'
    file_no+=1
  text = read_date_from_url(url)
  text=_filter(text)
  #将图片保存到本地
  result=prog5.findall(text)
  i=1
  for pic in result:
    folder=blog_address+'/'+filename+'/'
    pic_name='image'+i.__str__()+'.gif' 
    if os.path.exists(folder)==False:
      os.makedirs(folder)
    try:
      url_file = urlopen(pic[2])
      pic_file = codecs.open(folder+pic_name,'wb')
      while True:
        s = url_file.read(1024)
        if not s:
          break
        pic_file.write(s)
      pic_file.close()
      url_file.close()
    except:
      print '噢,保存图片的时候出现问题了,跳过此张图片...'
      print "Unexpected error:", sys.exc_info()[0],sys.exc_info()[1]
    else:
      print '保存图片成功...'
      #替换正文中的图片地址
      text=text.replace(pic[0],unicode("src=\"" + filename + "/" + pic_name + "\"" + pic[1]),1)
      i=i+1
  blog_file = codecs.open(blog_address+'/'+filename+'.html','wb')
  blog_file.write(text)
  blog_file.close()
#提取文本中的正文部分
def _filter(t):
  """提取文本中的正文部分,返回Unicode形式的字符串
  """
  result=prog4.search(t)
  if result is not None:
    return u'<html><head></head><body>' + unicode(result.group()) + u'</dody></html>'
  else:
    raise Exception('噢,提取正文出错了……')
#去掉文件名的不合法字符 
def ReplaceBadCharOfFileName(filename):
  filename=filename.replace(" ","")
  filename=filename.replace("\\", "")
  filename=filename.replace("/", "")
  filename=filename.replace(":", "")
  filename=filename.replace("*", "")
  filename=filename.replace("?", "")
  filename=filename.replace("<", "")
  filename=filename.replace(">", "")
  filename=filename.replace("|", "")
  filename=filename.replace("&","")
  filename=filename.replace(";","")
  return filename
#主函数
if __name__ == '__main__':
  #准备阶段
  blog_no=1#博文编号
  begin=1#起始博文
  end=0#结束博文
  page=0#页码
  saved=0#成功保存的篇数
  timeout = 60*5#超时设为5分钟
  socket.setdefaulttimeout(timeout)#这里对整个socket层设置超时时间。后续文件中如果再使用到socket,不必再设置
  blog_address=raw_input("请输入您的博客地址(输入最后部分即可,比如您的博客地址是http://blog.sina.com.cn/jiangafu,只要输入jiangafu):")
  blog_address=blog_address.replace('\r','')
  begin=raw_input('从第几篇开始:')  
  begin=locale.atoi(begin)
  while begin<=0:
    begin=raw_input('请输入大于0的数:')
    begin=locale.atoi(begin)
  end=raw_input('到第几篇结束(到最后请输入0):')
  end=locale.atoi(end)
  while end<0:
    end=raw_input('请输入大于等于0的数:')
    end=locale.atoi(end)
  if end==0:
    print '您的博客地址是:http://blog.sina.com.cn/'+blog_address+',保存第'+begin.__str__()+'篇到最后一篇博文'
  else:
    print '您的博客地址是:http://blog.sina.com.cn/'+blog_address+',保存第'+begin.__str__()+'篇到第'\
       +end.__str__()+'篇的博文'
  starttime = datetime.datetime.now()
  text=read_date_from_url('http://blog.sina.com.cn/'+blog_address)
  time.sleep(0.5)
  #提取“博文目录”的url
  result = prog1.search(text)
  if result is not None:
    print '博文目录地址:' , result.group(1)
    text=read_date_from_url(result.group(1))
    time.sleep(0.4)
  else:
    print '提取博文目录地址失败'
    #终止程序运行
    sys.exit()
  #查找每一页的全部博文,分析、提取、保存 
  while True:
    page+=1
    print '开始备份第' , page , '页'
    #匹配该页的所有博文地址
    result=prog2.findall(text)
    #循环下载本页每篇博文
    for blog in result: 
      if blog_no < begin:
        blog_no += 1
      elif end != 0 and blog_no > end:
        break
      else:
        try:
          save_to_file(blog[1],unicode(blog[0]),blog_address)
        except:
          print '噢,保存第',blog_no,'篇博文',blog[0],'的时候出现问题了,跳过...'
          blog_no += 1
          print "Unexpected error:", sys.exc_info()[0],sys.exc_info()[1]
        else:
          print '成功保存了第', blog_no, '篇博文:', blog[0]
          blog_no += 1
          saved += 1
          time.sleep(0.4)
    #判断是否有下一页
    result = prog3.search(text)
    if result is not None:
      text = read_date_from_url(result.group(1))
    else:
      print '这是最后一页'
      break
  print '博客备份完成一共备份',saved,'篇博文'
  print '共用时:',datetime.datetime.now() - starttime
  raw_input('按回车键退出...')

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python导出DBF文件到Excel的方法
Jul 25 Python
深入讲解Python函数中参数的使用及默认参数的陷阱
Mar 13 Python
如何用python写一个简单的词法分析器
Dec 18 Python
详解用Python为直方图绘制拟合曲线的两种方法
Aug 21 Python
Pytorch to(device)用法
Jan 08 Python
Python爬取阿拉丁统计信息过程图解
May 12 Python
Pytorch环境搭建与基本语法
Jun 03 Python
详细分析Python垃圾回收机制
Jul 01 Python
Python 操作 MySQL数据库
Sep 18 Python
利用Python批量识别电子账单数据的方法
Feb 08 Python
python 远程执行命令的详细代码
Feb 15 Python
Python实现文字pdf转换图片pdf效果
Apr 03 Python
Python2.7简单连接与操作MySQL的方法
Apr 27 #Python
Python判断文本中消息重复次数的方法
Apr 27 #Python
python脚本监控docker容器
Apr 27 #Python
Python多进程同步简单实现代码
Apr 27 #Python
Python对象转JSON字符串的方法
Apr 27 #Python
Python利用前序和中序遍历结果重建二叉树的方法
Apr 27 #Python
Python实现二维有序数组查找的方法
Apr 27 #Python
You might like
用在PHP里的JS打印函数
2006/10/09 PHP
php获取手机端的号码以及ip地址实例代码
2018/09/12 PHP
getAsDataURL在Firefox7.0下无法预览本地图片的解决方法
2013/11/15 Javascript
JS实现点击复选框将按钮或文本框变为灰色不可用的方法
2015/08/11 Javascript
angularjs表格分页功能详解
2016/01/21 Javascript
js+canvas绘制五角星的方法
2016/01/28 Javascript
学习Bootstrap滚动监听 附调用方法
2016/07/02 Javascript
AngularJS 指令详细介绍
2016/07/27 Javascript
AngularJs 动态加载模块和依赖
2016/09/15 Javascript
解决vue打包项目后刷新404的问题
2018/03/06 Javascript
基于vue框架手写一个notify插件实现通知功能的方法
2019/03/31 Javascript
vue路由守卫,限制前端页面访问权限的例子
2019/11/11 Javascript
Vue父组件向子组件传值以及data和props的区别详解
2020/03/02 Javascript
JS脚本实现定时到网站上签到/签退功能
2020/04/22 Javascript
JavaScript中使用Spread运算符的八种方法总结
2020/06/18 Javascript
详解ES6中class的实现原理
2020/10/03 Javascript
Python中用于返回绝对值的abs()方法
2015/05/14 Python
基于Python实现的ID3决策树功能示例
2018/01/02 Python
python2 与 python3 实现共存的方法
2018/07/12 Python
python定时按日期备份MySQL数据并压缩
2019/04/19 Python
Python 堆叠柱状图绘制方法
2019/07/29 Python
python线程的几种创建方式详解
2019/08/29 Python
python实现数据清洗(缺失值与异常值处理)
2019/12/02 Python
python 定义类时,实现内部方法的互相调用
2019/12/25 Python
中国最大的团购网站:聚划算
2016/09/21 全球购物
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
豪华床上用品 :Jennifer Adams
2019/09/15 全球购物
Linux管理员面试经常问道的相关命令
2013/04/29 面试题
设置器与访问器的定义以及各自特点
2016/01/08 面试题
优秀学生干部个人的自我评价
2013/10/04 职场文书
机械工程师的岗位职责
2013/11/17 职场文书
大学本科毕业生的自我鉴定
2013/11/26 职场文书
付款委托书范本
2014/04/04 职场文书
《北大荒的秋天》教学反思
2014/04/14 职场文书
搬迁通知
2015/04/20 职场文书
小喇叭开始广播了! 四十多年前珍贵老照片
2022/05/09 无线电