基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轻松实现代码编码格式转换
Mar 26 Python
Python函数式编程指南(三):迭代器详解
Jun 24 Python
用Python实现随机森林算法的示例
Aug 24 Python
Python3.x爬虫下载网页图片的实例讲解
May 22 Python
Python使用logging模块实现打印log到指定文件的方法
Sep 05 Python
python2 与 pyhton3的输入语句写法小结
Sep 10 Python
如何利用Python模拟GitHub登录详解
Jul 15 Python
Django admin model 汉化显示文字的实现方法
Aug 12 Python
pygame编写音乐播放器的实现代码示例
Nov 19 Python
Python如何使用内置库matplotlib绘制折线图
Feb 24 Python
python进行二次方程式计算的实例讲解
Dec 06 Python
Python编解码问题及文本文件处理方法详解
Jun 20 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
mysql 全文搜索 技巧
2007/04/27 PHP
php 数组二分法查找函数代码
2010/02/16 PHP
深入解析PHP 5.3.x 的strtotime() 时区设定 警告信息修复
2013/08/05 PHP
PHP SFTP实现上传下载功能
2017/07/26 PHP
在textarea文本域中显示HTML代码的方法
2007/03/06 Javascript
jquery 图片截取工具jquery.imagecropper.js
2010/04/09 Javascript
使用jquery实现IE下按backspace相当于返回操作
2014/03/18 Javascript
jQuery 顶部导航跟随滚动条滚动固定浮动在顶部
2014/06/06 Javascript
express的中间件cookieParser详解
2014/12/04 Javascript
JavaScript中的对象与JSON
2015/07/03 Javascript
Node.js实用代码段之正确拼接Buffer
2016/03/17 Javascript
indexedDB bootstrap angularjs之 MVC DOMO (应用示例)
2016/06/20 Javascript
JS正则表达式之非捕获分组用法实例分析
2016/12/28 Javascript
详谈DOM简介及节点、属性、查找节点的方法
2017/11/16 Javascript
React实现全局组件的Toast轻提示效果
2018/09/21 Javascript
JS实现倒序输出的几种常用方法示例
2019/04/13 Javascript
Vuejs通过拖动改变元素宽度实现自适应
2020/09/02 Javascript
利用Vue实现简易播放器的完整代码
2020/12/30 Vue.js
vue实现防抖的实例代码
2021/01/11 Vue.js
Vue实现摇一摇功能(兼容ios13.3以上)
2021/01/26 Vue.js
[00:43]魔廷新尊——痛苦女王至宝捆绑包
2020/06/12 DOTA
python判断字符串是否是json格式方法分享
2017/11/07 Python
对python dataframe逻辑取值的方法详解
2019/01/30 Python
python3.5安装python3-tk详解
2019/04/26 Python
详解Python绘图Turtle库
2019/10/12 Python
使用sklearn的cross_val_score进行交叉验证实例
2020/02/28 Python
css3 响应式媒体查询的示例代码
2019/09/25 HTML / CSS
工厂会计员职责
2014/02/06 职场文书
《天游峰的扫路人》教学反思
2014/04/25 职场文书
2014年母亲节寄语
2014/05/07 职场文书
住宅使用说明书
2014/05/09 职场文书
党的群众路线教育实践活动个人对照检查剖析材料
2014/09/23 职场文书
2015年全国“爱牙日”宣传活动总结
2015/03/23 职场文书
2015年学校教育教学工作总结
2015/04/22 职场文书
分享:关于学习的励志名言赏析
2019/08/16 职场文书
ant design vue的form表单取值方法
2022/06/01 Vue.js