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基于pygame实现的弹力球效果(附源码)
Nov 11 Python
Python数据拟合与广义线性回归算法学习
Dec 22 Python
python抓取网站的图片并下载到本地的方法
May 22 Python
将Django项目部署到CentOs服务器中
Oct 18 Python
python实现维吉尼亚算法
Mar 20 Python
通过cmd进入python的实例操作
Jun 26 Python
python文件转为exe文件的方法及用法详解
Jul 08 Python
PYTHON实现SIGN签名的过程解析
Oct 28 Python
Python填充任意颜色,不同算法时间差异分析说明
May 16 Python
python连接mysql有哪些方法
Jun 24 Python
Python pip使用超时问题解决方案
Aug 03 Python
pytorch训练神经网络爆内存的解决方案
May 22 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
PL-880隐藏功能
2021/03/01 无线电
PHP 表单提交给自己
2008/07/24 PHP
PHP基础学习小结
2011/04/17 PHP
php生成shtml类用法实例
2014/12/09 PHP
php把数组值转换成键的方法
2015/07/13 PHP
thinkPHP3.x常量整理(预定义常量/路径常量/系统常量)
2016/05/20 PHP
PHP面向对象程序设计组合模式与装饰模式详解
2016/12/02 PHP
php中bind_param()函数用法分析
2017/03/28 PHP
PHP大文件分割分片上传实现代码
2020/12/09 PHP
Javascript 构造函数 实例分析
2008/11/26 Javascript
表单元素事件 (Form Element Events)
2009/07/17 Javascript
jQuery之$(document).ready()使用介绍
2012/04/05 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
2015/04/03 Javascript
Bootstrap优化站点资源、响应式图片、传送带使用详解3
2016/10/14 Javascript
NodeJs测试框架Mocha的安装与使用
2017/03/28 NodeJs
w3c编程挑战_初级脚本算法实战篇
2017/06/23 Javascript
vue2.0使用v-for循环制作多级嵌套菜单栏
2018/06/25 Javascript
微信小程序和百度的语音识别接口详解
2019/05/06 Javascript
vue引入静态js文件的方法
2020/06/20 Javascript
[00:32]10月24、25日 辉夜杯外卡赛附加赛开赛!
2015/10/23 DOTA
[01:18]PWL开团时刻DAY10——一拳超人
2020/11/11 DOTA
浅谈python中copy和deepcopy中的区别
2017/10/23 Python
Python一键查找iOS项目中未使用的图片、音频、视频资源
2019/08/12 Python
在django-xadmin中APScheduler的启动初始化实例
2019/11/15 Python
Python 解码Base64 得到码流格式文本实例
2020/01/09 Python
Python实现投影法分割图像示例(二)
2020/01/17 Python
欧姆龙医疗保健与医疗产品:Omron Healthcare
2020/02/10 全球购物
应届生服务员求职信
2013/10/31 职场文书
网页美工求职信
2014/02/15 职场文书
经典洗发水广告词
2014/03/13 职场文书
遗嘱继承公证书
2014/04/09 职场文书
2015年教师节活动总结
2015/03/20 职场文书
天堂的孩子观后感
2015/06/11 职场文书
2016年学生会感恩节活动总结
2016/04/01 职场文书
pytorch Dropout过拟合的操作
2021/05/27 Python
WebWorker 封装 JavaScript 沙箱详情
2021/11/02 Javascript