【Python】IndexError: list index out of range错误原因及解决过程
【Python】IndexError: list index out of range错误原因及解决过程
背景
这两年,python是如火如荼,许多人都在学python,我也不例外,最近利用业余时间在家学习使用python爬取信息。
这两天,我基于Scrapy
,利用有限的时间写了个比较简陋的爬虫去爬一些素材网站,睡觉时开启爬虫。
第二天起来发现,查看数据库,只有4k+条数据,这个程序只爬了几个小时,就被一个名叫IndexError: list index out of range
的错误给绊倒了!网上一搜,大部分都是在使用爬虫过程中会出现这个问题。
报错原因
list在读取的时候下标是从0开始读取的,list在已经定义的范围内,我们可以读取到索引值对应的值,但是如果下标没有定义,那么他的值是没有办法读取到的,这个时候也就是为社么会出现IndexError: list index out of range
。
>>>aList = [1,2,3,4,5,6,7,8,9,10]
##我是下标##[0,1,2,3,4,5,6,7,8,9 ]
>>>aList[8]
9
>>>aList[10]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
# 像这样,索引值超出了循环,也叫越界
找到原因,才能从根本解决问题。
这个是我从下面的经历中,领悟出来的 =. = “
解决方法
方法1:添加 try except
由于前几天还要上班,只要能继续跑就行了,使用了一个出现异常就跳过的方法
在下班回家之后,在修改了一下,添加了 异常处理try: ... except: ...
# (报错就跳过,非根本解决)
def get_URLs(urls):
for x in urls:
try :
...
title = selector.css("#resultList>div.el>span.t5::text").extract()[x]
...
except:
print('第{0}条数据处理失败'.format(x))
...
修改过后,第二天看爬去的数据量,比第一天多了,如下图
添加了try except
虽然可以暂时解决了因报错停止运行,但是问题还是在的,治标不治本。
================================================================================================
这两天周末,找了个招聘网爬取一下招聘信息,想着之前的demo写得比较烂再重新写一个
重写过程中,再次出现IndexError: list index out of range
,以及报错的行数。
好端端的怎么越界了= =
我用len()
方法,获取到了包含数据父元素的个数,当前页面是有50条数据的
然后用 for x in range()
方法,循环将数据以一定格式输出
listLen = len(selector.css("#resultList>div.el>p.t1>span>a::attr(title)").extract()) # 50
for x in range(listLen):
try:
job = selector.css("#resultList>div.el>p.t1>span>a::attr(title)").extract()[x]
com = selector.css("#resultList>div.el>span.t2>a::attr(title)").extract()[x]
area = selector.css("#resultList>div.el>span.t3::text").extract()[x]
salary = selector.css("#resultList>div.el>span.t4::text").extract()[x]
date = selector.css("#resultList>div.el>span.t5::text").extract()[x]
print("=========================================\n
{0}.{1}\n
{2}\n
{3}\n
{4}\n
=========================================\n
{5}\n".format( x, job,com,area,salary,date))
except:
print('抛异常:{0}'.format(selector.css("#resultList>div.el>p.t1>span>a::attr(title)").extract()[x]))
然后就最后一条抛异常了,爬了3页,几乎每一页都是最后一条抛异常。
去掉注释try except
之后再运行, IndexError: list index out of range
以及报错的位置大概在
salary = selector.css("#resultList>div.el>span.t4::text").extract()[x]
好吧,我找了半天找不到,我先和朋友吐槽一下先。
跟朋友说到range()的参数是当前页面的标题数量,提醒我看看那个报错当行位置,被选中的元素长度是多少。
注释掉之后,云淡风轻,什么错也没有 。
再试试输出salary
字段
输出了一下salary
字段只有49
个,for x in range()
里可是50呀!
所以原因出在这里,万万没有想到是这个原因
回到页面上看
what?!! 顿时觉得被命运绊倒
只能怪自己分析页面的时候没有多翻几页 = =’’
方法二:
根本解决:查看报错行数,找到出错的list,输出长度,如果有不同的list,分别输出一下list的长度
================================================================================================
因为少量数据再薪资这个位置可以为空,所以使用select.css(“selector::text”)选区不到空值。所以薪资这个字段就直接将整个标签以及内容获取到,再用正则匹配
<span class="t4"></span>
import re
str = '<span class="t4">1万 - 1.6万</span>'
searchObj = re.search(r'<span class="t4">(.*?)</span>', str , re.M|re.I)
salary = searchObj.group(1)
print(salary) # 1万 - 1.6万
最终,我是使用了正则匹配,拿到了这个可能为空的值
长度一样,50
截取小部分作为效果图
更多推荐
所有评论(0)