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中使用Flask、MongoDB搭建简易图片服务器
Feb 04 Python
Python中函数eval和ast.literal_eval的区别详解
Aug 10 Python
代码分析Python地图坐标转换
Feb 08 Python
Python中is和==的区别详解
Nov 15 Python
python退出命令是什么?详解python退出方法
Dec 10 Python
python爬虫之验证码篇3-滑动验证码识别技术
Apr 11 Python
使用Python实现 学生学籍管理系统
Nov 26 Python
Python三元运算与lambda表达式实例解析
Nov 30 Python
用pytorch的nn.Module构造简单全链接层实例
Jan 14 Python
tensorflow2.0的函数签名与图结构(推荐)
Apr 28 Python
详解基于python的全局与局部序列比对的实现(DNA)
Oct 07 Python
Python爬虫中urllib3与urllib的区别是什么
Jul 21 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的栏目导航程序
2006/10/09 PHP
全新的PDO数据库操作类php版(仅适用Mysql)
2012/07/22 PHP
PHP的PDO操作简单示例
2016/03/30 PHP
php中遍历二维数组并以表格的形式输出的方法
2017/01/03 PHP
thinkphp3.2中实现phpexcel导出带生成图片示例
2017/02/14 PHP
多个js与css文件的合并方法详细说明
2012/12/26 Javascript
jQuery版本升级踩坑大全
2016/01/12 Javascript
基于javascript实现泡泡大冒险网页版小游戏
2016/03/23 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
2016/05/05 Javascript
js从数组中删除指定值(不是指定位置)的元素实现代码
2016/09/13 Javascript
JS中split()用法(将字符串按指定符号分割成数组)
2016/10/24 Javascript
React为 Vue 引入容器组件和展示组件的教程详解
2018/05/03 Javascript
JavaScript实用代码小技巧
2018/08/23 Javascript
详解JavaScript添加给定的标签选项
2018/09/17 Javascript
原生js实现抽奖小游戏
2019/06/27 Javascript
JavaScript实现的3D旋转魔方动画效果实例代码
2019/07/31 Javascript
关于vue2强制刷新,解决页面不会重新渲染的问题
2019/10/29 Javascript
jquery实现上传文件进度条
2020/03/26 jQuery
vue项目中使用rem,在入口文件添加内容操作
2020/11/11 Javascript
Python增量循环删除MySQL表数据的方法
2016/09/23 Python
python3.6 实现AES加密的示例(pyCryptodome)
2018/01/10 Python
python表格存取的方法
2018/03/07 Python
Python中的函数作用域
2018/05/07 Python
Python DataFrame设置/更改列表字段/元素类型的方法
2018/06/09 Python
python 递归深度优先搜索与广度优先搜索算法模拟实现
2018/10/22 Python
Python使用requests提交HTTP表单的方法
2018/12/26 Python
Python学习笔记之抓取某只基金历史净值数据实战案例
2019/06/03 Python
Python中zipfile压缩文件模块的基本使用教程
2020/06/14 Python
python 如何把docker-compose.yaml导入到数据库相关条目里
2021/01/15 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的代码
2020/11/30 HTML / CSS
html5简单示例_动力节点Java学院整理
2017/07/07 HTML / CSS
电气工程自动化求职信
2014/03/14 职场文书
社区元宵节活动总结
2015/02/06 职场文书
2015年语言文字工作总结
2015/07/23 职场文书
压缩Redis里的字符串大对象操作
2021/06/23 Redis
Vue的列表之渲染,排序,过滤详解
2022/02/24 Vue.js