基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的Twisted框架实现webshell密码扫描器的教程
Apr 16 Python
Python操作Word批量生成文章的方法
Jul 28 Python
Python 正则表达式的高级用法
Dec 04 Python
Python 3.x读写csv文件中数字的方法示例
Aug 29 Python
python爬虫系列Selenium定向爬取虎扑篮球图片详解
Nov 15 Python
python中urlparse模块介绍与使用示例
Nov 19 Python
解决csv.writer写入文件有多余的空行问题
Jul 06 Python
使用Python写一个量化股票提醒系统
Aug 22 Python
对Python的交互模式和直接运行.py文件的区别详解
Jun 29 Python
基于pytorch的保存和加载模型参数的方法
Aug 17 Python
基于Python绘制美观动态圆环图、饼图
Jun 03 Python
Python提取PDF指定内容并生成新文件
Jun 09 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
ThinkPHP3.1基础知识快速入门
2014/06/19 PHP
thinkphp中空模板与空模块的用法实例
2014/11/26 PHP
jQuery+PHP发布的内容进行无刷新分页(Fckeditor)
2015/10/22 PHP
PHP parse_ini_file函数的应用与扩展操作示例
2019/01/07 PHP
php和html的区别点详细总结
2019/09/24 PHP
JavaScript编程中容易出BUG的几点小知识
2015/01/31 Javascript
有趣的bootstrap走动进度条
2016/12/01 Javascript
解析预加载显示图片艺术
2016/12/05 Javascript
angular仿支付宝密码框输入效果
2017/03/25 Javascript
JavaScript阻止表单提交方法(附代码)
2017/08/15 Javascript
javascript 中模板方法单例的实现方法
2017/10/17 Javascript
echarts鼠标覆盖高亮显示节点及关系名称详解
2018/03/17 Javascript
详解小程序毫秒级倒计时(适用于拼团秒杀功能)
2019/05/05 Javascript
JavaScript实现PC端横向轮播图
2020/02/07 Javascript
实例解析Python设计模式编程之桥接模式的运用
2016/03/02 Python
详解Swift中属性的声明与作用
2016/06/30 Python
详解使用 pyenv 管理多个版本 python 环境
2017/10/19 Python
python networkx 包绘制复杂网络关系图的实现
2019/07/10 Python
python3下pygame如何实现显示中文
2020/01/11 Python
django 利用Q对象与F对象进行查询的实现
2020/05/15 Python
PyQt5实现登录页面
2020/05/30 Python
python3实现名片管理系统(控制台版)
2020/11/29 Python
HTML5 video 视频标签使用介绍
2014/02/03 HTML / CSS
美国校园市场:OCM
2017/06/08 全球购物
JD Sports马来西亚:英国领先的运动鞋和运动服饰零售商
2018/03/13 全球购物
 Alo Yoga官网:购买瑜伽服装
2018/06/17 全球购物
上海中网科技笔试题
2012/02/19 面试题
行政助理岗位职责
2013/11/10 职场文书
房地产广告词大全
2014/03/19 职场文书
2014年初三班主任工作总结
2014/12/05 职场文书
幼儿园教师读书笔记
2015/06/29 职场文书
浅谈Java实现分布式事务的三种方案
2021/06/11 Java/Android
postgresql使用filter进行多维度聚合的解决方法
2021/07/16 PostgreSQL
Python实现批量自动整理文件
2022/03/16 Python
mysql中DCL常用的用户和权限控制
2022/03/31 MySQL
tomcat下部署jenkins的方法
2022/05/06 Servers