#!/usr/bin/env python
#coding=utf-8
import threading
import urllib
import re
import time cur=0
last=0
totalcount=0
depth=0
t_mutex=threading.Condition() class Mycrawler:
def __init__(self,crawlername,seeds,threadnum):
self.crawlername=crawlername
self.seeds=seeds
self.crawqueue=CrawQueue()
self.initQueue(self.seeds)
self.threadnum=threadnum
self.threadpools=[]
self.logfile=file('log2.txt','w')
def initQueue(self,seeds):
if isinstance(seeds,str):
self.crawqueue.push(seeds)
elif isinstance(seeds,list):
for seed in seeds:
self.crawqueue.push(seed)
global last
global totalcount
totalcount=self.crawqueue.getQueueCount()
last=totalcount
def crawling(self):
global cur
global depth
global last
global totalcount
self.log(">>>Depth "+str(depth)+":\n")
while self.crawqueue.getQueueCount()!=0:
url=self.crawqueue.pop()
self.log(url)
if url==None:
continue
self.crawqueue.addToVisited(url)
links=self.getLinks(url)
if links==None:
print 'None'
self.crawqueue.failed.append(url)
continue
beforenum = self.crawqueue.getQueueCount()
self.crawqueue.addLinks(links)
afternum = self.crawqueue.getQueueCount()
totalcount+=afternum-beforenum
cur+=1
if cur==last:
depth+=1
self.log(">>>Depth "+str(depth)+":\n")
last=totalcount
def crawling2(self):
global last
global totalcount
global depth
self.log(">>>Depth "+str(depth)+":\n")
totalcount=self.crawqueue.getQueueCount()
last=totalcount
while self.crawqueue.getQueueCount()!=0:
for i in range(self.threadnum):
url=self.crawqueue.pop()
if url==None:
break
crawthread=crawlerThread(url,i,self)
self.threadpools.append(crawthread)
crawthread.start()
for i in range(len(self.threadpools)):
crawthread=self.threadpools[i]
crawthread.join(30)
def log(self,content):
self.logfile.write(content+"\n")
class crawlerThread(threading.Thread):
def __init__(self,url,tid,mycrawler):
threading.Thread.__init__(self)
self.url=url
self.tid=tid
self.mycrawler=mycrawler
def run(self):
global t_mutex
global cur
global last
global totalcount
global depth
t_mutex.acquire()
self.mycrawler.log(self.url)
t_mutex.release()
links=self.getLinks(self.url)
if links==None:
t_mutex.acquire()
self.mycrawler.crawqueue.addToVisited(self.url)
self.mycrawler.crawqueue.addToFailed(self.url)
t_mutex.release()
else:
t_mutex.acquire()
self.mycrawler.crawqueue.addToVisited(self.url)
beforenum=self.mycrawler.crawqueue.getQueueCount()
self.mycrawler.crawqueue.addLinks(links)
afternum =self.mycrawler.crawqueue.getQueueCount()
totalcount+=afternum-beforenum
t_mutex.release()
t_mutex.acquire()
cur+=1
if cur==last:
depth+=1
self.mycrawler.log(">>>Depth "+str(depth)+":\n")
last=totalcount
t_mutex.release()
def getLinks(self,url):
try:
page=urllib.urlopen(url)
html=page.read()
reg=r'"(http://.+?)"'
regob=re.compile(reg,re.DOTALL)
links=regob.findall(html)
return links
except:
print 'Failed downloading and saving',url
return None
class CrawQueue:
def __init__(self):
self.queue=[]
self.visited=[]
self.failed=[]
def getQueue(self):
return self.queue
def getVisited(self):
return self.visited
def getFailed(self):
return self.failed
def push(self,url):
if url!="" and url not in self.queue and url not in self.visited:
self.queue.insert(0,url)
def pop(self):
if len(self.queue)==0:
#print 'failed to pop: queue is empty'
return None
else:
return self.queue.pop()
def isEmpty(self):
if len(self.queue)==0:
return 1
else:
return 0
def addToVisited(self,url):
self.visited.append(url)
def addToFailed(self,url):
self.failed.append(url)
def remove(self,url):
self.queue.remove(url)
def getVisitedCount(self):
return len(self.visited)
def getQueueCount(self):
return len(self.queue)
def addLinks(self,links):
for link in links:
self.push(link) if __name__=="__main__":
seeds="http://www.douban.com/"
threadnum=int(raw_input("设置线程数:"))
crawlername="小小爬虫"
mycrawler=Mycrawler(crawlername,seeds,threadnum)
mycrawler.crawling2()

