首先创建两个队列,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+++++++++++++++++++++++++++++++++++++'