并发爬虫小练习。

直接粘贴到本地,命名为.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博客备份工具(可扩展成并行)的更多相关文章

  1. 推荐一款自己的软件作品[豆约翰博客备份专家],新浪博客,QQ空间,CSDN,cnblogs博客备份,导出CHM,PDF(转载)

    推荐一款自己的软件作品[豆约翰博客备份专 豆约翰博客备份专家是完全免费,功能强大的博客备份工具,博客电子书(PDF,CHM和TXT)生成工具,博文离线浏览工具,软件界面美观大方,支持多个主流博客网站( ...

  2. cnblogs博客迁移到hexo

    cnblogs博客备份 备份地址:https://i.cnblogs.com/BlogBackup.aspx?type=1 备份文件为xml格式,打开备份文件,如下所示: <?xml versi ...

  3. 用Python编写博客导出工具

    用Python编写博客导出工具 罗朝辉 (http://kesalin.github.io/) CC 许可,转载请注明出处   写在前面的话 我在 github 上用 octopress 搭建了个人博 ...

  4. python编写的自动获取代理IP列表的爬虫-chinaboywg-ChinaUnix博客

    python编写的自动获取代理IP列表的爬虫-chinaboywg-ChinaUnix博客 undefined Python多线程抓取代理服务器 | Linux运维笔记 undefined java如 ...

  5. python爬取博客圆首页文章链接+标题

    新人一枚,初来乍到,请多关照 来到博客园,不知道写点啥,那就去瞄一瞄大家都在干什么好了. 使用python 爬取博客园首页文章链接和标题. 首先当然是环境了,爬虫在window10系统下,python ...

  6. BlogPublishTool - 博客发布工具

    BlogPublishTool - 博客发布工具 这是一个发布博客的工具.本博客使用本工具发布. 本工具源码已上传至github:https://github.com/ChildishChange/B ...

  7. org-mode 写 cnblogs 博客

    1. 为什么用org-mode写博客 我最开始用Emacs, 是因为org-mode.这是一个专注于写,而让我忽略展示结果的一种写作方式.为 什么这么说?因为所有内容的格式都是可定制的.按照自己喜欢的 ...

  8. 有哪些关于 Python 的技术博客?

    Python是一种动态解释型的编程语言,它可以在Windows.UNIX.MAC等多种操作系统以及Java..NET开发平台上使用.不过包含的内容很多,加上各种标准库.拓展库,乱花渐欲迷人眼.因此如何 ...

  9. 把cnblogs变成简书 - cnblogs博客自定义皮肤css样式

    吐槽 博客园cnblogs作为老牌的IT技术博客类网站,为广大的开发者提供了非常不错的学习交流平台. 虽然博客内容才是重点,但是如果有赏心悦目的页面不更好吗! cnblogs可以更换博客模板,并且提供 ...

随机推荐

  1. Openfire 的安装和配置

    1. 下载最新的openfire安装文件 官方下载站点:http://www.igniterealtime.org/downloads/index.jsp#openfire 下载地址: Exe:htt ...

  2. Customizing the Editor

    Use the General, Text Editor, Options Dialog Box to customize the appearance and functionality of th ...

  3. IHttpModule

    随便写一个类继承IHttpModule 实现IHttpModule中的两个方法 Init() Dispose() public void Init(HttpApplication context) { ...

  4. WordPress基础:极简安装教程

    1.下载WordPress 2.将解压后的文件夹,放到网站根目录,并重命名为你喜欢的目录如:w, 3.重命名文件wp-config-sample.php 为 wp-config.php,并进行配置 4 ...

  5. resx文件在X64位编译,提示“未能加载文件或程序集”的问题?

    原文:resx文件在X64位编译,提示"未能加载文件或程序集"的问题? resx文件在X64位编译,提示"未能加载文件或程序集"的问题? 解答: 错误现象如下 ...

  6. swt小知识点

    1 换java小图标 Image image=this.getToolkit().getImage("d:/pu1.jpg"); setIconImage(image); 2 去掉 ...

  7. 网页内嵌入QQ通信组件,唤起QQ,针对不同平台的处理方式

    web浏览器中嵌入QQ通信组件,目前发现有两种方式,主要是区分 IOS平台(苹果系列)和其他平台(PC 安卓等……),下面是代码区别: <li><a href="http: ...

  8. App_global.asax.pdb: 另一个程序正在使用此文件,进程无法访问。

    页面修改后,浏览报错,信息如下. 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码. 编译器错误消息: CS0042: 创建调试信息文件“ ...

  9. 一个iOS项目中包含多个xcodeproj文件,如何运行其中的一个项目

    从GitHub上下载的Masonry的iOS源码,打开发现有多个项目,直接运行,模拟器没反应.由于Masonry是一个多工程的项目,每个项目都依赖Masonry的源码,所以要运行Masonry的Exa ...

  10. FTP上传

    package cn.zto.util; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileIn ...