《python爬虫学习》之for循环中的try和if效率对比

爬取b站数据时,因为有些视频没有简介或时长,导致使用xpath提取数据时出现IndexError错误,即

abstract = res.xpath('div[@class="r"]/div[@class="v-desc"]/text()')
times = res.xpath('div[@class="l"]//span[@class="dur"]/text()')
'''
这里如果爬取到的数据为空,得到的结果是abstract=[]和times=[]
因为这两个列表没有元素,所以使用abstract[0]和times[0]会导致越界,即索引值超出了列表长度
'''

 所以在后面重构代码的时候,我加了if语句去限定它,当他为空时赋值其他值,不为空时赋予list[0]的值。

for res in result:
    image = res.xpath('div[@class="l"]//div[@class="lazy-img"]/img/@src')[0]
    url = res.xpath('div[@class="l"]//a/@href')[0].replace('//', '')
    times = res.xpath('div[@class="l"]//span[@class="dur"]/text()')
    title = res.xpath('div[@class="r"]/a/text()')[0]
    abstract = res.xpath('div[@class="r"]/div[@class="v-desc"]/text()')
    num = res.xpath('div[@class="r"]/div[@class="v-info"]/span/span/text()')
    # 在66页有简介为空的视频导致IndexError: list index out of range错误,所以需要做一下判断
    # 其他的判断同理
    if len(abstract) == 0:
        abstract = '无简介'
    else:
        abstract = abstract[0]
    if len(times) == 0:
        times = '未知'
    else:
        times = times[0]

            

但思考了一下,每一次循环都用if语句去指定输出值,会不会增加时耗,所以我后面又添加了try语句,让它出现异常后再加限定。

    for res in result:
        '''
        如何没有空数据,即不会出现索引问题,我们就正常爬取,如果报错,那么我们就加判断条件限制.
        这里不直接使用if限定res的值不为空
        '''
        try:
            image = res.xpath('div[@class="l"]//div[@class="lazy-img"]/img/@src')[0]
            url = res.xpath('div[@class="l"]//a/@href')[0].replace('//', '')
            times = res.xpath('div[@class="l"]//span[@class="dur"]/text()')[0]
            title = res.xpath('div[@class="r"]/a/text()')[0]
            abstract = res.xpath('div[@class="r"]/div[@class="v-desc"]/text()')[0]
            num = res.xpath('div[@class="r"]/div[@class="v-info"]/span/span/text()')
        except IndexError:
            image = res.xpath('div[@class="l"]//div[@class="lazy-img"]/img/@src')[0]
            url = res.xpath('div[@class="l"]//a/@href')[0].replace('//', '')
            times = res.xpath('div[@class="l"]//span[@class="dur"]/text()')
            title = res.xpath('div[@class="r"]/a/text()')[0]
            abstract = res.xpath('div[@class="r"]/div[@class="v-desc"]/text()')
            num = res.xpath('div[@class="r"]/div[@class="v-info"]/span/span/text()')
            # 在66页有简介为空的视频导致IndexError: list index out of range错误,所以需要做一下判断
            # 其他的判断同理
            if len(abstract) == 0:
                abstract = '无简介'
            else:
                abstract = abstract[0]
            if len(times) == 0:
                times = '未知'
            else:
                times = times[0]

 那么,两种方法哪种效率最高呢?于是我做了一个比较不严谨的测试,就是对这两种方法进行一次爬取时长的测试对比。

首先是爬取1-99页数据(已知低66页会出现错误)

 iftry
1255.25015354156494253.46807074546814
2253.84186816215515252.08237195014954
3253.26841568946838251.44973397254944

 然后是1-50页数据(这里没有导致异常的数据)

 iftry
1128.0856523513794128.18170762062073
2127.2362470626831125.75610876083374
3126.44024205207825125.43329238891602

最后是1和51-100页(有导致异常的数据)

 iftry
1141.31432151794434141.8306381702423
2126.97643280029297137.30469703674316
3135.45368721348794140.42737317085266

这里看起来是有异常的情况下使用if去限定效率会比较高点,无异常的情况下try效率会高点,但实际考虑到网络的不稳定性,这组对比并不算严谨,所以我又写了下面代码来做对比。

import random
import time
T=[1]
F=[]
list=[T,F]
demoList1=[]
demoList2=[]
demoList3=[]
demoList4=[]
# 随机空列表
for i in range(1000000):
    demoList1.append(list[random.randint(0,1)])
