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 自动安装 Rising 杀毒软件
Apr 24 Python
python控制台显示时钟的示例
Feb 24 Python
Win7上搭建Cocos2d-x 3.1.1开发环境
Jul 03 Python
Django中使用group_by的方法
May 26 Python
Win10下Python环境搭建与配置教程
Nov 18 Python
python 分离文件名和路径以及分离文件名和后缀的方法
Oct 21 Python
详解如何在cmd命令窗口中搭建简单的python开发环境
Aug 29 Python
原来我一直安装 Python 库的姿势都不对呀
Nov 11 Python
tensorboard实现同时显示训练曲线和测试曲线
Jan 21 Python
Python 实现使用空值进行赋值 None
Mar 12 Python
Python pip使用超时问题解决方案
Aug 03 Python
Django DRF APIView源码运行流程详解
Aug 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
关于PHPDocument 代码注释规范的总结
2013/06/25 PHP
PHP获取php,mysql,apche的版本信息示例代码
2014/01/16 PHP
php-fpm服务启动脚本的方法
2018/04/27 PHP
Ubuntu彻底删除PHP7.0的方法
2018/07/27 PHP
DIY jquery plugin - tabs标签切换实现代码
2010/12/11 Javascript
关于Mozilla浏览器不支持innerText的解决办法
2011/01/01 Javascript
jquery聚焦文本框与扩展文本框聚焦方法
2012/10/12 Javascript
jQuery contains过滤器实现精确匹配使用方法
2013/04/12 Javascript
jQuery动态地获取系统时间实现代码
2013/05/24 Javascript
JavaScript function 的 length 属性使用介绍
2014/09/15 Javascript
jQuery实现图片上传和裁剪插件Croppie
2015/11/29 Javascript
jQuery ajax时间差导致的变量赋值问题分析
2016/01/22 Javascript
Bootstrap创建可折叠的组件
2016/02/23 Javascript
JS递归遍历对象获得Value值方法技巧
2016/06/14 Javascript
JavaScript中省略元素对数组长度的影响
2016/10/26 Javascript
jQuery实现弹窗居中效果类似alert()
2017/02/27 Javascript
jQuery选择器之子元素过滤选择器
2017/09/28 jQuery
vue2 mint-ui loadmore实现下拉刷新,上拉更多功能
2018/03/21 Javascript
React Router v4 入坑指南(小结)
2018/04/08 Javascript
es6 symbol的实现方法示例
2019/04/02 Javascript
vue实现前台列表数据过滤搜索、分页效果
2019/05/28 Javascript
Javascript数组方法reduce的妙用之处分享
2019/06/10 Javascript
你不可不知的Vue.js列表渲染详解
2019/10/01 Javascript
[04:29]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/02/01 DOTA
windows下安装python paramiko模块的代码
2013/02/10 Python
在Python的Flask框架中实现单元测试的教程
2015/04/20 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
Python对列表中的各项进行关联详解
2017/08/15 Python
python的pytest框架之命令行参数详解(上)
2019/06/27 Python
Python实现不规则图形填充的思路
2020/02/02 Python
Django values()和value_list()的使用
2020/03/31 Python
墨尔本照明批发商店:Mica Lighting
2017/12/28 全球购物
德国传统玻璃制造商:Cristalica
2018/04/23 全球购物
美国最好的钓鱼、狩猎和划船装备商店:Bass Pro Shops
2018/12/02 全球购物
StubHub希腊:购买体育赛事、音乐会和剧院门票
2019/08/03 全球购物
商务英语毕业生自荐信范文
2013/11/08 职场文书