麦子学院 2017-02-15 11:56
Python爬虫异常和超时问题怎么处理?
回复:0 查看:4259
python爬虫
这类型程序典型特征是意外多,无法确保每次请求都是稳定的返回统一的结果,要提高健壮性,能对错误数据or超时or程序死锁等都能进行处理,才能确保程序几个月不停止。本文和大家分享的就是python高度健壮性爬虫的异常和超时问题相关内容,一起来看看吧。
一:基础try&except异常处理
try&except的语句作用不仅仅是要让其捕获异常更重要的是让其忽略异常,因为爬虫中的绝大多数异常可能重新请求就不存在,因此,发现异常的时候将其任务队列进行修复其实是个最省力的好办法。
其次被try包住的语句即使出错也不会导致整个程序的退出,相信我,你绝对不希望计划跑一个周末的程序在半夜停止了。
try:
pass http://top.jobbole.com/deliver-article/#
#可能出错的语句except Exception,e:
pass
#保留错误的url,留待下次重跑
print efinally:
#无论是否处理了异常都继续运行
print time.ctime()
二:请求函数的超时处理
2.1:普通请求:
2.1.1单请求类型:
import requests
requests.get(url,timeout=60)
2.1.2会话保持类型:
import requesocks
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
显式等待:、等待某个条件发生,然后再继续进行代码。
fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriver.support.uiimportWebDriverWait
fromselenium.webdriver.supportimportexpected_conditionsas 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()
隐式等待:是告诉WebDriver在尝试查找一个或多个元素(如果它们不是立即可用的)时轮询DOM一定时间。默认设置为0,一旦设置,将为WebDriver对象实例的生命期设置隐式等待。
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。主要设置语句是
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
四:自定义函数的死锁or超时处理
这个非常重要!!
python是顺序执行的,但是如果下一句话可能导致死锁(比如一个while(1))那么如何强制让他超时呢?他本身如果没有带有超时设置的话,就要自己运行信号(import signal)来处理
#coding:utf-8import timeimport 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)
五:自定义线程的死锁or超时处理
在某个程序中一方面不适合使用selenium+phantomjs的方式(要实现的功能比较难不适合)因为只能用原生的phantomjs,但是这个问题他本身在极端情况下也有可能停止(在超时设置之前因为某些错误)
那么最佳方案就是用python单独开一个线程(进程)调用原生phantomjs,然后对这个线程进程进行超时控制。
这里用ping这个命令先做测试,
import subprocessfrom threading import Timerimport 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()
六:自重启的程序设计
比如程序在某种情况下报错多次,,那么满足条件后,让其重启即可解决大多数问题,当然这只不过是治标不治本而已,如果这个程序重启没有大问题(例如读队列类型)那么自重启这是最省力的方式之一。
import timeimport sysimport osdef 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()
来源:伯乐在线
一:基础try&except异常处理
try&except的语句作用不仅仅是要让其捕获异常更重要的是让其忽略异常,因为爬虫中的绝大多数异常可能重新请求就不存在,因此,发现异常的时候将其任务队列进行修复其实是个最省力的好办法。
其次被try包住的语句即使出错也不会导致整个程序的退出,相信我,你绝对不希望计划跑一个周末的程序在半夜停止了。
try:
pass http://top.jobbole.com/deliver-article/#
#可能出错的语句except Exception,e:
pass
#保留错误的url,留待下次重跑
print efinally:
#无论是否处理了异常都继续运行
print time.ctime()
二:请求函数的超时处理
2.1:普通请求:
2.1.1单请求类型:
import requests
requests.get(url,timeout=60)
2.1.2会话保持类型:
import requesocks
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
显式等待:、等待某个条件发生,然后再继续进行代码。
fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriver.support.uiimportWebDriverWait
fromselenium.webdriver.supportimportexpected_conditionsas 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()
隐式等待:是告诉WebDriver在尝试查找一个或多个元素(如果它们不是立即可用的)时轮询DOM一定时间。默认设置为0,一旦设置,将为WebDriver对象实例的生命期设置隐式等待。
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。主要设置语句是
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
四:自定义函数的死锁or超时处理
这个非常重要!!
python是顺序执行的,但是如果下一句话可能导致死锁(比如一个while(1))那么如何强制让他超时呢?他本身如果没有带有超时设置的话,就要自己运行信号(import signal)来处理
#coding:utf-8import timeimport 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)
五:自定义线程的死锁or超时处理
在某个程序中一方面不适合使用selenium+phantomjs的方式(要实现的功能比较难不适合)因为只能用原生的phantomjs,但是这个问题他本身在极端情况下也有可能停止(在超时设置之前因为某些错误)
那么最佳方案就是用python单独开一个线程(进程)调用原生phantomjs,然后对这个线程进程进行超时控制。
这里用ping这个命令先做测试,
import subprocessfrom threading import Timerimport 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()
六:自重启的程序设计
比如程序在某种情况下报错多次,,那么满足条件后,让其重启即可解决大多数问题,当然这只不过是治标不治本而已,如果这个程序重启没有大问题(例如读队列类型)那么自重启这是最省力的方式之一。
import timeimport sysimport osdef 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()
来源:伯乐在线