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 线程池threadpool之实现
Nov 17 Python
机器学习10大经典算法详解
Dec 07 Python
使用pandas对矢量化数据进行替换处理的方法
Apr 11 Python
对pandas处理json数据的方法详解
Feb 08 Python
详解Python 切片语法
Jun 10 Python
python retrying模块的使用方法详解
Sep 25 Python
Python 时间戳之获取整点凌晨时间戳的操作方法
Jan 28 Python
tensorflow之tf.record实现存浮点数数组
Feb 17 Python
OpenCV 之按位运算举例解析
Jun 19 Python
python按顺序重命名文件并分类转移到各个文件夹中的实现代码
Jul 21 Python
解决Pytorch修改预训练模型时遇到key不匹配的情况
Jun 05 Python
Python中Matplotlib的点、线形状、颜色以及绘制散点图
Apr 07 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
ie6 动态缩略图不显示的原因
2009/06/21 PHP
PHP number_format() 函数定义和用法
2012/06/01 PHP
php中strstr、strrchr、substr、stristr四个函数的区别总结
2014/09/22 PHP
PHP匿名函数和use子句用法实例
2016/03/16 PHP
JavaScript面象对象设计
2008/04/28 Javascript
推荐30个新鲜出炉的精美 jQuery 效果
2012/03/26 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理
2015/11/24 Javascript
谈谈我对JavaScript DOM事件的理解
2015/12/18 Javascript
js实现目录链接,内容跟着目录滚动显示的简单实例
2016/10/15 Javascript
简单实现jQuery多选框功能
2017/01/09 Javascript
jquery实现放大镜简洁代码(推荐)
2017/06/08 jQuery
jQuery中 DOM节点操作方法大全
2017/10/12 jQuery
详解vue中使用protobuf踩坑记
2019/05/07 Javascript
了解前端理论:rscss和rsjs
2019/05/23 Javascript
JavaScript面向对象核心知识与概念归纳整理
2020/05/09 Javascript
JavaScript中数组去重的5种方法
2020/07/04 Javascript
prettier自动格式化去换行的实现代码
2020/08/25 Javascript
Python实现批量更换指定目录下文件扩展名的方法
2016/09/19 Python
python将字典内容存入mysql实例代码
2018/01/18 Python
Python2与Python3的区别实例分析
2019/04/11 Python
Python如何处理大数据?3个技巧效率提升攻略(推荐)
2019/04/15 Python
机器学习实战之knn算法pandas
2019/06/22 Python
Python Web静态服务器非堵塞模式实现方法示例
2019/11/21 Python
django使用F方法更新一个对象多个对象字段的实现
2020/03/28 Python
python导入库的具体方法
2020/06/18 Python
大专毕业生自我鉴定
2013/11/21 职场文书
有兼职工作经历的简历自我评价
2014/03/07 职场文书
公司领导班子对照检查材料
2014/09/24 职场文书
出售房屋委托书范本
2014/09/24 职场文书
工伤死亡理赔协议书
2014/10/20 职场文书
自主招生推荐信怎么写
2015/03/26 职场文书
铁人观后感
2015/06/16 职场文书
新郎新娘致辞
2015/07/31 职场文书
职场新人知识:如何制定一份合理的工作计划?
2019/09/11 职场文书
新手初学Java网络编程
2021/07/07 Java/Android
zabbix 代理服务器的部署与 zabbix-snmp 监控问题
2022/07/15 Servers