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 正则表达式 概述及常用字符
May 04 Python
python的urllib模块显示下载进度示例
Jan 17 Python
利用Psyco提升Python运行速度
Dec 24 Python
Python中文字符串截取问题
Jun 15 Python
两个使用Python脚本操作文件的小示例分享
Aug 27 Python
python3.0 模拟用户登录,三次错误锁定的实例
Nov 02 Python
pyqt5 使用label控件实时显示时间的实例
Jun 14 Python
Python字符串对象实现原理详解
Jul 01 Python
Python closure闭包解释及其注意点详解
Aug 28 Python
Python生态圈图像格式转换问题(推荐)
Dec 02 Python
Pyqt5自适应布局实例
Dec 13 Python
python3 通过 pybind11 使用Eigen加速代码的步骤详解
Dec 07 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
smarty基础之拼接字符串的详解
2013/06/18 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
php二维码生成以及下载实现
2017/09/28 PHP
PHP注释语法规范与命名规范详解篇
2018/01/21 PHP
Laravel框架Request、Response及Session操作示例
2019/05/06 PHP
使用ajaxfileupload.js实现ajax上传文件php版
2014/06/26 Javascript
jQuery内置的AJAX功能和JSON的使用实例
2014/07/27 Javascript
jquery结婚电子请柬特效源码分享
2015/08/21 Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
2015/12/09 Javascript
jQuery制作圣诞主题页面 更像是爱情影集
2016/08/10 Javascript
JS公共小方法之判断对象是否为domElement的实例
2016/11/25 Javascript
js选项卡的制作方法
2017/01/23 Javascript
js实现下一页页码效果
2017/03/07 Javascript
angular仿支付宝密码框输入效果
2017/03/25 Javascript
Angular.js中ng-include用法及多标签页面的实现方式详解
2017/05/07 Javascript
前端天气插件tpwidget使用方法详解
2019/06/24 Javascript
Vue修改项目启动端口号方法
2019/11/07 Javascript
Python实现大文件排序的方法
2015/07/10 Python
python开发环境PyScripter中文乱码问题解决方案
2016/09/11 Python
python遍历 truple list dictionary的几种方法总结
2016/09/11 Python
Python向Excel中插入图片的简单实现方法
2018/04/24 Python
Python生成rsa密钥对操作示例
2019/04/26 Python
实例详解python函数的对象、函数嵌套、名称空间和作用域
2019/05/31 Python
pyqt5 实现 下拉菜单 + 打开文件的示例代码
2019/06/20 Python
python之拟合的实现
2019/07/19 Python
python实现梯度下降和逻辑回归
2020/03/24 Python
Python导入模块包原理及相关注意事项
2020/03/25 Python
如何卸载python插件
2020/07/08 Python
Python+unittest+DDT实现数据驱动测试
2020/11/30 Python
YOOX美国官方网站:全球著名的多品牌时尚网络概念店
2016/09/11 全球购物
POS解决方案:MUNBYN(热敏打印机、条形码扫描仪)
2020/06/09 全球购物
元宵节寄语大全
2015/02/27 职场文书
安全知识竞赛主持词
2015/06/30 职场文书
2019年世界儿童日宣传标语
2019/11/22 职场文书
船舶调度指挥系统——助力智慧海事
2022/02/18 无线电
element tree树形组件回显数据问题解决
2022/08/14 Javascript