python 网络爬虫与信息采取之异常处理

本篇文章转自Ryan Mitchell 写的python:网络数据采集
网络是十分复杂的。网页数据格式不友好,网站服务器宕机,目标数据的标签找不到,都是很麻烦的事情。网络数据采集最痛苦的遭遇之一,就是爬虫运行的时候你洗洗睡了,梦想着明天一早数据就都会采集好放在数据库里,结果第二天醒来,你看到的却是一个因某种数据格式异常导致运行错误的爬虫,在前一天当你不再盯着屏幕去睡觉之后,没过一会儿爬虫就不再运行了。那个时候,你可能想骂发明互联网(以及那些奇葩的网络数据格式)的人,但是你真正应该斥责的人是你自己,为什么一开始不估计可能会出现的异常!
让我们看看爬虫 import 语句后面的第一行代码,如何处理那里可能出现的异常:
html = urlopen("http://www.pythonscraping.com/pages/page1.html")
这行代码主要可能会发生两种异常:
• 网页在服务器上不存在(或者获取页面的时候出现错误)
• 服务器不存在第一种异常发生时,程序会返回 HTTP 错误。
HTTP 错误可能是“404 Page Not Found”“500Internal Server Error”等。所有类似情形,urlopen 函数都会抛出“HTTPError”异常。我们可以用下面的方式处理这种异常:

try: html =  urlopen("http://www.pythonscraping.com/pages/page1.html")
except HTTPError as e:
 print(e) # 返回空值,中断程序,或者执行另一个方案
 else: # 程序继续。

注意:如果你已经在上面异常捕捉那一段代码里返回或中断(break), # 那么就不需要使用else语句了,这段代码也不会执行如果程序返回 HTTP 错误代码,程序就会显示错误内容,不再执行 else 语句后面的代码。
如果服务器不存在(就是说链接 http://www.pythonscraping.com/ 打不开,或者是 URL 链接写错了),urlopen 会返回一个 None 对象。这个对象与其他编程语言中的 null 类似。我们可以增加一个判断语句检测返回的 html 是不是None:
if html is None:
print(“URL is not found”)
else: # 程序继续
网页已经从服务器成功获取,如果网页上的内容并非完全是我们期望的那样,仍然可能会出现异常。每当你调用 BeautifulSoup 对象里的一个标签时,增加一个检查条件保证标签确实存在是很聪明的做法。如果你想要调用的标签不存在,BeautifulSoup 就会返初见网络爬虫 | 9回 None 对象。不过,如果再调用这个 None 对象下面的子标签,就会发生 AttributeError错误。下面这行代码(nonExistentTag 是虚拟的标签,BeautifulSoup 对象里实际没有)print(bsObj.nonExistentTag)会返回一个 None 对象。处理和检查这个对象是十分必要的。如果你不检查,直接调用这个None 对象的子标签,麻烦就来了。如下所示。
print(bsObj.nonExistentTag.someTag)
AttributeError: 'NoneType' object has no attribute 'someTag'
我们怎么才能避免这两种情形的异常呢?最简单的方式就是对两种情形进行检查:

try: badContent = bsObj.nonExistingTag.anotherTag
except AttributeError as e:
    print("Tag was not found")
else: 
	 if badContent == None:
		  print ("Tag was not found")
	 else: print(badContent)
 `初看这些检查与错误处理的代码会觉得有点儿累赘,但是,我们可以重新简单组织一下代码,让它变得不那么难写(更重要的是,不那么难读)。例如,下面的代码是上面爬虫的另一种写法:
from urllib.request import urlopenfrom

urllib.error
import HTTPErrorfrom

bs4
import BeautifulSoup


def getTitle(url): try

    : html = urlopen(url) except HTTPError as e:
return None
try: bsObj = BeautifulSoup(html.read())
title = bsObj.body.h1 except AttributeError as e:
return None
return titletitle = getTitle("http://www.pythonscraping.com/pages/page1.html")
if title == None:
    print("Title could not be found")else:
    print(title)

第 1 章在这个例子中,我们创建了一个 getTitle 函数,可以返回网页的标题,如果获取网页的时候遇到问题就返回一个 None 对象。在 getTitle 函数里面,我们像前面那样检查了HTTPError,然后把两行 BeautifulSoup 代码封装在一个 try 语句里面。这两行中的任何一行有问题,AttributeError 都可能被抛出(如果服务器不存在,html 就是一个 None 对象,html.read() 就会抛出 AttributeError)。其实,我们可以在 try 语句里面放任意多行代码,或者放一个在任意位置都可以抛出 AttributeError 的函数。在写爬虫的时候,思考代码的总体格局,让代码既可以捕捉异常又容易阅读,这是很重要的。如果你还希望能够很大程度地重用代码,那么拥有像 getSiteHTML 和 getTitle 这样的通用函数(具有周密的异常处理功能)会让快速稳定地网络数据采集变得简单易行。

0x03 一些闲话

本人创建了一个公众号,分享科研路上的小问题,新发现,欢迎关注公众号,给我留言!!!
一起奋发向上,攻克难题吧~~

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淮左青衣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值