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通过装饰器检查函数参数数据类型的方法
Mar 13 Python
python中多层嵌套列表的拆分方法
Jul 02 Python
python 中字典嵌套列表的方法
Jul 03 Python
python url 参数修改方法
Dec 26 Python
python print输出延时,让其立刻输出的方法
Jan 07 Python
对Python的多进程锁的使用方法详解
Feb 18 Python
利用Python绘制有趣的万圣节南瓜怪效果
Oct 31 Python
pyinstaller还原python代码过程图解
Jan 08 Python
python实现ip地址的包含关系判断
Feb 07 Python
一文轻松掌握python语言命名规范规则
Jun 18 Python
python基于pygame实现飞机大作战小游戏
Nov 19 Python
pytorch实现ResNet结构的实例代码
May 17 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 检查扩展库或函数是否可用的代码
2010/04/06 PHP
PHP 中检查或过滤IP地址的实现代码
2011/11/27 PHP
yii操作cookie实例简介
2014/07/09 PHP
开启PHP的伪静态模式
2015/12/31 PHP
PHP中函数gzuncompress无法使用的解决方法
2017/03/02 PHP
javascript 读取图片文件的大小
2009/06/25 Javascript
JQueryEasyUI datagrid框架的进阶使用
2013/04/08 Javascript
js如何取消事件冒泡
2013/09/23 Javascript
js淡入淡出的图片轮播效果代码分享
2015/08/24 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
2015/10/08 Javascript
javascript实现查找数组中最大值方法汇总
2016/02/13 Javascript
纯JavaScript代码实现文本比较工具
2016/02/17 Javascript
JS实现放大、缩小及拖拽图片的方法【可兼容IE、火狐】
2016/08/23 Javascript
js文件中直接alert()中文出来的是乱码的解决方法
2016/11/01 Javascript
vue.js整合vux中的上拉加载下拉刷新实例教程
2018/01/09 Javascript
vscode中vue-cli项目es-lint的配置方法
2018/07/30 Javascript
vue通过滚动行为实现从列表到详情,返回列表原位置的方法
2018/08/31 Javascript
Node.js API详解之 assert模块用法实例分析
2020/05/26 Javascript
[01:01:18]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#2COL VS LGD
2016/03/03 DOTA
python实现csv格式文件转为asc格式文件的方法
2018/03/23 Python
python3将视频流保存为本地视频文件
2018/06/20 Python
pandas中apply和transform方法的性能比较及区别介绍
2018/10/30 Python
对pytorch网络层结构的数组化详解
2018/12/08 Python
Django如何使用jwt获取用户信息
2020/04/21 Python
pandas将list数据拆分成行或列的实现
2020/12/13 Python
用HTML5制作一个简单的桌球游戏的教程
2015/05/12 HTML / CSS
自主招生自荐信
2013/12/08 职场文书
幼儿园元旦亲子活动方案
2014/02/17 职场文书
共产党员公开承诺书范文
2014/03/28 职场文书
导航工程专业自荐信
2014/09/02 职场文书
村主任个人对照检查材料
2014/10/01 职场文书
二手房购房意向书
2015/05/09 职场文书
中学教师教学工作总结
2015/08/13 职场文书
德劲DE1108畅想
2021/04/22 无线电
CSS完成视差滚动效果
2021/04/27 HTML / CSS
MySQL中varchar和char类型的区别
2021/11/17 MySQL