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使用wmi模块获取windows下硬盘信息的方法
May 15 Python
详解Python中for循环是如何工作的
Jun 30 Python
python实现简易云音乐播放器
Jan 04 Python
python实现windows下文件备份脚本
May 27 Python
Python Series从0开始索引的方法
Nov 06 Python
深入浅析python 协程与go协程的区别
May 09 Python
使用python爬取抖音视频列表信息
Jul 15 Python
python3.x提取中文的正则表达式示例代码
Jul 23 Python
使用python接受tgam的脑波数据实例
Apr 09 Python
python利用Excel读取和存储测试数据完成接口自动化教程
Apr 30 Python
Python 开发工具通过 agent 代理使用的方法
Sep 27 Python
pandas中关于apply+lambda的应用
Feb 28 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提交表单时判断 if($_POST[submit])与 if(isset($_POST[submit])) 的区别
2011/02/08 PHP
CodeIgniter针对lighttpd服务器URL重写的方法
2015/06/10 PHP
PHP ADODB实现分页功能简单示例
2018/05/25 PHP
PHP5.6读写excel表格文件操作示例
2019/02/26 PHP
accesskey 提交
2006/06/26 Javascript
JavaScript 获取当前时间戳的代码
2010/08/05 Javascript
一些实用的jQuery代码片段收集
2011/07/12 Javascript
ExtJS DOM元素操作经验分享
2013/08/28 Javascript
javascript设置金额样式转换保留两位小数示例代码
2013/12/04 Javascript
js模拟C#中List的简单实例
2014/03/06 Javascript
javascript中eval和with用法实例总结
2015/11/30 Javascript
AngularJS整合Springmvc、Spring、Mybatis搭建开发环境
2016/02/25 Javascript
Node.js的npm包管理器基础使用教程
2016/05/26 Javascript
seajs模块之间依赖的加载以及模块的执行
2016/10/21 Javascript
Vue2.0使用过程常见的一些问题总结学习
2017/04/10 Javascript
VUE实现一个分页组件的示例
2017/09/13 Javascript
jsonp跨域获取数据的基础教程
2018/07/01 Javascript
JavaScript指定断点操作实例教程
2018/09/18 Javascript
详解原生JS回到顶部
2019/03/25 Javascript
浅谈Vue.js 关于页面加载完成后执行一个方法的问题
2019/04/01 Javascript
深入解析koa之异步回调处理
2019/06/17 Javascript
详解基于原生JS验证表单组件xy-form
2019/08/20 Javascript
Python自动化开发学习之三级菜单制作
2017/07/14 Python
Python中if elif else及缩进的使用简述
2018/05/31 Python
Python如何实现转换URL详解
2019/07/02 Python
matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)
2019/08/06 Python
python数据处理之如何选取csv文件中某几行的数据
2019/09/02 Python
Pycharm最新激活码2019(推荐)
2019/12/31 Python
英国电气世界:Electrical World
2019/09/08 全球购物
.net面试题
2016/09/17 面试题
九一八事变纪念日演讲稿
2014/09/14 职场文书
2014年保洁员工作总结
2014/11/19 职场文书
涪陵白鹤梁导游词
2015/02/09 职场文书
手术室消毒隔离制度
2015/08/05 职场文书
2016年小学“公民道德宣传日”活动总结
2016/04/01 职场文书
Redis 哨兵机制及配置实现
2022/03/25 Redis