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  __getattr__与__setattr__使用方法
Sep 06 Python
Python实现的HTTP并发测试完整示例
Apr 23 Python
Python通过命令开启http.server服务器的方法
Nov 04 Python
python+matplotlib实现礼盒柱状图实例代码
Jan 16 Python
对numpy中向量式三目运算符详解
Oct 31 Python
python实现石头剪刀布小游戏
Jan 20 Python
树莓派实现移动拍照
Jun 22 Python
简单介绍python封装的基本知识
Aug 10 Python
python isinstance函数用法详解
Feb 13 Python
python 解决tqdm模块不能单行显示的问题
Feb 19 Python
python简单实现最大似然估计&amp;scipy库的使用详解
Apr 15 Python
Python中random模块常用方法的使用教程
Oct 04 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&amp;java(一)
2006/10/09 PHP
php引用传值实例详解学习
2013/11/06 PHP
CodeIgniter生成网站sitemap地图的方法
2013/11/13 PHP
php生成QRcode实例
2014/09/22 PHP
PHP简单实现解析xml为数组的方法
2018/05/02 PHP
PHP重载基础知识回顾
2020/09/10 PHP
PHP7 弃用功能
2021/03/09 PHP
CSS+Table图文混排中实现文本自适应图片宽度(超简单+跨所有浏览器)
2009/02/14 Javascript
jQuery中width()方法用法实例
2014/12/24 Javascript
浅析Jquery操作select
2016/12/13 Javascript
详解使用vue-admin-template的优化历程
2018/05/20 Javascript
JavaScript事件委托原理与用法实例分析
2018/06/07 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
2018/08/09 jQuery
JS字典Dictionary类定义与用法示例
2019/02/01 Javascript
vue渲染方式render和template的区别
2020/06/05 Javascript
Node.js API详解之 V8模块用法实例分析
2020/06/05 Javascript
[01:46]2020完美世界全国高校联赛秋季赛报名开启
2020/10/15 DOTA
opencv python 傅里叶变换的使用
2018/07/21 Python
Python处理时间日期坐标轴过程详解
2019/06/25 Python
Python脚本利用adb进行手机控制的方法
2019/07/08 Python
Django项目使用CircleCI的方法示例
2019/07/14 Python
python实现两个字典合并,两个list合并
2019/12/02 Python
pytorch 彩色图像转灰度图像实例
2020/01/13 Python
使用Python matplotlib作图时,设置横纵坐标轴数值以百分比(%)显示
2020/05/16 Python
如何在mac下配置python虚拟环境
2020/07/06 Python
详解HTML5中的标签
2015/06/19 HTML / CSS
谈一谈HTML5本地存储技术
2016/03/02 HTML / CSS
介绍一下Linux内核的排队自旋锁
2014/08/27 面试题
超市业务员岗位职责
2013/12/05 职场文书
化学学院毕业生自荐信范文
2013/12/17 职场文书
大学校园生活自我鉴定
2014/01/13 职场文书
致垒球运动员加油稿
2014/02/16 职场文书
党的群众路线教育实践活动剖析材料
2014/09/30 职场文书
正风肃纪剖析材料范文
2014/10/10 职场文书
2016秋季小学开学寄语
2015/12/03 职场文书
redis实现共同好友的思路详解
2021/05/26 Redis