基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 相关文章推荐
Tornado 多进程实现分析详解
Jan 12 Python
Django学习教程之静态文件的调用详解
May 08 Python
python实现比较文件内容异同
Jun 22 Python
朴素贝叶斯分类算法原理与Python实现与使用方法案例
Jun 26 Python
python opencv minAreaRect 生成最小外接矩形的方法
Jul 01 Python
Python 多个图同时在不同窗口显示的实现方法
Jul 07 Python
python matplotlib 画dataframe的时间序列图实例
Nov 20 Python
Python SSL证书验证问题解决方案
Jan 13 Python
python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例
Feb 28 Python
jenkins+python自动化测试持续集成教程
May 12 Python
Python tkinter界面实现历史天气查询的示例代码
Aug 23 Python
python包的导入方式总结
Mar 02 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的宝库目录--PEAR
2006/10/09 PHP
如何对PHP程序中的常见漏洞进行攻击(下)
2006/10/09 PHP
第二节--PHP5 的对象模型
2006/11/16 PHP
一周学会PHP(视频)Http下载
2006/12/12 PHP
php中将数组存到文件里的实现代码
2012/01/19 PHP
PHP Parse Error: syntax error, unexpected $end 错误的解决办法
2012/06/05 PHP
php采用curl访问域名返回405 method not allowed提示的解决方法
2014/06/26 PHP
PHP __call()方法实现委托示例
2019/05/20 PHP
php屏蔽错误及提示的方法
2020/05/10 PHP
JavaScript使用cookie
2007/02/02 Javascript
jquery.validate使用攻略 第一部
2010/07/01 Javascript
Javascript模块化编程(一)AMD规范(规范使用模块)
2013/01/17 Javascript
JavaScript中的字符串操作详解
2013/11/12 Javascript
jQuery+Ajax+PHP+Mysql实现分页显示数据实例讲解
2015/09/27 Javascript
js实现接收表单的值并将值拼在表单action后面的方法
2015/11/23 Javascript
Bootstrap字体图标无法正常显示的解决方法
2016/10/08 Javascript
js导出excel文件的简洁方法(推荐)
2016/11/02 Javascript
深究AngularJS中$sce的使用
2017/06/12 Javascript
React + webpack 环境配置的方法步骤
2017/09/07 Javascript
详解在Vue中有条件地使用CSS类
2017/09/30 Javascript
Vue2.0实现调用摄像头进行拍照功能 exif.js实现图片上传功能
2018/04/28 Javascript
Nodejs模块的调用操作实例分析
2018/12/25 NodeJs
javascript设计模式 ? 装饰模式原理与应用实例分析
2020/04/14 Javascript
[02:10]DOTA2 TI10勇士令状玩法及不朽Ⅰ展示:焕新世界,如你所期
2020/05/29 DOTA
Python cookbook(数据结构与算法)将序列分解为单独变量的方法
2018/02/13 Python
python 爬取学信网登录页面的例子
2019/08/13 Python
Python面向对象程序设计之私有变量,私有方法原理与用法分析
2020/03/23 Python
西班牙在线药店:DosFarma
2020/03/28 全球购物
UML设计模式笔试题
2014/06/07 面试题
老师给学生的表扬信
2014/01/17 职场文书
如何写自我鉴定
2014/03/19 职场文书
保护环境建议书400字
2014/05/13 职场文书
传承焦裕禄精神思想汇报2014
2014/09/10 职场文书
给医院的感谢信
2015/01/21 职场文书
学校世界艾滋病日宣传活动总结
2015/05/05 职场文书
mysql5.7使用binlog 恢复数据的方法
2021/06/03 MySQL