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 08 Python
用Python进行TCP网络编程的教程
Apr 29 Python
探究Python多进程编程下线程之间变量的共享问题
May 05 Python
python定时执行指定函数的方法
May 27 Python
python实现域名系统(DNS)正向查询的方法
Apr 19 Python
基于python元祖与字典与集合的粗浅认识
Aug 23 Python
Python利用itchat库向好友或者公众号发消息的实例
Feb 21 Python
基于python进行抽样分布描述及实践详解
Sep 02 Python
python读取ini配置的类封装代码实例
Jan 08 Python
Selenium基于PIL实现拼接滚动截图
Apr 10 Python
基于python代码批量处理图片resize
Jun 04 Python
基于Python爬取京东双十一商品价格曲线
Oct 23 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+JavaScript实现无刷新上传图片
2017/02/21 PHP
Yii2汉字转拼音类的实例代码
2017/04/18 PHP
捕获关闭窗口的脚本
2009/01/10 Javascript
JavaScript 组件之旅(三):用 Ant 构建组件
2009/10/28 Javascript
javascript中substr,substring,slice.splice的区别说明
2010/11/25 Javascript
Node.js中的缓冲与流模块详细介绍
2015/02/11 Javascript
JS仿百度自动下拉框模糊匹配提示
2016/07/25 Javascript
js实现复选框的全选和取消全选效果
2017/01/03 Javascript
Reactjs实现通用分页组件的实例代码
2017/01/19 Javascript
5分钟打造简易高效的webpack常用配置
2017/07/04 Javascript
Vue.js项目模板搭建图文教程
2017/09/20 Javascript
JS基于开关思想实现的数组去重功能【案例】
2019/02/18 Javascript
jQuery each和js forEach用法比较
2019/02/27 jQuery
vant 时间选择器--开始时间和结束时间实例
2020/11/04 Javascript
vue实现可移动的悬浮按钮
2021/03/04 Vue.js
python opencv实现任意角度的透视变换实例代码
2018/01/12 Python
python实现图像识别功能
2018/01/29 Python
python3 读写文件换行符的方法
2018/04/09 Python
使用Django2快速开发Web项目的详细步骤
2019/01/06 Python
Django model update的多种用法介绍
2020/03/28 Python
python 调试冷知识(小结)
2019/11/11 Python
Python实现钉钉订阅消息功能
2020/01/14 Python
KLOOK客路:发现更好玩的世界,预订独一无二的旅行体验
2016/12/16 全球购物
加拿大廉价机票预订网站:CheapOair.ca
2018/03/04 全球购物
广州足迹信息技术有限公司Java软件工程师试题
2014/02/15 面试题
蛋糕店创业计划书
2014/05/06 职场文书
投标保密承诺书
2014/05/19 职场文书
预防传染病方案
2014/06/14 职场文书
英文辞职信范文
2015/05/13 职场文书
天那边观后感
2015/06/09 职场文书
逃出克隆岛观后感
2015/06/09 职场文书
2019年朋友圈经典励志语录50条
2019/07/05 职场文书
正能量励志演讲稿三分钟(范文)
2019/07/11 职场文书
浅谈由position属性引申的css进阶讨论
2021/05/25 HTML / CSS
python常见的占位符总结及用法
2021/07/02 Python
vue 给数组添加新对象并赋值
2022/04/20 Vue.js