python爬虫项目设置一个中断重连的程序的实现


Posted in Python onJuly 26, 2019

做爬虫项目时,我们需要考虑一个爬虫在爬取时会遇到各种情况(网站验证,ip封禁),导致爬虫程序中断,这时我们已经爬取过一些数据,再次爬取时这些数据就可以忽略,所以我们需要在爬虫项目中设置一个中断重连的功能,使其在重新运行时从之前断掉的位置重新爬取数据。

实现该功能有很多种做法,我自己就有好几种思路,但是真要自己写出来就要费很大的功夫,下面我就把自己好不容易拼凑出来的代码展示出来吧。

首先是来介绍代码的思路:

将要爬取的网站连接存在一个数组new_urls中,爬取一个网址就将它移入另一个数组old_urls中,爬取网站时,就看它是在哪一个数组中,然后再决定要不要爬取。

下面展示代码(从别处抄的):

class UrlManager(object):
  def __init__(self):  #定义两个数组
    self.new_urls=set()
    self.old_urls=set()

  def add_new_url(self, url): #将一个url加入到new_urls数组中
    if url is None:
      return
    if url not in self.new_urls and url not in self.old_urls:
      self.new_urls.add(url)

  def add_new_urls(self, urls): #将多个url加入到new_urls数组中
    if urls is None or len(urls)==0:
      return
    for url in urls :
      self.add_new_url(url)

  def has_new_url(self):  #判断url是否为空
    return len(self.new_urls)!=0

  def get_new_url(self):
    #list.pop()默认移除列表中最后一个元素对象
    new_url=self.new_urls.pop()
    self.old_urls.add(new_url)
    return new_url

这个类实现了中断重连的基本功能,但是当我们要爬取的网址非常的,那这就对我们电脑的内存要求非常大,所以我们要将数组保存到文档中,增加一个从文档中提取网址的过程。

下面看代码:

class UrlManager(object):
  def __init__(self):   #建立两个数组的文件
    with open('new_urls.txt','r+') as new_urls:
      self.new_urls = new_urls.read()
    with open('old_urls.txt','r+') as old_urls:
      self.old_urls = old_urls.read()

  def add_new_url(self, url):   #添加url到new_ulrs文件中
    if url is None:
      return
    if url not in self.new_urls and url not in self.old_urls:
      with open('new_urls.txt', 'a') as new_urls:
        new_urls.write(url)
    else:
      print('url had done')

  def add_new_urls(self, urls):  #添加多个url到new_ulrs文件中
    # if urls is None or (len(url) == 0 for url in urls):
    if urls is None:
      print('url is none')
      return
    for url in urls:
      if urls is None:
        print('url is none')
        return
      else:
        self.add_new_url(url)

  def has_new_url(self):
    return len(self.new_urls) != 0

  def get_new_url(self):  
    new_url = get_last_line('new_urls.txt')  #读取new_urls文件中最后一个url
    del_last_url('new_urls.txt',new_url) #删除new_urls文件中最后一个url
    add_old_urls('old_urls.txt',new_url) #将读取出来的url添加入old_urls数组中
    return new_url

其中的get_last_line()函数有些复杂,这也是我卡时间最长的一块,

