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语言的优雅之处
Jul 04 Python
python进阶教程之函数对象(函数也是对象)
Aug 30 Python
Python线程的两种编程方式
Apr 14 Python
Python中使用装饰器时需要注意的一些问题
May 11 Python
python 日期操作类代码
May 05 Python
python实现大转盘抽奖效果
Jan 22 Python
Python实现FM算法解析
Jun 18 Python
Python使用微信接入图灵机器人过程解析
Nov 04 Python
python判断两个序列的成员是否一样的实例代码
Mar 01 Python
基于django micro搭建网站实现加水印功能
May 22 Python
python切割图片的示例
Nov 12 Python
python_tkinter弹出对话框创建
Mar 20 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 操作数组(合并,拆分,追加,查找,删除等)
2012/07/20 PHP
php数组分页实现方法
2016/04/30 PHP
php处理单文件、多文件上传代码分享
2016/08/24 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
2019/07/24 PHP
thinkPHP5.1框架使用SemanticUI实现分页功能示例
2019/08/03 PHP
获取客户端网卡MAC地址和IP地址实现JS代码
2013/03/17 Javascript
html+js实现动态显示本地时间
2013/09/21 Javascript
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
jquery实现下拉菜单的二级联动利用json对象从DB取值显示联动
2014/03/27 Javascript
jquery调取json数据实现省市级联的方法
2015/01/29 Javascript
js实现鼠标触发图片抖动效果的方法
2015/02/27 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
2015/03/23 Javascript
JavaScript获取对象在页面中位置坐标的方法
2016/02/03 Javascript
angularjs 源码解析之injector
2016/08/22 Javascript
JS实现自动阅读单词(有道单词本添加功能)
2016/11/14 Javascript
详解JavaScript中this的指向问题
2017/01/20 Javascript
详解小程序输入框闪烁及重影BUG解决方案
2018/08/31 Javascript
通过实例了解Javascript柯里化流程
2020/03/03 Javascript
vue瀑布流组件实现上拉加载更多
2020/03/10 Javascript
JS实现拖动模糊框特效
2020/08/25 Javascript
[03:58]兄弟们,回来开黑了!DOTA2昔日战友招募宣传视频
2016/07/17 DOTA
使用python3.5仿微软记事本notepad
2016/06/15 Python
python将一组数分成每3个一组的实例
2018/11/14 Python
Django框架搭建的简易图书信息网站案例
2019/05/25 Python
Pandas分组与排序的实现
2019/07/23 Python
python生成器用法实例详解
2019/11/22 Python
python实现低通滤波器代码
2020/02/26 Python
Django model.py表单设置默认值允许为空的操作
2020/05/19 Python
体育老师的教学自我评价分享
2013/11/19 职场文书
2014年迎新年活动方案
2014/02/19 职场文书
群众路线教育实践活动民主生活会个人检查对照思想汇报
2014/10/04 职场文书
新闻人物通讯稿
2014/10/09 职场文书
化妆品促销活动总结
2015/05/07 职场文书
小马王观后感
2015/06/11 职场文书
JavaScript数组 几个常用方法总结
2021/11/11 Javascript
微信小程序纯CSS实现无限弹幕滚动效果
2022/09/23 HTML / CSS