Python爬虫框架之异常处理

任何访问服务器获取数据的请求,都需要做异常处理,当然爬虫更需要我们对各种异常进行处理。只有这样才能提高爬虫的健壮性。如果我们的爬虫足够健壮,那么就能确保程序几个月不停止。

我们从以下几个方面做出讲解:

一:try except处理异常代码块

二:普通请求函数的超时处理

三:selenium+chrome | phantomjs 的超时处理

四:自定义函数的死锁or超时处理

五:自定义线程的死锁or超时处理

六:自重启的程序设计

一:基础try except异常处理

try except的语句可以让我们的程序跳过代码中可能出现的异常

try:

pass http://code.py40.com/deliver-article/#

#可能出错的语句

except Exception as e:

pass

#保留错误的url,留待下次重跑

print(e)

finally:

#无论是否处理了异常都继续运行

print(time.ctime())

1

2

3

4

5

6

7

8

9

10

try:

passhttp://code.py40.com/deliver-article/#

#可能出错的语句

exceptExceptionase:

pass

#保留错误的url,留待下次重跑

print(e)

finally:

#无论是否处理了异常都继续运行

print(time.ctime())

二:请求函数的超时处理

2.1:普通请求:

2.1.1单请求类型:

import requests

requests.get(url,timeout=60)

1

2

importrequests

requests.get(url,timeout=60)

2.1.2会话保持类型:

import requesocks

session = requesocks.session()

response = session.get(URL,headers=headers,timeout=10)

1

2

3

importrequesocks

session=requesocks.session()

response=session.get(URL,headers=headers,timeout=10)

三:selenium+chrome | phantomjs 的超时处理

2.2.1:selenium+chrome的超时设置

官网原文:http://selenium-python.readthedocs.io/waits.html

显式等待:、等待某个条件发生,然后再继续进行代码。

from selenium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()

driver.get("http://somedomain/url_that_delays_loading")

try:

element = WebDriverWait(driver, 10).until( #这里修改时间

EC.presence_of_element_located((By.ID, "myDynamicElement"))

)

finally:

driver.quit()

1

2

3

4

5

6

7

8

9

10

11

12

13

fromseleniumimportwebdriver

fromselenium.webdriver.common.byimportBy

fromselenium.webdriver.support.uiimportWebDriverWait

fromselenium.webdriver.supportimportexpected_conditionsasEC

driver=webdriver.Firefox()

driver.get("http://somedomain/url_that_delays_loading")

try:

element=WebDriverWait(driver,10).until(#这里修改时间

EC.presence_of_element_located((By.ID,"myDynamicElement"))

)

finally:

driver.quit()

隐式等待:是告诉WebDriver在尝试查找一个或多个元素(如果它们不是立即可用的)时轮询DOM一定时间。默认设置为0,一旦设置,将为WebDriver对象实例的生命期设置隐式等待。

from selenium import webdriver

driver = webdriver.Firefox()

driver.implicitly_wait(10) # seconds

driver.get("http://somedomain/url_that_delays_loading")

myDynamicElement = driver.find_element_by_id("myDynamicElement")

1

2

3

4

5

6

fromseleniumimportwebdriver

driver=webdriver.Firefox()

driver.implicitly_wait(10)# seconds

driver.get("http://somedomain/url_that_delays_loading")

myDynamicElement=driver.find_element_by_id("myDynamicElement")

2.2.2:phantomjs的超时设置

这里使用不带selenium的phantomjs,需要使用js。主要设置语句是

#JavaScript

page.settings.resourceTimeout = 5000; // 等待5秒

var system = require('system');

var args = system.args;

var url = args[1];

var page = require('webpage').create();

page.settings.resourceTimeout = 5000; // 等待5秒

page.onResourceTimeout = function(e) {

console.log(e.errorCode);   //打印错误码

console.log(e.errorString);//打印错误语句

console.log(e.url);     //打印错误url

phantom.exit(1);

};

page.open(url, function(status) {

if(status==='success'){

var html=page.evaluate(function(){

returndocument.documentElement.outerHTML;

});

console.log(html);

}

phantom.exit();

});

//$phantomjs xx.js http://bbs.pcbaby.com.cn/topic-2149414.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#JavaScript

page.settings.resourceTimeout=5000;//等待5秒

varsystem=require('system');

varargs=system.args;

varurl=args[1];

varpage=require('webpage').create();

page.settings.resourceTimeout=5000;//等待5秒

