[Python爬虫]高并发cnblogs博客备份工具(可扩展成并行)

并发爬虫小练习。

直接粘贴到本地,命名为.py文件即可运行,运行时的参数为你想要爬取的用户。默认是本博客。

输出是以用户名命名的目录,目录内便是博客内容。

仅供学习python的多线程编程方法,后续会重写成并行爬虫。

爬虫代码如下:

  1 # -*- coding:utf-8 -*-
  2 from multiprocessing.managers import BaseManager
  3 from pyquery import PyQuery
  4 import os, sys, urllib
  5 import re, random, logging, time
  6 import Queue, threading, multiprocessing, threadpool
  7
  8 USER_NAME = ‘kirai‘
  9 TOTAL_PAGE_NUMBER = 0
 10 INT_REGEXP = re.compile(‘([\d]+)‘)
 11 BASE_URL = ‘http://www.cnblogs.com/‘+USER_NAME+‘/p/?page=‘
 12 ARTICLE_REGEXP = re.compile(‘href=\"(http://www.cnblogs.com/‘+USER_NAME+‘/p/[\d]+.html)\"‘)
 13 THREAD_NUMBER = multiprocessing.cpu_count() * 2
 14 ARTICLE_URLS_MUTEX = threading.Lock()
 15 ARTICLE_URLS = []
 16
 17 class ListWithLinkExtend(list):
 18     def extend(self, value):
 19         super(ListWithLinkExtend, self).extend(value)
 20         return self
 21
 22 def get_total_page_number():
 23     doc = PyQuery(url=BASE_URL)
 24     return int(INT_REGEXP.findall(
 25         doc.find(‘.pager .Pager‘).text())[0].encode(‘ascii‘))
 26
 27 def get_page_url():
 28     global TOTAL_PAGE_NUMBER
 29     return map(lambda page: BASE_URL+str(page),
 30                          [i for i in range(1, TOTAL_PAGE_NUMBER+1)])
 31
 32 def get_article_url(idx):
 33     url = PAGE_URLS[idx]
 34     doc = PyQuery(url=url)
 35     article_urls = ARTICLE_REGEXP.findall(str(doc.find(‘.PostList .postTitl2‘)))
 36     return article_urls
 37
 38 def handle_result(request, result):
 39     global ARTICLE_URLS_MUTEX, ARTICLE_URLS
 40     try:
 41         ARTICLE_URLS_MUTEX.acquire()
 42         ARTICLE_URLS.append(result)
 43     finally:
 44         ARTICLE_URLS_MUTEX.release()
 45
 46 def cluster_process():
 47     global ARTICLE_URLS
 48     # list : urls
 49     task_queue = Queue.Queue()
 50     # str : path
 51     result_queue = Queue.Queue()
 52     KiraiManager.register(‘get_task_queue‘, callable=lambda: task_queue)
 53     KiraiManager.register(‘get_result_queue‘, callable=lambda: result_queue)
 54     manager = KiraiManager(address=(‘‘, 6969), authkey=‘whosyourdaddy‘)
 55     manager.start()
 56     manager.shutdown()
 57     # article_flag, article_urls = get_article_url()
 58
 59 # a simple way.
 60 def get_article(url):
 61     html = urllib.urlopen(url).read()
 62     return html, INT_REGEXP.findall(url)[0]
 63
 64 def save_article(request, result):
 65     content = result[0]
 66     file_name = result[1]
 67     path = ‘./‘ + USER_NAME + ‘/‘ + file_name + ‘.html‘
 68     try:
 69         fp = file(path, ‘w‘)
 70         fp.writelines(content)
 71     finally:
 72         fp.close()
 73
 74 def thread_process():
 75     global ARTICLE_URLS
 76     os.mkdir(USER_NAME)
 77     thread_pool = threadpool.ThreadPool(THREAD_NUMBER)
 78     requests = threadpool.makeRequests(get_article, ARTICLE_URLS, save_article)
 79     [thread_pool.putRequest(req) for req in requests]
 80     thread_pool.wait()
 81
 82 def __main__(argv):
 83     global ARTICLE_URLS, TOTAL_PAGE_NUMBER, USER_NAME, BASE_URL, ARTICLE_REGEXP, PAGE_URLS, TOTAL_PAGE_NUMBER
 84     if len(argv) == 2:
 85         USER_NAME = argv[1]
 86     BASE_URL = ‘http://www.cnblogs.com/‘+USER_NAME+‘/p/?page=‘
 87     ARTICLE_REGEXP = re.compile(‘href=\"(http://www.cnblogs.com/‘+USER_NAME+‘/p/[\d]+.html)\"‘)
 88     TOTAL_PAGE_NUMBER = get_total_page_number()
 89     PAGE_URLS = get_page_url()
 90     thread_pool = threadpool.ThreadPool(THREAD_NUMBER)
 91     requests = threadpool.makeRequests(
 92         get_article_url,
 93         [i for i in range(0, TOTAL_PAGE_NUMBER)],
 94         handle_result)
 95     [thread_pool.putRequest(req) for req in requests]
 96     thread_pool.wait()
 97     ARTICLE_URLS = list(reduce(lambda a, b: ListWithLinkExtend(a).extend(ListWithLinkExtend(b)),
 98                                                          ARTICLE_URLS))
 99     thread_process()
100
101 if __name__ == ‘__main__‘:
102     __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。

时间: 2024-10-11 00:31:22

[Python爬虫]高并发cnblogs博客备份工具(可扩展成并行)的相关文章

cnblogs博客下载-cnblogs博客导出-cnblogs博客备份工具-基于python

http://blog.csdn.net/infoworld/article/details/19547723 以下代码是基于infoworld的csdn备份python代码修改的cnblogs博客备份,但是和infoworld的界面不匹配,只能够用在python里面.python确实有意思,开发很快,怪不得这么流行. #! encoding=utf-8 #cnblogs博客备份,使用方法:修改最下面的url和output,然后执行就可以了. import urllib2 import re i

python爬虫爬取csdn博客专家所有博客内容

python爬虫爬取csdn博客专家所有博客内容: 全部过程采取自动识别与抓取,抓取结果是将一个博主的所有 文章存放在以其名字命名的文件内,代码如下 结果如下: 版权声明:本文为博主原创文章,未经博主允许不得转载.

Python爬虫入门教程:博客园首页推荐博客排行的秘密

1. 前言 虽然博客园注册已经有五年多了,但是最近才正式开始在这里写博客.(进了博客园才知道这里面个个都是人才,说话又好听,超喜欢这里...)但是由于写的内容都是软件测试相关,热度一直不是很高.看到首页的推荐博客排行时,心里痒痒的,想想看看这些大佬究竟是写了什么文章这么受欢迎,可以被推荐.所以用Python抓取了这100位推荐博客,简单分析了每个博客的文章分类,阅读排行榜,评论排行榜及推荐排行榜,最后统计汇总并生成词云.正好这也算是一篇非常好的Python爬虫入门教程了. 2. 环境准备 2.1

Python爬虫入门教程 54-100 博客园等博客网站自动评论器

爬虫背景 爬虫最核心的问题就是解决重复操作,当一件事情可以重复的进行的时候,就可以用爬虫来解决这个问题,今天要实现的一个基本需求是完成"博客园" 博客的自动评论,其实原理是非常简单的,提炼一下需求 基本需求 登录博客园<不实现,登录单独编写博客> 调用评论接口 返回请求结果 确定流程之后,基本就是找突破口的环节了 实际的去评论一下,然后不管你用什么抓包工具都可以,只要抓取到你想要的数据,即可 评论API如下 Request URL: https://www.cnblogs.

python爬虫抓取51cto博客大牛的文章名和文章url

脚本一: #!/usr/bin/env python #coding:utf-8 from  bs4  import  BeautifulSoup import urllib import re art = {} for page in range(1,5): page = str(page) url = 'http://yujianglei.blog.51cto.com/all/7215578/page/'  + page response = urllib.urlopen(url).read

Python爬虫入门教程 17-100 博客抓取数据

写在前面 写了一段时间的博客了,忽然间忘记了,其实博客频道的博客也是可以抓取的,所以我干了..... 其实这事情挺简单的,打开CSDN博客首页,他不是有个最新文章么,这个里面都是最新发布的文章. 打开F12抓取一下数据API,很容易就获取到了他的接口 提取链接长成这个样子 https://blog.csdn.net/api/articles?type=more&category=newarticles&shown_offset=1540381234000000 发现博客最新文章是一个瀑布流

python爬虫抓取51cto博客大牛的文章保存到MySQL数据库

脚本实现:获取51cto网站某大牛文章的url,并存储到数据库中. #!/usr/bin/env python #coding:utf-8 from  bs4  import  BeautifulSoup import urllib import re import MySQLdb k_art_name = [] v_art_url = [] db = MySQLdb.connect('192.168.115.5','blog','blog','blog') cursor = db.cursor

Python爬虫抓取csdn博客

昨天晚上为了下载保存某位csdn大牛的全部博文,写了一个爬虫来自动抓取文章并保存到txt文本,当然也可以 保存到html网页中.这样就可以不用Ctrl+C 和Ctrl+V了,非常方便,抓取别的网站也是大同小异. 为了解析抓取的网页,用到了第三方模块,BeautifulSoup,这个模块对于解析html文件非常有用,当然也可以自己使用正则表达式去解析,但是比较麻烦. 由于csdn网站的robots.txt文件中显示禁止任何爬虫,所以必须把爬虫伪装成浏览器,而且不能频繁抓取,得sleep一会再抓,使

使用org-mode写cnblogs博客

.title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium; font-weight: bold; margin-top: 0 } .todo { font-family: monospace; color: red } .done { font-family: monospace; color: green } .priority { font-fami