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中input和raw_input的一点区别
Oct 21 Python
Python isinstance函数介绍
Apr 14 Python
python使用xlrd实现检索excel中某列含有指定字符串记录的方法
May 09 Python
简单谈谈Python流程控制语句
Dec 04 Python
python日志记录模块实例及改进
Feb 12 Python
python 上下文管理器使用方法小结
Oct 10 Python
python logging日志模块原理及操作解析
Oct 12 Python
详解python opencv、scikit-image和PIL图像处理库比较
Dec 26 Python
django修改models重建数据库的操作
Mar 31 Python
python下载的库包存放路径
Jul 27 Python
python pip如何手动安装二进制包
Sep 30 Python
Python3.9.1中使用split()的处理方法(推荐)
Feb 07 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
PHP中实现crontab代码分享
2015/03/26 PHP
PHP中应该避免使用同名变量(拆分临时变量)
2015/04/03 PHP
php支持断点续传、分块下载的类
2016/05/02 PHP
php简单读取.vcf格式文件的方法示例
2017/09/02 PHP
php求斐波那契数的两种实现方式【递归与递推】
2019/09/09 PHP
解决jquery操作checkbox火狐下第二次无法勾选问题
2014/02/10 Javascript
jquery easyui中treegrid用法的简单实例
2014/02/18 Javascript
推荐25个超炫的jQuery网格插件
2014/11/28 Javascript
Bootstrap学习笔记之js组件(4)
2016/06/12 Javascript
关于jQuery EasyUI 中刷新Tab选项卡后一个页面变形的解决方法
2017/03/02 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
2017/03/30 Javascript
webpack4 处理CSS的方法示例
2018/09/03 Javascript
Vue项目总结之webpack常规打包优化方案
2019/06/06 Javascript
Vue配置marked链接添加target=&quot;_blank&quot;的方法
2019/07/19 Javascript
jquery制作的移动端购物车效果完整示例
2020/02/24 jQuery
用Python的Django框架编写从Google Adsense中获得报表的应用
2015/04/17 Python
Python中列表和元组的相关语句和方法讲解
2015/08/20 Python
Python pygorithm模块用法示例【常见算法测试】
2018/08/16 Python
python实现梯度下降算法
2020/03/24 Python
Python3实现获取图片文字里中文的方法分析
2018/12/13 Python
新年快乐! python实现绚烂的烟花绽放效果
2019/01/30 Python
python中时间模块的基本使用教程
2019/05/14 Python
Python学习笔记之Django创建第一个数据库模型的方法
2019/08/07 Python
Python Django模板之模板过滤器与自定义模板过滤器示例
2019/10/18 Python
Python使用type动态创建类操作示例
2020/02/29 Python
python3注册全局热键的实现
2020/03/22 Python
世界上最伟大的马产品:Equiderma
2020/01/07 全球购物
大学本科生的个人自我评价
2013/12/09 职场文书
电钳专业个人求职信
2014/01/04 职场文书
共青团员自我评价范文
2014/09/14 职场文书
运动会稿件100字
2014/09/24 职场文书
教师自我剖析材料
2014/09/29 职场文书
应急管理工作总结2015
2015/05/04 职场文书
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
2021/05/05 Golang
JavaScript 数组去重详解
2021/09/15 Javascript
UNION CREATIVE《Re:从零开始的异世界生活》雷姆手办
2022/03/20 日漫