基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网络编程学习笔记(二):socket建立网络客户端
Jun 09 Python
Python多线程编程(五):死锁的形成
Apr 05 Python
Python实现对PPT文件进行截图操作的方法
Apr 28 Python
python 查找字符串是否存在实例详解
Jan 20 Python
Python计时相关操作详解【time,datetime】
May 26 Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
Jul 04 Python
python使用Plotly绘图工具绘制柱状图
Apr 01 Python
浅谈opencv自动光学检测、目标分割和检测(连通区域和findContours)
Jun 04 Python
numpy 矩阵形状调整:拉伸、变成一位数组的实例
Jun 18 Python
浅谈优化Django ORM中的性能问题
Jul 09 Python
tensorflow基于CNN实战mnist手写识别(小白必看)
Jul 20 Python
python 详解turtle画爱心代码
Feb 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
PHP模板引擎Smarty内建函数section,sectionelse用法详解
2016/04/11 PHP
几个比较经典常用的jQuery小技巧
2010/03/01 Javascript
基于jquery的滚动条滚动固定div(附演示下载)
2012/10/29 Javascript
js判断样式className同时增加class或删除class
2013/01/30 Javascript
jQuery 取值、赋值的基本方法整理
2014/03/31 Javascript
当滚动条滚动到页面底部自动加载增加内容的js代码
2014/05/13 Javascript
Jquery操作Ajax方法小结
2015/11/29 Javascript
BootStrap 智能表单实战系列(二)BootStrap支持的类型简介
2016/06/13 Javascript
解决Angular.Js与Django标签冲突的方案
2016/12/20 Javascript
详解webpack编译多页面vue项目的配置问题
2017/12/11 Javascript
Node.js利用console输出日志文件的方法示例
2018/04/27 Javascript
详解.vue文件中style标签的几个标识符
2018/07/17 Javascript
对Vue beforeRouteEnter 的next执行时机详解
2018/08/25 Javascript
在vue中动态添加class类进行显示隐藏实例
2019/11/09 Javascript
[06:16]《DAC最前线》之地区预选赛全面回顾
2015/01/19 DOTA
[02:16]完美世界DOTA2联赛PWL S3 集锦第三期
2020/12/21 DOTA
Python本地与全局命名空间用法实例
2015/06/16 Python
python3下实现搜狗AI API的代码示例
2018/04/10 Python
Django Web开发中django-debug-toolbar的配置以及使用
2018/05/06 Python
python 中字典嵌套列表的方法
2018/07/03 Python
Linux下python制作名片示例
2018/07/20 Python
在Python中调用Ping命令,批量IP的方法
2019/01/26 Python
python 字符串常用函数详解
2019/09/11 Python
详解Ubuntu环境下部署Django+uwsgi+nginx总结
2020/04/02 Python
python如何查看安装了的模块
2020/06/23 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
2021/01/15 Python
python爬虫如何解决图片验证码
2021/02/14 Python
JD Sports西班牙:英国领先的运动服装公司
2020/01/06 全球购物
中科软测试工程师面试题
2012/06/16 面试题
万年牢教学反思
2014/02/15 职场文书
《九色鹿》教学反思
2014/02/27 职场文书
求职简历自我评价范例
2014/03/12 职场文书
安全生产标语大全
2014/10/06 职场文书
运动会跳远广播稿
2015/08/19 职场文书
创业计划书之校园跑腿公司
2019/09/24 职场文书
Python中的tkinter库简单案例详解
2022/01/22 Python