基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之wxPython应用实例
Sep 28 Python
编写Python脚本使得web页面上的代码高亮显示
Apr 24 Python
python中urllib.unquote乱码的原因与解决方法
Apr 24 Python
Python实现删除时保留特定文件夹和文件的示例
Apr 27 Python
使用Python实现将list中的每一项的首字母大写
Jun 11 Python
Python绘图实现显示中文
Dec 04 Python
python base64库给用户名或密码加密的流程
Jan 02 Python
python集合能干吗
Jul 19 Python
python 中[0]*2与0*2的区别说明
May 10 Python
如何使用Python实现一个简易的ORM模型
May 12 Python
解决pytorch读取自制数据集出现过的问题
May 31 Python
教你怎么用Python实现GIF动图的提取及合成
Jun 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开发中的中文编码问题
2013/08/08 PHP
JS 控制非法字符的输入代码
2009/12/04 Javascript
通过判断JavaScript的版本实现执行不同的代码
2010/05/11 Javascript
js对象数组按属性快速排序
2011/01/31 Javascript
使用javascript实现有效时间的控制,并显示将要过期的时间
2014/01/02 Javascript
JavaScript+CSS控制打印格式示例介绍
2014/01/07 Javascript
jQuery中removeData()方法用法实例
2014/12/27 Javascript
详解js中构造流程图的核心技术JsPlumb
2015/12/08 Javascript
jQuery+css3实现转动的正方形效果(附demo源码下载)
2016/01/27 Javascript
jQuery ajax的功能实现方法详解
2017/01/06 Javascript
JS 实现计算器详解及实例代码(一)
2017/01/08 Javascript
深入浅析Node.js单线程模型
2017/07/10 Javascript
react-redux中connect的装饰器用法@connect详解
2018/01/13 Javascript
详解react-redux插件入门
2018/04/19 Javascript
详解element-ui日期时间选择器的日期格式化问题
2019/04/08 Javascript
深入解析koa之中间件流程控制
2019/06/17 Javascript
VUE子组件向父组件传值详解(含传多值及添加额外参数场景)
2020/09/01 Javascript
[47:35]VP vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/20 DOTA
详解tensorflow训练自己的数据集实现CNN图像分类
2018/02/07 Python
python 统计数组中元素出现次数并进行排序的实例
2018/07/02 Python
pycharm 取消默认的右击运行unittest的方法
2018/11/29 Python
Django restframework 源码分析之认证详解
2019/02/22 Python
Pytorch通过保存为ONNX模型转TensorRT5的实现
2020/05/25 Python
匡威帆布鞋美国官网:Converse美国
2016/08/22 全球购物
世界领先的在线地板和建筑材料批发商:BuildDirect
2017/02/26 全球购物
印度网上药店:1mg
2017/10/13 全球购物
生物化工工艺专业应届生求职信
2013/10/08 职场文书
心理健康教育制度
2014/01/27 职场文书
运动会稿件50字
2014/02/17 职场文书
优秀党支部申报材料
2014/12/24 职场文书
开平碉楼导游词
2015/02/06 职场文书
单方投资意向书
2015/05/11 职场文书
三好学生竞选稿
2015/11/21 职场文书
二手手机买卖合同范本(2019年版)
2019/10/28 职场文书
Python django中如何使用restful框架
2021/06/23 Python
总结Pyinstaller打包的高级用法
2021/06/28 Python