python支持多线程的爬虫实例


Posted in Python onDecember 21, 2019

python是支持多线程的, 主要是通过thread和threading这两个模块来实现的,本文主要给大家分享python实现多线程网页爬虫

一般来说,使用线程有两种模式, 一种是创建线程要执行的函数, 把这个函数传递进Thread对象里,让它来执行. 另一种是直接从Thread继承,创建一个新的class,把线程执行的代码放到这个新的class里。

实现多线程网页爬虫,采用了多线程和锁机制,实现了广度优先算法的网页爬虫。

先给大家简单介绍下我的实现思路:

对于一个网络爬虫,如果要按广度遍历的方式下载,它是这样的:

1.从给定的入口网址把第一个网页下载下来

2.从第一个网页中提取出所有新的网页地址,放入下载列表中

3.按下载列表中的地址,下载所有新的网页

4.从所有新的网页中找出没有下载过的网页地址,更新下载列表

5.重复3、4两步,直到更新后的下载列表为空表时停止

python代码如下:

#!/usr/bin/env python
#coding=utf-8
import threading
import urllib
import re
import time
g_mutex=threading.Condition()
g_pages=[] #从中解析所有url链接
g_queueURL=[] #等待爬取的url链接列表
g_existURL=[] #已经爬取过的url链接列表
g_failedURL=[] #下载失败的url链接列表
g_totalcount=0 #下载过的页面数
class Crawler:
 def __init__(self,crawlername,url,threadnum):
  self.crawlername=crawlername
  self.url=url
  self.threadnum=threadnum
  self.threadpool=[]
  self.logfile=file("log.txt",'w')
 def craw(self):
  global g_queueURL
  g_queueURL.append(url) 
  depth=0
  print self.crawlername+" 启动..."
  while(len(g_queueURL)!=0):
   depth+=1
   print 'Searching depth ',depth,'...\n\n'
   self.logfile.write("URL:"+g_queueURL[0]+"........")
   self.downloadAll()
   self.updateQueueURL()
   content='\n>>>Depth '+str(depth)+':\n'
   self.logfile.write(content)
   i=0
   while i<len(g_queueURL):
    content=str(g_totalcount+i)+'->'+g_queueURL[i]+'\n'
    self.logfile.write(content)
    i+=1
 def downloadAll(self):
  global g_queueURL
  global g_totalcount
  i=0
  while i<len(g_queueURL):
   j=0
   while j<self.threadnum and i+j < len(g_queueURL):
    g_totalcount+=1
    threadresult=self.download(g_queueURL[i+j],str(g_totalcount)+'.html',j)
    if threadresult!=None:
     print 'Thread started:',i+j,'--File number =',g_totalcount
    j+=1
   i+=j
   for thread in self.threadpool:
    thread.join(30)
   threadpool=[]
  g_queueURL=[]
 def download(self,url,filename,tid):
  crawthread=CrawlerThread(url,filename,tid)
  self.threadpool.append(crawthread)
  crawthread.start()
 def updateQueueURL(self):
  global g_queueURL
  global g_existURL
  newUrlList=[]
  for content in g_pages:
   newUrlList+=self.getUrl(content)
  g_queueURL=list(set(newUrlList)-set(g_existURL)) 
 def getUrl(self,content):
  reg=r'"(http://.+?)"'
  regob=re.compile(reg,re.DOTALL)
  urllist=regob.findall(content)
  return urllist
class CrawlerThread(threading.Thread):
 def __init__(self,url,filename,tid):
  threading.Thread.__init__(self)
  self.url=url
  self.filename=filename
  self.tid=tid
 def run(self):
  global g_mutex
  global g_failedURL
  global g_queueURL
  try:
   page=urllib.urlopen(self.url)
   html=page.read()
   fout=file(self.filename,'w')
   fout.write(html)
   fout.close()
  except Exception,e:
   g_mutex.acquire()
   g_existURL.append(self.url)
   g_failedURL.append(self.url)
   g_mutex.release()
   print 'Failed downloading and saving',self.url
   print e
   return None
  g_mutex.acquire()
  g_pages.append(html)
  g_existURL.append(self.url)
  g_mutex.release()
