基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 相关文章推荐
web.py中调用文件夹内模板的方法
Aug 26 Python
Python文件和目录操作详解
Feb 08 Python
在Python中使用M2Crypto模块实现AES加密的教程
Apr 08 Python
python实现按行切分文本文件的方法
Apr 18 Python
Python 使用PIL numpy 实现拼接图片的示例
May 08 Python
pycharm的console输入实现换行的方法
Jan 16 Python
Python中断多重循环的思路总结
Oct 04 Python
Python爬虫使用代理IP的实现
Oct 27 Python
tensorflow安装成功import tensorflow 出现问题
Apr 16 Python
详解Python 函数参数的拆解
Sep 02 Python
python3.8动态人脸识别的实现示例
Sep 21 Python
matplotlib之多边形选区(PolygonSelector)的使用
Feb 24 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 cookis创建实现代码
2009/03/16 PHP
php中autoload的用法总结
2013/11/08 PHP
php格式化日期和时间格式化示例分享
2014/02/24 PHP
PHP模板引擎Smarty内建函数foreach,foreachelse用法分析
2016/04/11 PHP
jquery 插件 任意位置浮动固定层
2008/12/25 Javascript
jQuery 性能优化指南 (1)
2009/05/21 Javascript
JQuery里选择超链接的实现代码
2011/05/22 Javascript
详解AngularJS中自定义过滤器
2015/12/28 Javascript
AngularJs  unit-testing(单元测试)详解
2016/09/02 Javascript
用js制作淘宝放大镜效果
2020/10/28 Javascript
nodejs批量下载图片的实现方法
2017/05/19 NodeJs
Angular2仿照微信UI实现9张图片上传和预览的示例代码
2017/10/19 Javascript
jquery手机触屏滑动拼音字母城市选择器的实例代码
2017/12/11 jQuery
KOA+egg.js集成kafka消息队列的示例
2018/11/09 Javascript
基于JavaScript canvas绘制贝塞尔曲线
2018/12/25 Javascript
vue ssr 实现方式(学习笔记)
2019/01/18 Javascript
浅谈layui数据表格判断问题(加入表单元素),设置单元格样式
2019/10/26 Javascript
vue+animation实现翻页动画
2020/06/29 Javascript
jQuery实现简单评论功能
2020/08/19 jQuery
js实现磁性吸附的示例
2020/10/26 Javascript
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
[32:39]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第一场 11.04
2020/11/04 DOTA
用Python制作简单的钢琴程序的教程
2015/04/01 Python
python+pillow绘制矩阵盖尔圆简单实例
2018/01/16 Python
python使用socket实现的传输demo示例【基于TCP协议】
2019/09/24 Python
感知器基础原理及python实现过程详解
2019/09/30 Python
Tensorflow 多线程设置方式
2020/02/06 Python
Python常见反爬虫机制解决方案
2020/06/01 Python
Python tkinter实现日期选择器
2021/02/22 Python
维氏瑞士军刀英国网站:Victorinox英国
2019/07/04 全球购物
CSMA/CD介质访问控制协议
2015/11/17 面试题
企业理念标语
2014/06/09 职场文书
开展批评与自我批评发言稿
2014/10/16 职场文书
电工实训报告总结
2014/11/05 职场文书
2014年护士个人工作总结
2014/11/11 职场文书
2016年教师反腐倡廉心得体会
2016/01/13 职场文书