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网络编程学习笔记(二):socket建立网络客户端
Jun 09 Python
Python提取Linux内核源代码的目录结构实现方法
Jun 24 Python
浅析Python中元祖、列表和字典的区别
Aug 17 Python
对python中xlsx,csv以及json文件的相互转化方法详解
Dec 25 Python
python远程调用rpc模块xmlrpclib的方法
Jan 11 Python
python学生管理系统开发
Jan 30 Python
详解PyCharm安装MicroPython插件的教程
Jun 24 Python
浅谈Python 敏感词过滤的实现
Aug 15 Python
postman传递当前时间戳实例详解
Sep 14 Python
Python使用enumerate获取迭代元素下标
Feb 03 Python
Python偏函数Partial function使用方法实例详解
Jun 17 Python
Python中os模块的简单使用及重命名操作
Apr 17 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程序中的常见漏洞进行攻击(下)
2006/10/09 PHP
聊天室php&amp;mysql(一)
2006/10/09 PHP
php去除换行符的方法小结(PHP_EOL变量的使用)
2013/02/16 PHP
php正则匹配文章中的远程图片地址并下载图片至本地
2015/09/29 PHP
PHP+MySQL实现在线测试答题实例
2020/01/02 PHP
jQuery 判断元素上是否绑定了事件
2009/10/28 Javascript
jquery的live使用注意事项
2014/02/18 Javascript
javascript实现页面刷新时自动清空表单并选中的方法
2015/07/18 Javascript
封装属于自己的JS组件
2016/01/27 Javascript
jQuery简单创建节点的方法
2016/09/09 Javascript
Node.js开启Https的实践详解
2016/10/25 Javascript
JS中传递参数的几种不同方法比较
2017/01/20 Javascript
AngularJS之页面跳转Route实例代码
2017/03/10 Javascript
详解vue.js全局组件和局部组件
2017/04/10 Javascript
浅谈vue-lazyload实现的详细过程
2017/08/22 Javascript
vue-resource拦截器设置头信息的实例
2017/10/27 Javascript
Webpack框架核心概念(知识点整理)
2017/12/22 Javascript
vuejs+element UI点击编辑表格某一行时获取内容填入表单的示例
2018/10/31 Javascript
微信小程序实现点击卡片 翻转效果
2019/09/04 Javascript
Python科学计算包numpy用法实例详解
2018/02/08 Python
python如何派生内置不可变类型并修改实例化行为
2018/03/21 Python
Django使用HttpResponse返回图片并显示的方法
2018/05/22 Python
django如何连接已存在数据的数据库
2018/08/14 Python
python配置grpc环境
2019/01/01 Python
Django 权限管理(permissions)与用户组(group)详解
2020/11/30 Python
python实现马丁策略回测3000只股票的实例代码
2021/01/22 Python
老师自我鉴定范文
2013/12/25 职场文书
创新比赛获奖感言
2014/02/13 职场文书
材料员岗位职责
2014/03/13 职场文书
幼儿园区域活动总结
2014/05/08 职场文书
根叔历年演讲稿
2014/05/20 职场文书
班级标语大全
2014/06/21 职场文书
民主生活会发言材料
2014/10/20 职场文书
关于分班的感言
2015/08/04 职场文书
如何写好活动总结
2019/06/21 职场文书
Python使用Kubernetes API访问集群
2021/05/30 Python