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通过索引遍历列表的方法
May 04 Python
python 简单的绘图工具turtle使用详解
Jun 21 Python
Python单体模式的几种常见实现方法详解
Jul 28 Python
Python实现的矩阵类实例
Aug 22 Python
python提取具有某种特定字符串的行数据方法
Dec 11 Python
详解Python循环作用域与闭包
Mar 21 Python
Python中一些深不见底的“坑”
Jun 12 Python
PyQt5 在label显示的图片中绘制矩形的方法
Jun 17 Python
Linux下升级安装python3.8并配置pip及yum的教程
Jan 02 Python
python实现梯度下降法
Mar 24 Python
完美解决pycharm 不显示代码提示问题
Jun 02 Python
Django如何实现密码错误报错提醒
Sep 04 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和MySql中计算时间差的方法详解
2015/03/27 PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
2016/12/15 PHP
PHP合并数组函数array_merge用法分析
2017/02/17 PHP
浅谈Yii乐观锁的使用及原理
2017/07/25 PHP
详解Yaf框架PHPUnit集成测试方法
2017/12/27 PHP
使弱类型的语言JavaScript变强势
2009/06/22 Javascript
jquery animate 动画效果使用说明
2009/11/04 Javascript
读取input:file的路径并显示本地图片的方法
2013/09/23 Javascript
jquery 获取 outerHtml 包含当前节点本身的代码
2014/10/30 Javascript
javascript实现base64 md5 sha1 密码加密
2015/09/09 Javascript
jQuery实现可以控制图片旋转角度效果(附demo源码下载)
2016/01/27 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
2016/04/06 Javascript
js仿支付宝多方框输入支付密码效果
2016/09/27 Javascript
js实现点击图片自动提交action的简单方法
2016/10/16 Javascript
使用DeviceOne实现微信小程序功能
2016/12/29 Javascript
微信小程序 增、删、改、查操作实例详解
2017/01/13 Javascript
Vue中添加过渡效果的方法
2017/03/16 Javascript
element上传组件循环引用及简单时间倒计时的实现
2018/10/01 Javascript
vue实现的组件兄弟间通信功能示例
2018/12/04 Javascript
vue项目中使用fetch的实现方法
2019/04/25 Javascript
Vue基于iview table展示图片实现点击放大
2020/08/05 Javascript
使用Python判断IP地址合法性的方法实例
2014/03/13 Python
Python下载指定页面上图片的方法
2016/05/12 Python
对python函数签名的方法详解
2019/01/22 Python
Python实现将蓝底照片转化为白底照片功能完整实例
2019/12/13 Python
谈一谈数组拼接tf.concat()和np.concatenate()的区别
2020/02/07 Python
python中通过pip安装库文件时出现“EnvironmentError: [WinError 5] 拒绝访问”的问题及解决方案
2020/08/11 Python
解决Firefox下不支持outerHTML问题代码分享
2014/06/04 HTML / CSS
Gibson London官网:以地道的英国男装而著称
2019/12/06 全球购物
房地产经营管理专业自荐信
2014/09/02 职场文书
法制教育主题班会
2015/08/13 职场文书
MySQL一些常用高级SQL语句
2021/07/03 MySQL
高性能跳频抗干扰宽带自组网电台
2022/02/18 无线电
《吸血鬼幸存者》新内容发布 追加多个全新模式
2022/04/07 其他游戏
css3属性选择器 “~”(波浪号) “,”(逗号) “+”(加号)和 “>”(大于号)
2022/04/19 HTML / CSS
python区块链持久化和命令行接口实现简版
2022/05/25 Python