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的id()函数解密过程
Dec 25 Python
python基于mysql实现的简单队列以及跨进程锁实例详解
Jul 07 Python
Python3.2中的字符串函数学习总结
Apr 23 Python
Python中with及contextlib的用法详解
Jun 08 Python
Python SqlAlchemy动态添加数据表字段实例解析
Feb 07 Python
python 求1-100之间的奇数或者偶数之和的实例
Jun 11 Python
在pycharm中显示python画的图方法
Aug 31 Python
Python通过fnmatch模块实现文件名匹配
Sep 30 Python
基于python爬取链家二手房信息代码示例
Oct 21 Python
Python利用imshow制作自定义渐变填充柱状图(colorbar)
Dec 10 Python
利用Python如何画一颗心、小人发射爱心
Feb 21 Python
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
May 31 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分页显示制作详细讲解
2008/11/19 PHP
php中global和$GLOBALS[]的分析之一
2012/02/02 PHP
PHP多文件上传实例
2015/07/09 PHP
Aster vs KG BO3 第三场2.18
2021/03/10 DOTA
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
看了就知道什么是JSON
2007/12/09 Javascript
JavaScript eval() 函数介绍及应用示例
2014/07/29 Javascript
js中日期的加减法
2015/05/06 Javascript
jQuery中animate动画第二次点击事件没反应
2015/05/07 Javascript
jquery实现多条件筛选特效代码分享
2015/08/28 Javascript
Jquery on绑定的事件 触发多次实例代码
2016/12/08 Javascript
详解JS数值Number类型
2018/02/07 Javascript
JavaScript数据结构与算法之基本排序算法定义与效率比较【冒泡、选择、插入排序】
2019/02/21 Javascript
基于iview-admin实现动态路由的示例代码
2019/10/02 Javascript
微信小程序实现星级评价
2019/11/20 Javascript
Vue 3.0 全家桶抢先体验
2020/04/28 Javascript
详细探究Python中的字典容器
2015/04/14 Python
使用Python实现博客上进行自动翻页
2017/08/23 Python
Python基于Flask框架配置依赖包信息的项目迁移部署
2018/03/02 Python
使用NumPy和pandas对CSV文件进行写操作的实例
2018/06/14 Python
详解分布式任务队列Celery使用说明
2018/11/29 Python
Python通用循环的构造方法实例分析
2018/12/19 Python
python读取文件名并改名字的实例
2019/01/07 Python
Numpy之random函数使用学习
2019/01/29 Python
python 上下文管理器及自定义原理解析
2019/11/19 Python
Python脚本实现Zabbix多行日志监控过程解析
2020/08/26 Python
StubHub墨西哥:购买和出售您的门票
2016/09/17 全球购物
世界领先的艺术图书出版社:TASCHEN
2018/07/23 全球购物
维多利亚的秘密官方网站:Victoria’s Secret
2018/10/24 全球购物
PyQt 如何创建自定义QWidget
2021/03/24 Python
综合测评自我鉴定
2013/10/08 职场文书
写自荐信有哪些不宜?
2013/10/17 职场文书
学校先进集体事迹材料
2014/05/31 职场文书
安全施工标语
2014/06/07 职场文书
甘南现象心得体会
2014/09/11 职场文书
SpringBoot2零基础到精通之异常处理与web原生组件注入
2022/03/22 Java/Android