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线程池的实现实例
Nov 18 Python
python编写网页爬虫脚本并实现APScheduler调度
Jul 28 Python
Python实现CET查分的方法
Mar 10 Python
Python制作爬虫抓取美女图
Jan 20 Python
详解Python进程间通信之命名管道
Aug 28 Python
Python实现简单的HttpServer服务器示例
Sep 25 Python
Python动态导入模块的方法实例分析
Jun 28 Python
python函数与方法的区别总结
Jun 23 Python
远程部署工具Fabric详解(支持Python3)
Jul 04 Python
django实现支付宝支付实例讲解
Oct 17 Python
解决python中的幂函数、指数函数问题
Nov 25 Python
关于多元线性回归分析——Python&amp;SPSS
Feb 24 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
星际玩家的三大定律
2020/03/04 星际争霸
一键删除顽固的空文件夹 软件下载
2007/01/26 PHP
使用ThinkPHP自带的Http类下载远程图片到本地的实现代码
2011/08/02 PHP
PHP下判断网址是否有效的代码
2011/10/08 PHP
linux系统下php安装mbstring扩展的二种方法
2014/01/20 PHP
PHP页面转UTF-8中文编码乱码的解决办法
2015/10/20 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
javascript 基础篇1 什么是js 建立第一个js程序
2012/03/14 Javascript
jquery 简单应用示例总结
2013/08/09 Javascript
禁用Tab键JS代码兼容Firefox和IE
2014/04/18 Javascript
Javascript异步编程模型Promise模式详细介绍
2014/05/08 Javascript
JavaScript将数字转换成大写中文的方法
2015/03/23 Javascript
JS实现图片高亮展示效果实例
2015/11/24 Javascript
JavaScript截取、切割字符串的技巧
2016/01/07 Javascript
jquery+css3实现会动的小圆圈效果
2016/01/27 Javascript
如何消除inline-block属性带来的标签间间隙
2016/03/31 Javascript
原生态js,鼠标按下后,经过了那些单元格的简单实例
2016/08/11 Javascript
js获取页面引用的css样式表中的属性值方法(推荐)
2016/08/19 Javascript
javascript实现消灭星星小游戏简单版
2016/11/15 Javascript
js 单引号替换成双引号,双引号替换成单引号的实现方法
2017/02/16 Javascript
了解JavaScript表单操作和表单域
2019/05/27 Javascript
layui动态渲染生成左侧3级菜单的方法(根据后台返回数据)
2019/09/23 Javascript
[02:53]DOTA2亚洲邀请赛 NewBee战队巡礼
2015/02/03 DOTA
[02:02:38]VG vs Mineski Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
编写Python脚本来实现最简单的FTP下载的教程
2015/05/04 Python
用python标准库difflib比较两份文件的异同详解
2018/11/16 Python
对Python 语音识别框架详解
2018/12/24 Python
keras中epoch,batch,loss,val_loss用法说明
2020/07/02 Python
Dyson加拿大官方网站:购买戴森吸尘器,风扇,冷热器及配件
2016/10/26 全球购物
社保转移委托书范本
2014/10/08 职场文书
交警失职检讨书
2015/01/26 职场文书
反腐倡廉主题教育活动总结
2015/05/07 职场文书
2015少先队大队辅导员工作总结
2015/07/24 职场文书
2016教师廉洁从教心得体会
2016/01/13 职场文书
手把手教你实现PyTorch的MNIST数据集
2021/06/28 Python
ORACLE中dbms_output.put_line输出问题的解决过程
2022/06/28 Oracle