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实现拉钩网上的FizzBuzzWhizz问题示例
May 05 Python
Python入门篇之列表和元组
Oct 17 Python
初步解析Python中的yield函数的用法
Apr 03 Python
python读取word文档的方法
May 09 Python
Python中使用Queue和Condition进行线程同步的方法
Jan 19 Python
浅谈Python 对象内存占用
Jul 15 Python
使用python进行波形及频谱绘制的方法
Jun 17 Python
pyqt5 获取显示器的分辨率的方法
Jun 18 Python
Python数据可视化:顶级绘图库plotly详解
Dec 07 Python
Python MySQLdb 执行sql语句时的参数传递方式
Mar 04 Python
Python3爬虫中Splash的知识总结
Jul 10 Python
浅析NumPy 切片和索引
Sep 02 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下通过curl抓取yahoo boss 搜索结果的实现代码
2011/06/10 PHP
解决file_get_contents无法请求https连接的方法
2013/12/17 PHP
分享最受欢迎的5款PHP框架
2014/11/27 PHP
PHP实现json_decode不转义中文的方法
2017/05/20 PHP
php中通用的excel导出方法实例
2017/12/30 PHP
php apache开启跨域模式过程详解
2019/07/08 PHP
jQuery+easyui中的combobox实现下拉框特效
2015/02/27 Javascript
jQuery插件datepicker 日期连续选择
2015/06/12 Javascript
node.js读取文件到字符串的方法
2015/06/29 Javascript
完美实现八种js焦点轮播图(上篇)
2016/07/18 Javascript
JS实现列表的响应式排版(推荐)
2016/09/01 Javascript
jQuery实现的form转json经典示例
2017/10/10 jQuery
JavaScript实现点击出现图片并统计点击次数功能示例
2018/07/23 Javascript
Vue监听页面刷新和关闭功能
2019/06/20 Javascript
vue 实现Web端的定位功能 获取经纬度
2019/08/08 Javascript
微信小程序转发事件实现解析
2019/10/22 Javascript
vue实现在线预览pdf文件和下载(pdf.js)
2019/11/26 Javascript
[02:04]2018DOTA2亚洲邀请赛Secret赛前采访
2018/04/03 DOTA
[55:16]Mski vs VGJ.S Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
Python中单线程、多线程和多进程的效率对比实验实例
2019/05/14 Python
Python3.7 新特性之dataclass装饰器
2019/05/27 Python
keras使用Sequence类调用大规模数据集进行训练的实现
2020/06/22 Python
pytorch 计算ConvTranspose1d输出特征大小方式
2020/06/23 Python
中外合拍动画首获奥斯卡提名,“上海出品”《飞奔去月球》能否拿下最终大奖?
2021/03/16 国漫
详解HTML5中垂直上下居中的解决方案
2017/12/20 HTML / CSS
iPad和Surface Pro蓝牙键盘:Brydge
2018/11/10 全球购物
某公司面试题
2012/03/05 面试题
初婚未育未抱养证明
2014/01/12 职场文书
出纳员岗位职责
2014/03/13 职场文书
车辆委托书范本
2014/10/05 职场文书
学习十八大标语
2014/10/09 职场文书
2015会计试用期工作总结
2014/12/12 职场文书
清洁工个人工作总结
2015/03/05 职场文书
幸福来敲门观后感
2015/06/04 职场文书
《合作意向书》怎么写?
2019/08/20 职场文书
Python Pandas pandas.read_sql_query函数实例用法分析
2021/06/21 Python