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重试装饰器示例
Feb 11 Python
Python实现读取并保存文件的类
May 11 Python
用生成器来改写直接返回列表的函数方法
May 25 Python
python jieba分词并统计词频后输出结果到Excel和txt文档方法
Feb 11 Python
python 多维切片之冒号和三个点的用法介绍
Apr 19 Python
Python SVM(支持向量机)实现方法完整示例
Jun 19 Python
python如何实现一个刷网页小程序
Nov 27 Python
PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形
May 13 Python
django的分页器Paginator 从django中导入类
Jul 25 Python
使用python写的opencv实时监测和解析二维码和条形码
Aug 14 Python
Django静态文件加载失败解决方案
Aug 26 Python
Pytorch实现WGAN用于动漫头像生成
Mar 04 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 insert语法详解
2008/06/07 PHP
编写安全 PHP应用程序的七个习惯深入分析
2013/06/08 PHP
PHP实现伪静态方法汇总
2016/01/13 PHP
PHP Trait代码复用类与多继承实现方法详解
2019/06/17 PHP
php实现通过stomp协议连接ActiveMQ操作示例
2020/02/23 PHP
浅谈关于JavaScript的语言特性分析
2013/04/11 Javascript
让table变成exls的示例代码
2014/03/24 Javascript
Node.js文件操作详解
2014/08/16 Javascript
jQuery中find()方法用法实例
2015/01/07 Javascript
基于JavaScript代码实现随机漂浮图片广告
2016/01/05 Javascript
js只执行1次的函数示例
2016/07/20 Javascript
Angular.JS判断复选框checkbox是否选中并实时显示
2016/11/30 Javascript
用node和express连接mysql实现登录注册的实现代码
2017/07/05 Javascript
JavaScript基础之流程控制语句的用法
2017/08/31 Javascript
react-router browserHistory刷新页面404问题解决方法
2017/12/29 Javascript
使用layer弹窗和layui表单实现新增功能
2018/08/09 Javascript
如何用Node写页面爬虫的工具集
2018/10/26 Javascript
JavaScript实现小球沿正弦曲线运动
2020/09/07 Javascript
详解iframe跨域的几种常用方法(小结)
2019/04/29 Javascript
微信小程序点餐系统开发常见问题汇总
2019/08/06 Javascript
vue.js watch经常失效的场景与解决方案
2021/01/07 Vue.js
利用python获取某年中每个月的第一天和最后一天
2016/12/15 Python
python逆向入门教程
2018/01/15 Python
Python中print和return的作用及区别解析
2019/05/05 Python
Python比较配置文件的方法实例详解
2019/06/06 Python
Python的互斥锁与信号量详解
2019/09/12 Python
Python Websocket服务端通信的使用示例
2020/02/25 Python
Django bulk_create()、update()与数据库事务的效率对比分析
2020/05/15 Python
Python列表嵌套常见坑点及解决方案
2020/09/30 Python
世界上最大的在线汽车租赁预订平台:Rentalcars.com(支持中文)
2018/10/12 全球购物
浙大网新C/C++面试解惑
2015/05/27 面试题
关于毕业的中学校园广播稿
2014/01/26 职场文书
专家推荐信模板
2014/05/09 职场文书
大学生党员批评与自我批评范文
2014/10/14 职场文书
2014年学校卫生工作总结
2014/11/20 职场文书
如何设置多台电脑共享打印机?多台电脑共享打印机的方法
2022/04/08 数码科技