基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生成多个只含0,1元素的随机数组或列表的实例
Nov 12 Python
python去除拼音声调字母,替换为字母的方法
Nov 28 Python
python处理DICOM并计算三维模型体积
Feb 26 Python
详解pyppeteer(python版puppeteer)基本使用
Jun 12 Python
让Python脚本暂停执行的几种方法(小结)
Jul 11 Python
python可视化篇之流式数据监控的实现
Aug 07 Python
django 连接数据库 sqlite的例子
Aug 14 Python
python协程gevent案例 爬取斗鱼图片过程解析
Aug 27 Python
python实现高斯判别分析算法的例子
Dec 09 Python
浅析python表达式4+0.5值的数据类型
Feb 26 Python
python读取多层嵌套文件夹中的文件实例
Feb 27 Python
深入理解python协程
Jun 15 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
PHP5在Apache下的两种模式的安装
2006/09/05 PHP
php随机抽奖实例分析
2015/03/04 PHP
js继承的实现代码
2010/08/05 Javascript
JavaScript arguments 多参传值函数
2010/10/24 Javascript
主页面中的两个iframe实现鼠标拖动改变其大小
2013/04/16 Javascript
jQuery的one()方法用法实例
2015/01/19 Javascript
ajax读取数据后使用jqchart显示图表的方法
2015/06/10 Javascript
浅谈jquery点击label触发2次的问题
2016/06/12 Javascript
JavaScript实现动态增删表格的方法
2017/03/09 Javascript
JavaScript中this的用法及this在不同应用场景的作用解析
2017/04/13 Javascript
Vue中定义全局变量与常量的各种方式详解
2017/08/23 Javascript
vue router学习之动态路由和嵌套路由详解
2017/09/21 Javascript
javascript将json格式数组下载为excel表格的方法
2017/12/22 Javascript
Vue将页面导出为图片或者PDF
2020/08/17 Javascript
javascript+css实现俄罗斯方块小游戏
2020/06/28 Javascript
JavaScript中的函数式编程详解
2020/08/22 Javascript
Angular+Ionic使用queryParams实现跳转页传值的方法
2020/09/05 Javascript
[01:00:13]完美世界DOTA2联赛 LBZS vs Forest 第一场 11.07
2020/11/09 DOTA
Python中设置变量作为默认值时容易遇到的错误
2015/04/03 Python
Python使用multiprocessing实现一个最简单的分布式作业调度系统
2016/03/14 Python
详解字典树Trie结构及其Python代码实现
2016/06/03 Python
python下载图片实现方法(超简单)
2017/07/21 Python
Python实现的本地文件搜索功能示例【测试可用】
2018/05/30 Python
python3.6实现学生信息管理系统
2019/02/21 Python
Django如何实现防止XSS攻击
2020/10/13 Python
pytorch Dataset,DataLoader产生自定义的训练数据案例
2021/03/03 Python
2014年党员公开承诺践诺书
2014/03/25 职场文书
母亲节演讲稿
2014/05/27 职场文书
个性车贴标语
2014/06/24 职场文书
班主任经验交流材料
2014/12/16 职场文书
羊脂球读书笔记
2015/06/30 职场文书
小学英语教学反思范文
2016/02/15 职场文书
《蜜蜂引路》教学反思
2016/02/22 职场文书
人民币使用说明书
2019/04/17 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书
Nginx报404错误的详细解决方法
2022/07/23 Servers