基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 logging类库使用例子
Nov 22 Python
Python中使用插入排序算法的简单分析与代码示例
May 04 Python
python如何实现反向迭代
Mar 20 Python
Python pymongo模块用法示例
Mar 31 Python
APIStar:一个专为Python3设计的API框架
Sep 26 Python
用Python逐行分析文件方法
Jan 28 Python
使用 Python 玩转 GitHub 的贡献板(推荐)
Apr 04 Python
Python实现隐马尔可夫模型的前向后向算法的示例代码
Dec 31 Python
Python语言异常处理测试过程解析
Jan 08 Python
python圣诞树编写实例详解
Feb 13 Python
虚拟机下载python是否需要联网
Jul 27 Python
Python抖音快手代码舞(字符舞)的实现方法
Feb 07 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
PHP HTML代码串 截取实现代码
2009/06/29 PHP
PHP中文竖排转换实现方法
2015/10/23 PHP
php排序算法实例分析
2016/10/17 PHP
laravel model模型处理之修改查询或修改字段时的类型格式案例
2019/10/17 PHP
用JavaScript获取网页中的js、css、Flash等文件
2006/12/20 Javascript
Open and Print a Word Document
2007/06/15 Javascript
javascript数组的扩展实现代码集合
2008/06/01 Javascript
Javascript学习笔记1 数据类型
2010/01/11 Javascript
基于jquery的inputlimiter 实现字数限制功能
2010/05/30 Javascript
汉化英文版的Dreamweaver CS5并自动提示jquery
2010/11/25 Javascript
JSDoc 介绍使用规范JsDoc的使用介绍
2011/02/12 Javascript
原生javascript图片自动或手动切换示例附演示源码
2013/09/04 Javascript
jquery等宽输出文字插件使用介绍
2013/09/18 Javascript
avalonjs实现仿微博的图片拖动特效
2015/05/06 Javascript
JS模仿手机端九宫格登录功能实现代码
2016/04/28 Javascript
jQuery事件绑定方法学习总结(推荐)
2016/11/21 Javascript
JS中如何实现Laravel的route函数详解
2017/02/12 Javascript
vuejs使用递归组件实现树形目录的方法
2017/09/30 Javascript
jQuery中extend函数简单用法示例
2017/10/11 jQuery
使用vue2实现购物车和地址选配功能
2018/03/29 Javascript
详解Vue.js自定义tipOnce指令用法实例
2018/12/19 Javascript
js+html5 canvas实现ps钢笔抠图
2019/04/28 Javascript
关于引入vue.js 文件的知识点总结
2020/01/28 Javascript
[03:15]2014DOTA2国际邀请赛 专访国士无双信心满满
2014/07/12 DOTA
10款最好的Web开发的 Python 框架
2015/03/18 Python
Win10下python 2.7.13 安装配置方法图文教程
2018/09/18 Python
Python学习笔记之pandas索引列、过滤、分组、求和功能示例
2019/06/03 Python
查看已安装tensorflow版本的方法示例
2020/04/19 Python
Python析构函数__del__定义原理解析
2020/11/20 Python
德国电子产品购物网站:TechInTheBasket德国
2018/12/07 全球购物
部门活动策划方案
2014/08/16 职场文书
党支部群众路线整改措施思想汇报
2014/10/10 职场文书
小学师德师风整改措施
2014/10/27 职场文书
2014年青年志愿者工作总结
2014/12/09 职场文书
工作简历自我评价
2015/03/11 职场文书
奖金申请报告模板
2015/05/15 职场文书