基python实现多线程网页爬虫


Posted in Python onSeptember 06, 2015

一般来说,使用线程有两种模式, 一种是创建线程要执行的函数, 把这个函数传递进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定时采集摄像头图像上传ftp服务器功能实现
Dec 23 Python
Python中apply函数的用法实例教程
Jul 31 Python
Python基类函数的重载与调用实例分析
Jan 12 Python
python批量生成本地ip地址的方法
Mar 23 Python
python+splinter实现12306网站刷票并自动购票流程
Sep 25 Python
解决Python print输出不换行没空格的问题
Nov 14 Python
使用Fabric自动化部署Django项目的实现
Sep 27 Python
Python3.7 读取 mp3 音频文件生成波形图效果
Nov 05 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
Nov 19 Python
python获取整个网页源码的方法
Aug 03 Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
Aug 07 Python
Python合并pdf文件的工具
Jul 01 Python
python杀死一个线程的方法
Sep 06 #Python
在Python的Flask框架中验证注册用户的Email的方法
Sep 02 #Python
Python实现身份证号码解析
Sep 01 #Python
实例Python处理XML文件的方法
Aug 31 #Python
通过实例浅析Python对比C语言的编程思想差异
Aug 30 #Python
使用Python脚本将文字转换为图片的实例分享
Aug 29 #Python
Python中常见的数据类型小结
Aug 29 #Python
You might like
Ajax+PHP 边学边练 之二 实例
2009/11/24 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
php-app开发接口加密详解
2018/04/18 PHP
jquery.validate分组验证代码
2011/03/17 Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
2014/06/30 Javascript
小心!AngularJS结合RequireJS做文件合并压缩的那些坑
2016/01/09 Javascript
AngularJS模块学习之Anchor Scroll
2016/01/19 Javascript
html+js实现简单的计算器代码(加减乘除)
2016/07/12 Javascript
教你如何在Node.js中使用jQuery
2016/08/28 Javascript
AngularJS ngModel实现指令与输入直接的数据通信
2016/09/21 Javascript
详解微信开发中snsapi_base和snsapi_userinfo及静默授权的实现
2017/03/11 Javascript
纯jQuery实现前端分页功能
2017/03/23 jQuery
Ajax异步文件上传与NodeJS express服务端处理
2017/04/01 NodeJs
解决bootstrap中使用modal加载kindeditor时弹出层文本框不能输入的问题
2017/06/05 Javascript
详解Webpack+Babel+React开发环境的搭建的方法步骤
2018/01/09 Javascript
js获取form表单中name属性的值
2019/02/27 Javascript
微信小程序实现点赞业务
2021/02/10 Javascript
JavaScript实现H5接金币功能(实例代码)
2021/02/22 Javascript
python通过cookie模拟已登录状态的初步研究
2016/11/09 Python
Python 绘图和可视化详细介绍
2017/02/11 Python
python下实现二叉堆以及堆排序的示例
2017/09/29 Python
Python编程scoketServer实现多线程同步实例代码
2018/01/29 Python
python3 tkinter实现点击一个按钮跳出另一个窗口的方法
2019/06/13 Python
Python 捕获代码中所有异常的方法
2020/08/03 Python
html5触摸事件判断滑动方向的实现
2018/06/05 HTML / CSS
html5 Web SQL Database 之事务处理函数transaction与executeSQL解析
2013/11/07 HTML / CSS
详解WebSocket跨域问题解决
2018/08/06 HTML / CSS
化工机械应届生求职信
2013/11/04 职场文书
保险专业自荐信范文
2014/02/20 职场文书
幼儿园毕业致辞
2015/07/29 职场文书
超级实用的公文标题大全!
2019/07/19 职场文书
HTML5页面音频自动播放的实现方式
2021/06/21 HTML / CSS
一文搞懂python异常处理、模块与包
2021/06/26 Python
SQL中的三种去重方法小结
2021/11/01 SQL Server
分布式架构Redis中有哪些数据结构及底层实现原理
2022/03/13 Redis
vue3语法糖内的defineProps及defineEmits
2022/04/14 Vue.js