[Python爬虫]cnblogs博客备份工具(可扩展成并行)
并发爬虫小练习。
直接粘贴到本地,命名为.py文件即可运行,运行时的参数为你想要爬取的用户。默认是本博客。
输出是以用户名命名的目录,目录内便是博客内容。
仅供学习python的多线程编程方法,后续会重写成并行爬虫。
爬虫代码如下:
# -*- coding:utf-8 -*-
from multiprocessing.managers import BaseManager
from pyquery import PyQuery
import os, sys, urllib
import re, random, logging, time
import Queue, threading, multiprocessing, threadpool USER_NAME = 'kirai'
TOTAL_PAGE_NUMBER = 0
INT_REGEXP = re.compile('([\d]+)')
BASE_URL = 'http://www.cnblogs.com/'+USER_NAME+'/p/?page='
ARTICLE_REGEXP = re.compile('href=\"(http://www.cnblogs.com/'+USER_NAME+'/p/[\d]+.html)\"')
THREAD_NUMBER = multiprocessing.cpu_count() * 2
ARTICLE_URLS_MUTEX = threading.Lock()
ARTICLE_URLS = [] class ListWithLinkExtend(list):
def extend(self, value):
super(ListWithLinkExtend, self).extend(value)
return self def get_total_page_number():
doc = PyQuery(url=BASE_URL)
return int(INT_REGEXP.findall(
doc.find('.pager .Pager').text())[0].encode('ascii')) def get_page_url():
global TOTAL_PAGE_NUMBER
return map(lambda page: BASE_URL+str(page),
[i for i in range(1, TOTAL_PAGE_NUMBER+1)]) def get_article_url(idx):
url = PAGE_URLS[idx]
doc = PyQuery(url=url)
article_urls = ARTICLE_REGEXP.findall(str(doc.find('.PostList .postTitl2')))
return article_urls def handle_result(request, result):
global ARTICLE_URLS_MUTEX, ARTICLE_URLS
try:
ARTICLE_URLS_MUTEX.acquire()
ARTICLE_URLS.append(result)
finally:
ARTICLE_URLS_MUTEX.release() def cluster_process():
global ARTICLE_URLS
# list : urls
task_queue = Queue.Queue()
# str : path
result_queue = Queue.Queue()
KiraiManager.register('get_task_queue', callable=lambda: task_queue)
KiraiManager.register('get_result_queue', callable=lambda: result_queue)
manager = KiraiManager(address=('', 6969), authkey='whosyourdaddy')
manager.start()
manager.shutdown()
# article_flag, article_urls = get_article_url() # a simple way.
def get_article(url):
html = urllib.urlopen(url).read()
return html, INT_REGEXP.findall(url)[0] def save_article(request, result):
content = result[0]
file_name = result[1]
path = './' + USER_NAME + '/' + file_name + '.html'
try:
fp = file(path, 'w')
fp.writelines(content)
finally:
fp.close() def thread_process():
global ARTICLE_URLS
os.mkdir(USER_NAME)
thread_pool = threadpool.ThreadPool(THREAD_NUMBER)
requests = threadpool.makeRequests(get_article, ARTICLE_URLS, save_article)
[thread_pool.putRequest(req) for req in requests]
thread_pool.wait() def __main__(argv):
global ARTICLE_URLS, TOTAL_PAGE_NUMBER, USER_NAME, BASE_URL, ARTICLE_REGEXP, PAGE_URLS, TOTAL_PAGE_NUMBER
if len(argv) == 2:
USER_NAME = argv[1]
BASE_URL = 'http://www.cnblogs.com/'+USER_NAME+'/p/?page='
ARTICLE_REGEXP = re.compile('href=\"(http://www.cnblogs.com/'+USER_NAME+'/p/[\d]+.html)\"')
TOTAL_PAGE_NUMBER = get_total_page_number()
PAGE_URLS = get_page_url()
thread_pool = threadpool.ThreadPool(THREAD_NUMBER)
requests = threadpool.makeRequests(
get_article_url,
[i for i in range(0, TOTAL_PAGE_NUMBER)],
handle_result)
[thread_pool.putRequest(req) for req in requests]
thread_pool.wait()
ARTICLE_URLS = list(reduce(lambda a, b: ListWithLinkExtend(a).extend(ListWithLinkExtend(b)),
ARTICLE_URLS))
thread_process() if __name__ == '__main__':
__main__(sys.argv)
简单介绍下全局变量的意义:
USER_NAME:希望爬取的用户名,默认为kirai。
TOTAL_PAGE_NUMBER:会被更新成博客随笔的总页数。
INT_REGEXP:为了匹配数字的正则。
BASE_URL:随笔页的初始URL。
ARTICLE_REGEXP:在经过pyquery处理过后的每个随笔目录页中提取出博客文章页面的正则。
THREAD_NUMBER:线程数,默认设置是本机cpu核数的2倍。
ARTICLE_URLS_MUTEX:ARTICLE_URLS的锁,保证线程唯一占用。
ARTICLE_URLS:用于存放所有的文章url。
[Python爬虫]cnblogs博客备份工具(可扩展成并行)的更多相关文章
- 推荐一款自己的软件作品[豆约翰博客备份专家],新浪博客,QQ空间,CSDN,cnblogs博客备份,导出CHM,PDF(转载)
推荐一款自己的软件作品[豆约翰博客备份专 豆约翰博客备份专家是完全免费,功能强大的博客备份工具,博客电子书(PDF,CHM和TXT)生成工具,博文离线浏览工具,软件界面美观大方,支持多个主流博客网站( ...
- cnblogs博客迁移到hexo
cnblogs博客备份 备份地址:https://i.cnblogs.com/BlogBackup.aspx?type=1 备份文件为xml格式,打开备份文件,如下所示: <?xml versi ...
- 用Python编写博客导出工具
用Python编写博客导出工具 罗朝辉 (http://kesalin.github.io/) CC 许可,转载请注明出处 写在前面的话 我在 github 上用 octopress 搭建了个人博 ...
- python编写的自动获取代理IP列表的爬虫-chinaboywg-ChinaUnix博客
python编写的自动获取代理IP列表的爬虫-chinaboywg-ChinaUnix博客 undefined Python多线程抓取代理服务器 | Linux运维笔记 undefined java如 ...
- python爬取博客圆首页文章链接+标题
新人一枚,初来乍到,请多关照 来到博客园,不知道写点啥,那就去瞄一瞄大家都在干什么好了. 使用python 爬取博客园首页文章链接和标题. 首先当然是环境了,爬虫在window10系统下,python ...
- BlogPublishTool - 博客发布工具
BlogPublishTool - 博客发布工具 这是一个发布博客的工具.本博客使用本工具发布. 本工具源码已上传至github:https://github.com/ChildishChange/B ...
- org-mode 写 cnblogs 博客
1. 为什么用org-mode写博客 我最开始用Emacs, 是因为org-mode.这是一个专注于写,而让我忽略展示结果的一种写作方式.为 什么这么说?因为所有内容的格式都是可定制的.按照自己喜欢的 ...
- 有哪些关于 Python 的技术博客?
Python是一种动态解释型的编程语言,它可以在Windows.UNIX.MAC等多种操作系统以及Java..NET开发平台上使用.不过包含的内容很多,加上各种标准库.拓展库,乱花渐欲迷人眼.因此如何 ...
- 把cnblogs变成简书 - cnblogs博客自定义皮肤css样式
吐槽 博客园cnblogs作为老牌的IT技术博客类网站,为广大的开发者提供了非常不错的学习交流平台. 虽然博客内容才是重点,但是如果有赏心悦目的页面不更好吗! cnblogs可以更换博客模板,并且提供 ...
随机推荐
- Linux内存管理基本概念
1. 基本概念 1.1 地址 (1)逻辑地址:指由程序产生的与段相关的偏移地址部分.在C语言指针中,读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址.( ...
- Date类型-演示JS中的日期
<script type="text/javascript"> /* *演示JS中的日期 */ var date = new Date(); document.writ ...
- 【iCore3 双核心板_ uC/OS-III】例程五:软件定时器
实验指导书及代码包下载: http://pan.baidu.com/s/1eSHenjs iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- Apache Spark源码走读之23 -- Spark MLLib中拟牛顿法L-BFGS的源码实现
欢迎转载,转载请注明出处,徽沪一郎. 概要 本文就拟牛顿法L-BFGS的由来做一个简要的回顾,然后就其在spark mllib中的实现进行源码走读. 拟牛顿法 数学原理 代码实现 L-BFGS算法中使 ...
- Qt常用命令收集
qt的命令很多,用到的时候到网上查,常常不能一下查到.这里记录下一些备用 1 从.ui文件生成头文件: uic xxx.ui > xxx.h 2 moc生成 moc yourfilename.h ...
- angularjs backbone 集成requirejs 模块化
首先认识requirejs requirejs是个包加载器,核心功能是模块化管理,可以实现按需加载. 重点是明白 模块化不是按需加载. 模块化的意义: 是通过代码逻辑表明模块之间的依赖关系和执行顺序, ...
- 关于preg_match输出多个数组的解释,使用()时
第一个数组显示的是所有的匹配,第二个显示的是第一个括号里的内容,第三个显示的是第二个括号里的内容
- linux常用操作指令
Linux常用操作指令: 常用指令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(a ...
- [PointCloud] GICP
泛化的ICP算法,通过协方差矩阵起到类似于权重的作用,消除某些不好的对应点在求解过程中的作用.不过可以囊括Point to Point,Point to Plane的ICP算法,真正的是泛化的ICP. ...
- win7 安装 memcached
1. 下载 memcached-win32-1.4.4-14.zip,里面包含6个文件,将解压后的文件夹随便放在什么位置.如果需要win64版,下载 memcached-win64-1.4.4-14. ...