page.onResourceTimeout=function(e){

console.log(e.errorCode);  //打印错误码

console.log(e.errorString);//打印错误语句

console.log(e.url);    //打印错误url

phantom.exit(1);

};

page.open(url,function(status){

if(status==='success'){

varhtml=page.evaluate(function(){

returndocument.documentElement.outerHTML;

});

console.log(html);

}

phantom.exit();

});

//$phantomjsxx.jshttp://bbs.pcbaby.com.cn/topic-2149414.html

四:自定义函数的死锁or超时处理

这个非常重要!!

python是顺序执行的,但是如果下一句话可能导致死锁(比如一个while(1))那么如何强制让他超时呢?他本身如果没有带有超时设置的话,就要自己运行信号(import signal)来处理

#coding:utf-8

import time

import signal

def test(i):

time.sleep(0.999)#模拟超时的情况

print "%d within time"%(i)

return i

def fuc_time(time_out):

# 此为函数超时控制,替换下面的test函数为可能出现未知错误死锁的函数

def handler(signum, frame):

raise AssertionError

try:

signal.signal(signal.SIGALRM, handler)

signal.alarm(time_out)#time_out为超时时间

temp = test(1) #函数设置部分,如果未超时则正常返回数据,

return temp

except AssertionError:

print("%d timeout"%(i))# 超时则报错

if __name__ == '__main__':

for i in range(1,10):

fuc_time(1)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#coding:utf-8

importtime

importsignal

deftest(i):

time.sleep(0.999)#模拟超时的情况

print"%d within time"%(i)

returni

deffuc_time(time_out):

# 此为函数超时控制,替换下面的test函数为可能出现未知错误死锁的函数

defhandler(signum,frame):

raiseAssertionError

try:

signal.signal(signal.SIGALRM,handler)

signal.alarm(time_out)#time_out为超时时间

temp=test(1)#函数设置部分,如果未超时则正常返回数据,

returntemp

exceptAssertionError:

print("%d timeout"%(i))# 超时则报错

if__name__=='__main__':

foriinrange(1,10):

fuc_time(1)

五:自定义线程的死锁or超时处理

在某个程序中一方面不适合使用selenium+phantomjs的方式(要实现的功能比较难不适合)因为只能用原生的phantomjs,但是这个问题他本身在极端情况下也有可能停止(在超时设置之前因为某些错误)

那么最佳方案就是用python单独开一个线程(进程)调用原生phantomjs,然后对这个线程进程进行超时控制。

这里用ping这个命令先做测试,

import subprocess

from threading import Timer

import time

kill = lambda process: process.kill()

cmd = ["ping", "www.google.com"]