import os
def get_last_line(inputfile):
  filesize = os.path.getsize(inputfile)
  blocksize = 1024
  dat_file = open(inputfile, 'rb')

  last_line = b""
  lines = []
  if filesize > blocksize:
    maxseekpoint = (filesize // blocksize) # 这里的除法取的是floor
    maxseekpoint -= 1
    dat_file.seek(maxseekpoint * blocksize)
    lines = dat_file.readlines()
    while ((len(lines) < 2) | ((len(lines) >= 2) & (lines[1] == b'\r\n'))): # 因为在Windows下,所以是b'\r\n'
      # 如果列表长度小于2,或者虽然长度大于等于2,但第二个元素却还是空行
      # 如果跳出循环,那么lines长度大于等于2,且第二个元素肯定是完整的行
      maxseekpoint -= 1
      dat_file.seek(maxseekpoint * blocksize)
      lines = dat_file.readlines()
  elif filesize: # 文件大小不为空
    dat_file.seek(0, 0)
    lines = dat_file.readlines()
  if lines: # 列表不为空
    for i in range(len(lines) - 1, -1, -1):
      last_line = lines[i].strip()
      if (last_line != b''):
        break # 已经找到最后一个不是空行的
  dat_file.close()
  return last_line

def del_last_url(fname,part):
  with open(fname,'rb+') as f:
    a = f.read()
  a = a.replace(part,b'')
  with open(fname,'wb+') as f:
    f.write(a)
    
def add_old_urls(fname,new_url):
  line = new_url + b'\r'
  with open(fname,'ab') as f:
    f.write(line)

好了,爬虫的中断重连的功能就实现了,下面要做的就是将该功能接入爬虫项目中,比较简单。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python重试装饰器示例
Feb 11 Python
介绍Python的Django框架中的QuerySets
Apr 20 Python
Python中的filter()函数的用法
Apr 27 Python
Python2.x版本中基本的中文编码问题解决
Oct 12 Python
Python中矩阵库Numpy基本操作详解
Nov 21 Python
Python实现按中文排序的方法示例
Apr 25 Python
使用pandas实现csv/excel sheet互相转换的方法
Dec 10 Python
Python及Pycharm安装方法图文教程
Aug 05 Python
Matplotlib绘制雷达图和三维图的示例代码
Jan 07 Python
使用Python-OpenCV消除图像中孤立的小区域操作
Jul 05 Python
Python自省及反射原理实例详解
Jul 06 Python
Python urllib3软件包的使用说明
Nov 18 Python
python通过http下载文件的方法详解
Jul 26 #Python
快速解决vue.js 模板和jinja 模板冲突的问题
Jul 26 #Python
Python调用C语言的实现
Jul 26 #Python
Python实现的企业粉丝抽奖功能示例
Jul 26 #Python
对Django外键关系的描述
Jul 26 #Python
python绘图模块matplotlib示例详解
Jul 26 #Python
详解Python中正则匹配TAB及空格的小技巧
Jul 26 #Python
You might like
zf框架的数据库追踪器使用示例
2014/03/13 PHP
php实现数组筛选奇数和偶数示例
2014/04/11 PHP
yii分页组件用法实例分析
2015/12/28 PHP
PHP yield关键字功能与用法分析
2019/01/03 PHP
PHP中引用类型和值类型功能与用法示例
2019/02/26 PHP
PHP实现限制域名访问的实现代码(本地验证)
2020/09/13 PHP
Jquery 基础学习笔记
2009/05/29 Javascript
JQUERY对单选框(radio)操作的小例子
2013/04/25 Javascript
jquery获取被勾选的checked(选中)的那一行的3列和4列的值
2013/07/04 Javascript
jQuery 三击事件实现代码
2013/09/11 Javascript
jquery validate在ie8下的bug解决方法
2013/11/13 Javascript
js生成缩略图后上传并利用canvas重绘
2014/05/15 Javascript
JS闭包、作用域链、垃圾回收、内存泄露相关知识小结
2016/05/16 Javascript
javascript浏览器用户代理检测脚本实现方法
2017/10/27 Javascript
bootstrap treeview 树形菜单带复选框及级联选择功能
2018/06/08 Javascript
详解vue.js下引入百度地图jsApi的两种方法
2018/07/27 Javascript
vue实现文件上传读取及下载功能
2020/11/17 Javascript
微信小程序实现分享商品海报功能
2019/09/30 Javascript
vue-cli3自动消除console.log()的调试信息方式
2020/10/21 Javascript
javascript中闭包closure的深入讲解
2021/03/03 Javascript
Python实现自动发送邮件功能
2021/03/02 Python
python批量图片处理简单示例
2019/08/06 Python
python 变量初始化空列表的例子
2019/11/28 Python
Python2及Python3如何实现兼容切换
2020/09/01 Python
CSS3 透明色 RGBA使用介绍
2013/08/06 HTML / CSS
h5封装下拉刷新
2020/08/25 HTML / CSS
End Clothing美国站:英国男士潮牌商城
2018/04/20 全球购物
Michael Kors英国官网:美国奢侈品品牌
2019/11/13 全球购物
The Athlete’s Foot新西兰:新西兰最大的运动鞋零售商
2019/12/23 全球购物
个人自我鉴定怎么写
2013/10/28 职场文书
销售副总经理岗位职责
2013/12/11 职场文书
软件专业毕业生个人自我鉴定
2014/04/17 职场文书
党员对十八届四中全会的期盼思想汇报范文
2014/10/17 职场文书
2015年库房管理工作总结
2015/10/14 职场文书
2016年党员承诺书范文
2016/03/24 职场文书
Java8 CompletableFuture 异步回调
2022/04/28 Java/Android