1. #!/usr/bin/env python
  2. #coding=utf-8
  3. import threading
  4. import urllib
  5. import re
  6. import time
  7.  
  8. cur=0
  9. last=0
  10. totalcount=0
  11. depth=0
  12. t_mutex=threading.Condition()
  13.  
  14. class Mycrawler:
  15. def __init__(self,crawlername,seeds,threadnum):
  16. self.crawlername=crawlername
  17. self.seeds=seeds
  18. self.crawqueue=CrawQueue()
  19. self.initQueue(self.seeds)
  20. self.threadnum=threadnum
  21. self.threadpools=[]
  22. self.logfile=file('log2.txt','w')
  23. def initQueue(self,seeds):
  24. if isinstance(seeds,str):
  25. self.crawqueue.push(seeds)
  26. elif isinstance(seeds,list):
  27. for seed in seeds:
  28. self.crawqueue.push(seed)
  29. global last
  30. global totalcount
  31. totalcount=self.crawqueue.getQueueCount()
  32. last=totalcount
  33. def crawling(self):
  34. global cur
  35. global depth
  36. global last
  37. global totalcount
  38. self.log(">>>Depth "+str(depth)+":\n")
  39. while self.crawqueue.getQueueCount()!=0:
  40. url=self.crawqueue.pop()
  41. self.log(url)
  42. if url==None:
  43. continue
  44. self.crawqueue.addToVisited(url)
  45. links=self.getLinks(url)
  46. if links==None:
  47. print 'None'
  48. self.crawqueue.failed.append(url)
  49. continue
  50. beforenum = self.crawqueue.getQueueCount()
  51. self.crawqueue.addLinks(links)
  52. afternum = self.crawqueue.getQueueCount()
  53. totalcount+=afternum-beforenum
  54. cur+=1
  55. if cur==last:
  56. depth+=1
  57. self.log(">>>Depth "+str(depth)+":\n")
  58. last=totalcount
  59. def crawling2(self):
  60. global last
  61. global totalcount
  62. global depth
  63. self.log(">>>Depth "+str(depth)+":\n")
  64. totalcount=self.crawqueue.getQueueCount()
  65. last=totalcount
  66. while self.crawqueue.getQueueCount()!=0:
  67. for i in range(self.threadnum):
  68. url=self.crawqueue.pop()
  69. if url==None:
  70. break
  71. crawthread=crawlerThread(url,i,self)
  72. self.threadpools.append(crawthread)
  73. crawthread.start()
  74. for i in range(len(self.threadpools)):
  75. crawthread=self.threadpools[i]
  76. crawthread.join(30)
  77. def log(self,content):
  78. self.logfile.write(content+"\n")
  79. class crawlerThread(threading.Thread):
  80. def __init__(self,url,tid,mycrawler):
  81. threading.Thread.__init__(self)
  82. self.url=url
  83. self.tid=tid
  84. self.mycrawler=mycrawler
  85. def run(self):
  86. global t_mutex
  87. global cur
  88. global last
  89. global totalcount
  90. global depth
  91. t_mutex.acquire()
  92. self.mycrawler.log(self.url)
  93. t_mutex.release()
  94. links=self.getLinks(self.url)
  95. if links==None:
  96. t_mutex.acquire()
  97. self.mycrawler.crawqueue.addToVisited(self.url)
  98. self.mycrawler.crawqueue.addToFailed(self.url)
  99. t_mutex.release()
  100. else:
  101. t_mutex.acquire()
  102. self.mycrawler.crawqueue.addToVisited(self.url)
  103. beforenum=self.mycrawler.crawqueue.getQueueCount()
  104. self.mycrawler.crawqueue.addLinks(links)
  105. afternum =self.mycrawler.crawqueue.getQueueCount()
  106. totalcount+=afternum-beforenum
  107. t_mutex.release()
  108. t_mutex.acquire()
  109. cur+=1
  110. if cur==last:
  111. depth+=1
  112. self.mycrawler.log(">>>Depth "+str(depth)+":\n")
  113. last=totalcount
  114. t_mutex.release()
  115. def getLinks(self,url):
  116. try:
  117. page=urllib.urlopen(url)
  118. html=page.read()
  119. reg=r'"(http://.+?)"'
  120. regob=re.compile(reg,re.DOTALL)
  121. links=regob.findall(html)
  122. return links
  123. except:
  124. print 'Failed downloading and saving',url
  125. return None
  126. class CrawQueue:
  127. def __init__(self):
  128. self.queue=[]
  129. self.visited=[]
  130. self.failed=[]
  131. def getQueue(self):
  132. return self.queue
  133. def getVisited(self):
  134. return self.visited
  135. def getFailed(self):
  136. return self.failed
  137. def push(self,url):
  138. if url!="" and url not in self.queue and url not in self.visited:
  139. self.queue.insert(0,url)
  140. def pop(self):
  141. if len(self.queue)==0:
  142. #print 'failed to pop: queue is empty'
  143. return None
  144. else:
  145. return self.queue.pop()
  146. def isEmpty(self):
  147. if len(self.queue)==0:
  148. return 1
  149. else:
  150. return 0
  151. def addToVisited(self,url):
  152. self.visited.append(url)
  153. def addToFailed(self,url):
  154. self.failed.append(url)
  155. def remove(self,url):
  156. self.queue.remove(url)
  157. def getVisitedCount(self):
  158. return len(self.visited)
  159. def getQueueCount(self):
  160. return len(self.queue)
  161. def addLinks(self,links):
  162. for link in links:
  163. self.push(link)
  164.  
  165. if __name__=="__main__":
  166. seeds="http://www.douban.com/"
  167. threadnum=int(raw_input("设置线程数:"))
  168. crawlername="小小爬虫"
  169. mycrawler=Mycrawler(crawlername,seeds,threadnum)
  170. 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. vscode and python

    http://robotkang.cc/2017/04/VS-Code-%E9%85%8D%E7%BD%AEPython/

  2. 图论trainning-part-2 C. The Largest Clique

    C. The Largest Clique Time Limit: 3000ms Memory Limit: 131072KB 64-bit integer IO format: %lld      ...

  3. VS2010SP1修复补丁&Microsoft Visual Studio 2010 Service Pack 1

    网上比较难找,官网找也容易找错,现在贴出来 补丁包下载地址:链接:https://pan.baidu.com/s/1_tFzXL6PaHiWk3JeRBw0ww 密码:z38k

  4. C语言的那些秘密之---函数返回局部变量[转]

    来源:http://blog.csdn.net/haiwil/article/details/6691854/ 一般的来说,函数是可以返回局部变量的. 局部变量的作用域只在函数内部,在函数返回后,局部 ...

  5. 九度oj 1547

    题目描述: 给定一个初始为空的栈,和n个操作组成的操作序列,每个操作只可能是出栈或者入栈. 要求在操作序列的执行过程中不会出现非法的操作,即不会在空栈时执行出栈操作,同时保证当操作序列完成后,栈恰好为 ...

  6. iOS学习笔记13-网络(二)NSURLSession

    在2013年WWDC上苹果揭开了NSURLSession的面纱,将它作为NSURLConnection的继任者.现在使用最广泛的第三方网络框架:AFNetworking.SDWebImage等等都使用 ...

  7. POJ 2409 Let it Bead ——Burnside引理

    [题目分析] 裸题直接做. 一个长度为n,颜色为m的环,本质不同的染色方案是多少. 数据范围比较小,直接做就好了. [代码] #include <cstdio> #include < ...

  8. [BZOJ1579] [Usaco2009 Feb]Revamping Trails 道路升级(分层图最短路 + 堆优化dijk)

    传送门 dis[i][j]表示第i个点,更新了j次的最短路 此题不良心,卡spfa #include <queue> #include <cstdio> #include &l ...

  9. 雅礼培训 Problem A 【线段树】

    题意 维护一段区间,支持求区间最大值,区间且,区间或 \(n,q<=2*10^5\) 题解 我们用线段树维护区间最大值 对于and和or运算, and实质就是强行把一些位改为0 or实质就是强行 ...

  10. CentOS7下安装Docker-Compose No module named 'requests.packages.urllib3'

    在使用Docker的时候,有一个工具叫做  docker-compose,安装它的前提是要安装pip工具. 1.首先检查Linux有没有安装Python-pip包,直接执行 yum install p ...