文章 > 其他 > python爬虫容易被忽略的问题:确保可靠的网络连接

python爬虫容易被忽略的问题:确保可靠的网络连接

Python爬虫

头像

太阳HTTP

2021-03-19 19:05:5857浏览 · 0收藏 · 0评论

5d65e1d4da4b5864.jpg

随着代理ip技术的普及,爬虫的使用也变得简单起来。 但网络是非常复杂的。网页数据格式不友好,网站服务器宕机,目标数据的标签找不到,都是很麻烦的事情。网络数据采集最痛苦的遭遇之一,就是爬虫运行的时候你洗洗睡了,梦想着明天一早数据就都会采集好放在数据库里,结果第二天醒来,你看到的却是一个因某种数据格式异常导致运行错误的爬虫。在前一天当你不再盯着屏幕去睡觉时,没过一会爬虫就不行了。针对这种情况,如何进行这种异常的处理方式:

让我们看看爬虫import语句后面的第一行代码,如何处理那里可能出现的异常:

html=urlopen("http://www.pythonscraping.com/pages/page1.html")

这行代码主要可能会发生两种异常:

(1)服务器不存在

(2)网页在服务器上不存在(或者获取页面的时候出现错误)

      第一种异常情况,如果服务器不存在(就是说链接http://www.pythonscraping.com/打不开,或者是URL链接写错了),urlopen会返回一个None对象。这个对象与其他编程语言中的null类似。我们可以增加一个判断语句检测返回的html是不是none

if html is None:

     print("URL is not found")

else:

     #程序继续

        当然,即使网页已经从服务器成功获取,如果网页上的内容并非完全是我们期望的那样,仍然会出现异常。每当你调用BeautifulSoup对象里的一个标签时,增加一个检查条件保证标签确实存在时很聪明的做法。如果你想要调用的标签不存在,BeautifulSoup就会返回None对象。不过,如果再调用这个None对象下面的子标签,就会发生AttributeError错误。

         下面这行代码(notExistentTag是虚拟的标签,BeautifulSoup对象里实际没有)

print (bsObj.noExistentTag)

就会返回一个None对象,处理和检查这个对象是十分必要的。如果你不检查,直接调用这个None对象的子标签,麻烦就来了,如下所示

print (bsObj.noExistentTag.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)

第二种异常情况,程序返回HTTP错误。HTTP错误可能是“404 Page Not Found”"500 Internal Server Error"等。所有类似情形,urlopen函数都会抛出“Http Error”异常。我们可以用下面的方式处理这种异常:

try:

     html=urlopen("http://www.pythonscrapinig.com/pages/page1.html")

except HTTPError as e:

     print(e)

     #返回空值,中断程序,或者执行另一个方案

else:

       #程序继续:注意,如果你已经在上面异常捕捉那段代码里返回或中断(break)

       #那么久不需要使用else语句了,这段代码也不会执行

        如果程序返回HTTP错误代码,程序就会显示错误内容,不再执行else语句后面的代码。

整合上面的两种异常处理,一个全新的爬虫写法如下:

from urllib.request import urlopen

from urllib.error import HTTPError

from bs4 import BeautifulSoup

def getTitle(url):

    try:

        html=urlopen(url)

    except HTTPError as e:

        return None

    try:

        bsObj=BeautifulSoup(html.read(),"html.parser")

        title=bsObj.body.h1

    except AttributeError as e:

        return None

    return title

title=getTitle("http://pythonscraping.com/pages/page1.html")    

if title == None:

    print("Title Could not be found")

else:

    print(title)

执行结果如下:

在这个例子中,我们创建了一个getTitle函数,可以返回网页的标题,如果获取网页的时候遇到问题就返回同一个None对象。在getTitle函数里面,我们像前面那样检查了HTTPError,然后把两行BeautifulSoup代码封装在一个try语句里面。这两行中的任何一行有问题,AttributeError都可能被抛出(如果服务器不存在,html就是一个None对象,html.read()就会抛出AttributeError). 其实,我们可以在try语句里面放任意多行代码,或者放一个在任意位置都可以抛出AttributeError的函数。

在写爬虫的时候,思考代码的总体格局,让代码既可以捕捉异常又容易阅读,这是很重要的。如果你还希望能够很大程度地重用代码,那么拥有像getSiteHTML和getTitle这样的通用函数(具有周密的异常处理功能)会让快速稳定地网络数据采集变得简单易行。

关注公众号

关注公众号,随时随地在线学习

本教程部分素材来源于网络,版权问题联系站长!

底部广告图 底部广告图按钮