beginTime = time.time()
count=0
num=0
FNum=0
for res in demoList1:
    if len(res)>0:
        num+=res[0]
    else:
        num +=1
        FNum+=1
    count+=num
endTime = time.time()
print(f'F数量为{FNum},本次if限定用时{endTime - beginTime}')

beginTime = time.time()
count=0
num=0
FNum=0
for res in demoList1:
    try:
        num+=res[0]
    except IndexError:
        num+=1
        FNum += 1
    finally:
        count+=num
endTime = time.time()
print(f'F数量为{FNum},本次try限定用时{endTime - beginTime}')

# 极少空列表的情况
for i in range(1000000):
    demoList2.append(list[0])
for i in range(100):
    demoList2[random.randint(0,1000000)]=F

beginTime = time.time()
count=0
num=0
FNum=0
for res in demoList2:
    if len(res)>0:
        num+=res[0]
    else:
        num +=1
        FNum+=1
    count+=num
endTime = time.time()
print(f'F数量为{FNum},本次if限定用时{endTime - beginTime}')

beginTime = time.time()
count=0
num=0
FNum=0
for res in demoList2:
    try:
        num+=res[0]
    except IndexError:
        num+=1
        FNum += 1
    finally:
        count+=num
endTime = time.time()
print(f'F数量为{FNum},本次try限定用时{endTime - beginTime}')
# 无空列表的情况
for i in range(1000000):
    demoList3.append(T)

beginTime = time.time()
count=0
num=0
FNum=0
for res in demoList3:
    if len(res)>0:
        num+=res[0]
    else:
        num +=1
        FNum+=1
    count+=num
endTime = time.time()
print(f'F数量为{FNum},本次if限定用时{endTime - beginTime}')

beginTime = time.time()
count=0
num=0
FNum=0
for res in demoList3:
    try:
        num+=res[0]
    except IndexError:
        num+=1
        FNum += 1
    finally:
        count+=num
endTime = time.time()
print(f'F数量为{FNum},本次try限定用时{endTime - beginTime}')

# 全空列表的情况
for i in range(1000000):
    demoList4.append(F)
beginTime = time.time()
count=0
num=0
FNum=0
for res in demoList4:
    if len(res)>0:
        num+=res[0]
    else:
        num +=1
        FNum+=1
    count+=num
endTime = time.time()
print(f'F数量为{FNum},本次if限定用时{endTime - beginTime}')

beginTime = time.time()
count=0
num=0
FNum=0
for res in demoList4:
    try:
        num+=res[0]
    except IndexError:
        num+=1
        FNum += 1
    finally:
        count+=num
endTime = time.time()
print(f'F数量为{FNum},本次try限定用时{endTime - beginTime}')

 第一次结果

F数量为500775,本次if限定用时0.7730720043182373
F数量为500775,本次try限定用时0.9919514656066895
F数量为100,本次if限定用时0.7140657901763916
F数量为100,本次try限定用时0.5791869163513184
F数量为0,本次if限定用时0.7121121883392334
F数量为0,本次try限定用时0.5681884288787842
F数量为1000000,本次if限定用时0.793057918548584
F数量为1000000,本次try限定用时1.504162073135376

第二次结果

F数量为499578,本次if限定用时0.8145346641540527
F数量为499578,本次try限定用时1.003842830657959
F数量为100,本次if限定用时0.812556266784668
F数量为100,本次try限定用时0.6121621131896973
F数量为0,本次if限定用时0.7909219264984131
F数量为0,本次try限定用时0.6411514282226562
F数量为1000000,本次if限定用时0.8359837532043457
F数量为1000000,本次try限定用时1.98175048828125

第三次结果

F数量为499816,本次if限定用时0.7385780811309814
F数量为499816,本次try限定用时0.9664478302001953
F数量为100,本次if限定用时0.6796119213104248
F数量为100,本次try限定用时0.5826675891876221
F数量为0,本次if限定用时0.6956019401550293
F数量为0,本次try限定用时0.5746748447418213
F数量为1000000,本次if限定用时0.775557279586792
F数量为1000000,本次try限定用时1.4921455383300781

 从测试结果可以知道,没有空列表或极少空列表时,try效率比if要高,但如果空列表数量过大时,采用if去限定比try效率高。

我们爬取数据时经常会遇见空列表,并且不知道有多少空列表,所以比起if去限定,不如直接用try语句。即使我们不知道哪个地方会出现IndexError这类错误,也可以先打印出来并且跳过进行执行代码。

 


 

 

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值