python支持多线程的爬虫实例


Posted in Python onDecember 21, 2019

python是支持多线程的, 主要是通过thread和threading这两个模块来实现的,本文主要给大家分享python实现多线程网页爬虫

一般来说,使用线程有两种模式, 一种是创建线程要执行的函数, 把这个函数传递进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基于pygame实现的弹力球效果(附源码)
Nov 11 Python
Python-嵌套列表list的全面解析
Jun 08 Python
Pycharm学习教程(1) 定制外观
May 02 Python
Python中的pygal安装和绘制直方图代码分享
Dec 08 Python
rabbitmq(中间消息代理)在python中的使用详解
Dec 14 Python
使用python绘制二元函数图像的实例
Feb 12 Python
Python3+Pycharm+PyQt5环境搭建步骤图文详解
May 29 Python
python conda操作方法
Sep 11 Python
基于pytorch的lstm参数使用详解
Jan 14 Python
python3 使用traceback定位异常实例
Mar 09 Python
自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码
Mar 30 Python
Python爬取阿拉丁统计信息过程图解
May 12 Python
Python 实现try重新执行
Dec 21 #Python
在python shell中运行python文件的实现
Dec 21 #Python
Python 脚本的三种执行方式小结
Dec 21 #Python
python带参数打包exe及调用方式
Dec 21 #Python
python脚本后台执行方式
Dec 21 #Python
Python模块的制作方法实例分析
Dec 21 #Python
基于Python 中函数的 收集参数 机制
Dec 21 #Python
You might like
php多任务程序实例解析
2014/07/19 PHP
PHP安装memcache扩展的步骤讲解
2019/02/14 PHP
javascript中的变量是传值还是传址的?
2010/04/19 Javascript
JQuery select标签操作代码段
2010/05/16 Javascript
javascript实现简单查找与替换的方法
2015/07/22 Javascript
jQuery使用$.ajax进行即时验证实例详解
2015/12/11 Javascript
学习javascript面向对象 理解javascript原型和原型链
2016/01/04 Javascript
详解用node.js实现简单的反向代理
2017/06/26 Javascript
解决npm安装Electron缓慢网络超时导致失败的问题
2018/02/06 Javascript
微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例
2019/03/30 Javascript
如何使用Node.js爬取任意网页资源并输出PDF文件到本地
2019/06/17 Javascript
vue 项目软键盘回车触发搜索事件
2020/09/09 Javascript
[01:29]2017 DOTA2国际邀请赛官方英雄手办展示
2017/03/18 DOTA
[46:58]完美世界DOTA2联赛PWL S3 Forest vs LBZS 第一场 12.17
2020/12/19 DOTA
在windows下快速搭建web.py开发框架方法
2016/04/22 Python
判断网页编码的方法python版
2016/08/12 Python
python 中if else 语句的作用及示例代码
2018/03/05 Python
使用pymysql查询数据库,把结果保存为列表并获取指定元素下标实例
2020/05/15 Python
pycharm 关掉syntax检查操作
2020/06/09 Python
美国领先的低折扣旅行网站:Hotwire
2019/01/19 全球购物
如何在.net Winform里面显示PDF文档
2012/09/11 面试题
什么是网络协议
2016/04/07 面试题
写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分隔
2015/07/30 面试题
总经理岗位职责
2013/11/09 职场文书
化验室技术员岗位职责
2013/12/24 职场文书
学校安全工作制度
2014/01/19 职场文书
不打扫卫生检讨书
2014/02/12 职场文书
文科生自我鉴定
2014/02/15 职场文书
财务总经理岗位职责
2014/02/16 职场文书
环保建议书作文
2014/03/12 职场文书
创建无烟单位实施方案
2014/03/29 职场文书
离婚协议书格式
2014/11/21 职场文书
2019通用版导游词范本!
2019/08/07 职场文书
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL
Python中第三方库Faker的使用详解
2022/04/02 Python