首先创建两个队列,queue队列存储要爬的网址,out_queue存储的是要取内容的网页源代码。
创建线程类,ThreadUrl的作用是从给定的网址上抓取网页内容,并将内容存储在out_queue队列上,而DatamineThread的作用是从网页源代码中通过正则来取想要的内容。
这个代码在window下运行的话就需要将.decode(‘utf8‘)那句话前面的#删除就ok了,编码方式需要改一下。
如果想自己编写的话,使用queue的时候一定不要忘了调用task_done()函数,不然程序将一直运行。
使用正则表达式的时候抓取内容的格式一定要注意,要与源代码中一致,开始的时候我少了几个空格回车,各种抓不到啊。
运行时间更电脑配置有关,可能会较长,可以通过调整抓取网页的数量来控制时间。
#-*- coding:utf-8 -*- import Queue import threading import urllib2 import time import re from BeautifulSoup import BeautifulSoup host = 'http://www.douban.com/tag/%E7%BC%96%E7%A8%8B/book?start=' queue = Queue.Queue() out_queue = Queue.Queue() class ThreadUrl(threading.Thread): def __init__(self,queue,out_queue): threading.Thread.__init__(self) self.queue = queue self.out_queue = out_queue def run(self): while True: host = self.queue.get() url = urllib2.urlopen(host) chunk = url.read() self.out_queue.put(chunk) self.queue.task_done() class DatamineThread(threading.Thread): def __init__(self,out_queue): threading.Thread.__init__(self) self.out_queue = out_queue def run(self): while True: chunk = self.out_queue.get() title = re.findall('''class="title" target="_blank">(.*?)</a>''',chunk) apprise = re.findall('''<span class="rating_nums">(.*?)</span>''',chunk) desc = re.findall('''<div class="desc"> (.*?) </div>''',chunk) #print desc[14] for i in range(14): print ('书名:'+title[i]+'\n评价:'+apprise[i]+'\n描述:'+desc[i]+'\n')#.decode('utf8') self.out_queue.task_done() start = time.time() def main(): for i in range(5): t = ThreadUrl(queue,out_queue) t.setDaemon(True) t.start() for BookNum in range(10): queue.put(host+str(BookNum*15)) for i in range(5): dt = DatamineThread(out_queue) dt.setDaemon(True) dt.start() queue.join() out_queue.join() #print '++++++++++++++++++++++++++++++++JD_SPIDER+++++++++++++++++++++++++++++++++++++' main() print "Total time :%s"%(time.time()-start) #print '++++++++++++++++++++++++++++++++JD_SPIDER+++++++++++++++++++++++++++++++++++++'
多线程抓取豆瓣编程书籍(linux\windows都可运行)
原文地址:http://blog.csdn.net/djd1234567/article/details/45555811