ping = subprocess.Popen(

cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

my_timer = Timer(5, kill, [ping])#这里设定时间,和命令

try:

my_timer.start()#启用

stdout, stderr = ping.communicate()#获得输出

#print stderr

print(time.ctime())

finally:

print(time.ctime())

my_timer.cancel()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

importsubprocess

fromthreadingimportTimer

importtime

kill=lambdaprocess:process.kill()

cmd=["ping","www.google.com"]

ping=subprocess.Popen(

cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

my_timer=Timer(5,kill,[ping])#这里设定时间,和命令

try:

my_timer.start()#启用

stdout,stderr=ping.communicate()#获得输出

#print stderr

print(time.ctime())

finally:

print(time.ctime())

my_timer.cancel()

六:程序自动重启

比如我们的程序在某种情况下报错多次,那么当满足条件后,让其重启即可解决大多数问题,当然这只不过是治标不治本而已,如果这个程序重启没有大问题(例如读队列类型)那么自重启这是最省力的方式之一。

import time

import sys

import os

def restart_program():

python = sys.executable

os.execl(python, python, * sys.argv)

if __name__ == "__main__":

print 'start...'

print u"3秒后,程序将结束...".encode("utf8")

time.sleep(3)

restart_program()

1

2

3

4

5

6

7

8

9

10

11

12

importtime

importsys

importos

defrestart_program():

python=sys.executable

os.execl(python,python,*sys.argv)

if__name__=="__main__":

print'start...'

printu"3秒后,程序将结束...".encode("utf8")

time.sleep(3)

restart_program()

python异常数据处理_Python爬虫提高之异常处理相关推荐

  1. python异常数据处理_Python 异常处理和捕获信息教程

    在学习了Python的基础数据类型和它们的相关操作方法之后,要学习的另外一个重点知识是 Python异常. 我们经常在编写程序和调试代码的过程中,有发生一些错误,为了处理和提醒用户这些错误,Pytho ...

  2. python异常数据处理_Python数据处理:异常值处理方法之3σ原则

    原标题:Python数据处理:异常值处理方法之3σ原则 一.3σ原则定义 异常值是指样本中的个别值,其数值明显偏离其余的观测值.异常值也称离群点,异常值的分析也称为离群点的分析. 在进行机器学习过程中 ...

  3. python异常数据处理_python中如何处理异常值

    打开pycharm开发工具,在运行窗口输入命令:import pandas as pd #导入pandas库 输入数据集.data=pd.DataFrame({'name':['A','B','C', ...

  4. python异常捕获_Python 异常的捕获、异常的传递与主动抛出异常操作示例

    本文实例讲述了Python 异常的捕获.异常的传递与主动抛出异常操作.分享给大家供大家参考,具体如下: 异常的捕获 demo.py(异常的捕获): try: # 提示用户输入一个整数 num = in ...

  5. python 异常分类_python的异常处理

    1. 异常 2. 异常种类 3. 异常处理 1. 异常 异常就是程序运行中发生的错误信号,如程序产生问题,而没有处理它,程序运行就将停止,py中错误触发的异常如下 2.异常种类 一般异常 Attrib ...

  6. python异常包_python异常处理与导入模块与导入包

    一.什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常. 异常是Python对象,表示一个错误. 当Py ...

  7. python异常如何处理_python异常处理

    异常处理 异常和错误 程序中错误分类 1.语法错误(程序执行前改正) 2.逻辑错误 什么是异常? 异常就是程序运行时发生错误的信号 python中常见的异常种类 在python中不同的异常可以用不同的 ...

  8. python 异常回溯_Python 代码的异常处理和打印异常信息

    前言 1.Python的异常处理可以向用户准确反馈出错信息,所有异常都是基类Exception的子类.自定义异常都是从基类Exception中继承.Python自动将所有内建的异常放到内建命名空间中, ...

  9. python爬虫urllib 数据处理_Python 爬虫笔记之Urllib的用法

    urllib总共有四个子模块,分别为request,error,parse,robotparser request用于发送request(请求)和取得response(回应) error包含reque ...

最新文章

  1. MySQL主从原理,基于快速学习一门技术的3种方式!
  2. 连接失败_iG.Firefox连接失败?iG新赛季仍未敲定主教练人选
  3. 《探索需求》阅读笔记1
  4. 关于ubuntu无法启动nginx的问题
  5. Problem L. Graph Theory Homework
  6. Python数据结构与算法(1.4)——Python基础之控制结构
  7. Three.js 学习笔记(1)--坐标体系和旋转
  8. java后台生成APP和H5所需要支付宝订单
  9. linux odbc 配置文件,linux操作系统配置ODBC数据源
  10. 在win10下安装Linux双系统
  11. 机房收费系统——可行性研究报告
  12. 2020软考软件设计师--基础知识实战培训视频-任铄-专题视频课程
  13. etal斜体吗 参考文献_期刊论文的参考文献格式
  14. tumblr_从iPhone或iPod Touch更新Tumblr博客
  15. [微语 20.11.17] 本质
  16. 钟道隆逆向英语学习法—学习SpeciaI English的三个阶段
  17. Java 泛型 <? super T> <? extend T> 的通俗理解
  18. 【教程】ECharts饼图记录
  19. leetcode 跳跃游戏系列 c++
  20. 视频文件服务器加速,视频CDN,视频点播加速,视频点播CDN加速,CDN流媒体点播加速_速网云计算CDN服务商·卓越的互联网业务平台提供商...

热门文章

  1. mysql分组之后统计数量
  2. ☆☆在Eclipse中编译NDK的so文件(普通安卓项目转换为NDK项目的设定)
  3. c/c++整理--c++面向对象(5)
  4. Alsa里面恶心的DAPM
  5. ms access to mysql_Access转MySQL工具
  6. Python带*参数和带**参数
  7. 智慧交通day02-车流量检测实现11:yoloV3模型
  8. linux 6.2 期末考试题,redhat6.2-linux考试试卷(带部分答案)
  9. mysql与缓存脏读_MySQL 事务的隔离级别问题 之 脏读
  10. LeetCode 2049. 统计最高分的节点数目(DFS)