【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

截取小部分作为效果图
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