多线程网页爬虫 python 实现(二)的更多相关文章

  1. 多线程网页爬虫 python 实现

    采用了多线程和锁机制,实现了广度优先算法的网页爬虫. 对于一个网络爬虫,如果要按广度遍历的方式下载,它就是这样干活的:         1.从给定的入口网址把第一个网页下载下来         2.从 ...

  2. python网页爬虫开发之二

    1.网站robots robotparser模块首先加载robots.txt文件,然后通过can_fetch()函数确定指定的用户代理是否允许访问网页. 2.识别网站技术 3.下载网页 使用urlli ...

  3. python 网页爬虫+保存图片+多线程+网络代理

    今天,又算是浪费了一天了.python爬虫,之前写过简单的版本,那个时候还不懂原理,现在算是收尾吧. 以前对网页爬虫不了解,感觉非常神奇,但是解开这面面纱,似乎里面的原理并不是很难掌握.首先,明白一个 ...

  4. Python爬虫初学(二)—— 爬百度贴吧

    Python爬虫初学(二)-- 爬百度贴吧 昨天初步接触了爬虫,实现了爬取网络段子并逐条阅读等功能,详见Python爬虫初学(一). 今天准备对百度贴吧下手了,嘿嘿.依然是跟着这个博客学习的,这次仿照 ...

  5. Python 网页爬虫 & 文本处理 & 科学计算 & 机器学习 & 数据挖掘兵器谱(转)

    原文:http://www.52nlp.cn/python-网页爬虫-文本处理-科学计算-机器学习-数据挖掘 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开 ...

  6. Python网页爬虫(一)

    很多时候我们想要获得网站的数据,但是网站并没有提供相应的API调用,这时候应该怎么办呢?还有的时候我们需要模拟人的一些行为,例如点击网页上的按钮等,又有什么好的解决方法吗?这些正是python和网页爬 ...

  7. Python爬虫学习:二、爬虫的初步尝试

    我使用的编辑器是IDLE,版本为Python2.7.11,Windows平台. 本文是博主原创随笔,转载时请注明出处Maple2cat|Python爬虫学习:二.爬虫的初步尝试 1.尝试抓取指定网页 ...

  8. 【Python】Python 网页爬虫 & 文本处理 & 科学计算 & 机器学习 & 数据挖掘兵器谱

    本文转载自:https://www.cnblogs.com/colipso/p/4284510.html 好文 mark http://www.52nlp.cn/python-%E7%BD%91%E9 ...

  9. Python 3实现网页爬虫

    1 什么是网页爬虫 网络爬虫( 网页蜘蛛,网络机器人,网页追逐者,自动索引,模拟程序)是一种按照一定的规则自动地抓取互联网信息的程序或者脚本,从互联网上抓取对于我们有价值的信息.Tips:自动提取网页 ...

随机推荐

  1. Linux poll机制

    1.用户空间调用(参考 poll(2) - Linux man page) int poll(struct pollfd *fds, nfds_t nfds, int timeout); it wai ...

  2. LeetCode(136) Single Number

    题目 Given an array of integers, every element appears twice except for one. Find that single one. Not ...

  3. LeetCode(106) Construct Binary Tree from Inorder and Postorder Traversal

    题目 Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume ...

  4. PAT Basic 1040

    1040 有几个PAT 字符串APPAPT中包含了两个单词“PAT”,其中第一个PAT是第2位(P),第4位(A),第6位(T):第二个PAT是第3位(P),第4位(A),第6位(T). 现给定字符串 ...

  5. C/C++复杂类型声明

    曾经碰到过让你迷惑不解.类似于int * (* (*fp1) (int) ) [10];这样的变量声明吗?本文将由易到难,一步一步教会你如何理解这种复杂的C/C++声明.   我们将从每天都能碰到的较 ...

  6. apache下虚拟域名配置

    在我们开发中通过虚拟域名来访问一个指定的项目确实很方便,接下来教大家如何通过手动的方式去配置虚拟域名(已apache服务器为例) 一.首页我们得找到host文件.windows下这个文件在c盘中WIN ...

  7. NYOJ 469 擅长排列的小明 II

    擅长排列的小明 II 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 小明十分聪明,而且十分擅长排列计算. 有一天小明心血来潮想考考你,他给了你一个正整数n,序列1, ...

  8. PTA 09-排序3 Insertion or Heap Sort (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/676 5-14 Insertion or Heap Sort   (25分) Accor ...

  9. 【bzoj2989】数列 KD-tree+旋转坐标系

    题目描述 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|. 2种操作(k都是正整数): 1.Mo ...

  10. HDU 1565 方格取数(1) ——插头DP

    [题目分析] 其实直接状压就可以了. 但是有点闲,又写了一个可读性极差,智商低下,很(gou)好(pi)的代码 [代码] #include <cstdio> #include <cs ...