if __name__=="__main__":
 url=raw_input("请输入url入口:\n")
 threadnum=int(raw_input("设置线程数:"))
 crawlername="小小爬虫"
 crawler=Crawler(crawlername,url,threadnum)
 crawler.craw()

以上这篇python支持多线程的爬虫实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers
Nov 05 Python
使用Python编写一个模仿CPU工作的程序
Apr 16 Python
python使用turtle库绘制树
Jun 25 Python
解决pycharm安装后代码区不能编辑的问题
Oct 28 Python
pycharm运行程序时在Python console窗口中运行的方法
Dec 03 Python
使用python list 查找所有匹配元素的位置实例
Jun 11 Python
django 使用 PIL 压缩图片的例子
Aug 16 Python
Python递归调用实现数字累加的代码
Feb 25 Python
Python正则表达式学习小例子
Mar 03 Python
python矩阵运算,转置,逆运算,共轭矩阵实例
May 11 Python
python相对企业语言优势在哪
Jun 12 Python
Python Selenium操作Cookie的实例方法
Feb 28 Python
Python 实现try重新执行
Dec 21 #Python
在python shell中运行python文件的实现
Dec 21 #Python
Python 脚本的三种执行方式小结
Dec 21 #Python
python带参数打包exe及调用方式
Dec 21 #Python
python脚本后台执行方式
Dec 21 #Python
Python模块的制作方法实例分析
Dec 21 #Python
基于Python 中函数的 收集参数 机制
Dec 21 #Python
You might like
php验证是否是md5编码的简单代码
2014/04/01 PHP
Thinkphp自定义代码生成工具及用法说明(附下载地址)
2016/05/27 PHP
解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示
2016/11/25 PHP
修复ie8&amp;chrome下window的resize事件多次执行
2011/10/20 Javascript
基于jQuery的360图片展示实现代码
2012/06/14 Javascript
基于js disabled=&quot;false&quot;不起作用的解决办法
2013/06/26 Javascript
jQuery ajax serialize() 方法使用示例
2014/11/02 Javascript
Javascript从数组中随机取出不同元素的两种方法
2016/09/22 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
2017/07/07 Javascript
Vue filter介绍及详细使用
2018/04/04 Javascript
Angular Material Icon使用详解
2018/11/07 Javascript
express 项目分层实践详解
2018/12/10 Javascript
node app 打包工具pkg的具体使用
2019/01/17 Javascript
JS实现鼠标移动拖尾
2020/12/27 Javascript
实例讲解python函数式编程
2014/06/09 Python
简单介绍Python的Django框架加载模版的方式
2015/07/20 Python
Python处理文本文件中控制字符的方法
2017/02/07 Python
shell命令行,一键创建 python 模板文件脚本方法
2018/03/20 Python
Python实现的HMacMD5加密算法示例
2018/04/03 Python
Django Web开发中django-debug-toolbar的配置以及使用
2018/05/06 Python
python使用Flask操作mysql实现登录功能
2018/05/14 Python
python中退出多层循环的方法
2018/11/27 Python
PyCharm在新窗口打开项目的方法
2019/01/17 Python
python词云库wordCloud使用方法详解(解决中文乱码)
2020/02/17 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
2020/06/08 Python
快速了解Python开发环境Spyder
2020/06/29 Python
关于css兼容性问题及一些常见问题汇总
2016/05/03 HTML / CSS
德国著名廉价网上药店:Shop-Apotheke
2017/07/23 全球购物
纽约手袋品牌:KARA
2018/03/18 全球购物
彪马土耳其官网:PUMA土耳其
2019/07/14 全球购物
四年级数学教学反思
2014/02/02 职场文书
广播体操口号
2014/06/18 职场文书
感恩教育月活动总结
2014/07/07 职场文书
2014财产信托协议书范本
2014/11/18 职场文书
任命书标准格式
2015/03/02 职场文书
2015年大班保育员工作总结
2015/05/18 职场文书