我正在解析来自网站的数据,但出现错误“ IndexError:列表索引超出范围”。但是,在调试时,我得到了所有值。以前,它完全可以正常工作,但是突然不明白为什么我会收到此错误。
@GET
@Path("connect")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void subscribe(@Context SseEventSink sseEventSink, @Context Sse sse,
@HeaderParam(HttpHeaders.LAST_EVENT_ID_HEADER) @DefaultValue("-1") int lastReceivedId) {
...
while(true){
...
OutboundSseEvent sseEvent = sse.newEventBuilder()
.comment("some comment")
.name("some name")
.id("somem id")
.mediaType(MediaType.TEXT_PLAIN_TYPE)
.data("some data")
.reconnectDelay(30)
.build();
CompletionStage<?> cs = sseEventSink.send(sseEvent);
cs.ifPresent(x -> {
x.whenComplete((serverSideEvent, serverSideThrowable) -> {
if (serverSideThrowable == null) {
//ok
} else {
//error
}
});
});
}
IndexError:列表索引超出范围
这是我的代码。
str2 = cols[1].text.strip()
这些是调试时的值:
import requests
import DivisionModel
from bs4 import BeautifulSoup
from time import sleep
class DivisionParser:
def __init__(self, zoneName, zoneUrl):
self.zoneName = zoneName
self.zoneUrl = zoneUrl
def getDivision(self):
response = requests.get(self.zoneUrl)
soup = BeautifulSoup(response.content, 'html5lib')
table = soup.findAll('table', id='mytable')
rows = table[0].findAll('tr')
division = []
for row in rows:
if row.text.find('T No.') == -1:
cols = row.findAll('td')
str1 = cols[0].text.strip()
str2 = cols[1].text.strip()
str3 = cols[2].text.strip()
strurl = cols[2].findAll('a')[0].get('href')
str4 = cols[3].text.strip()
str5 = cols[4].text.strip()
str6 = cols[5].text.strip()
str7 = cols[6].text.strip()
divisionModel = DivisionModel.DivisionModel(self.zoneName, str2, str3, strurl, str4, str5, str6, str7)
division.append(divisionModel)
return division
答案 0 :(得分:0)
通常,来自寒冷和敌对的外部世界的任何东西都是完全不可靠的。在这里:
response = requests.get(self.zoneUrl)
soup = BeautifulSoup(response.content, 'html5lib')
您似乎遭受了可怕的幻想,那就是响应将永远是您所期望的。提示:不会。 保证,有时响应会有所不同-可能是该站点已关闭,或者因为他们不希望您剪贴数据而决定将您的IP列入黑名单。>
IOW,您真的想检查响应的状态码和响应内容。实际上,您希望为任何事情做好准备-FWIW,因为您没有specify a timeout,所以您的代码可能会永远冻结,一直在等待响应
所以实际上您想要的是
try:
response = requests.get(yoururl, timeout=some_appropriate_value)
# cf requests doc
response.raise_for_status()
# cf requests doc
except requests.exceptions.RequestException as e
# nothing else you can do here - depending on
# the context (script ? library code ?),
# you either want to re-raise the exception
# raise your own exception or well, just
# show the error message and exit.
# Only you can decide what's the appropriate course
print("couldn't fetch {}: {}".format(yoururl, e))
return
if not response.headers['content-type'].startswith("text/html"):
# idem - not what you expected, and you can't do much
# except mentionning the fact to the caller one way
# or another. Here I just print the error and return
# but if this is library code you want to raise an exception
# instead
print("{} returned non text/html content {}".format(yoururl, response.headers['content-type']))
print("response content:\n\n{}\n".format(response.text))
return
# etc...
request
有一些相当详尽的文档,我建议您阅读的内容比快速入门更多,以正确学习和使用它。这只是工作的一半-即使您确实得到200条响应,没有重定向和正确的内容类型,也不意味着标记就是您所期望的,因此在这里,您必须再次检查从BeautifulSoup获得的内容-例如:
table = soup.findAll('table', id='mytable')
rows = table[0].findAll('tr')
绝对没有任何理由保证标记包含具有匹配ID的任何表(也没有所有FWIW的任何表),因此您必须事先检查或处理异常:
table = soup.findAll('table', id='mytable')
if not tables:
# oops, no matching tables ?
print("no table 'mytable' found in markup")
print("markup:\n{}\n".format(response.text))
return
rows = table[0].findAll('tr')
# idem, the table might be empty, etc etc
编程的有趣之处之一是处理标称情况通常很简单-但是您必须处理所有可能的极端情况,这通常需要比标称情况更多或更多的代码;-)< / p>
答案 1 :(得分:0)
当我通过连续检查T号从网站中解析数据并在td中获取所有值时,网站开发人员在某td行中输入了“ No Result”,因此这就是为什么在运行时我的循环无法运行的原因获取值并通过“列表索引超出范围错误”。
非常感谢大家的帮助。
DivisionParser类:
def __init__(self, zoneName, zoneUrl):
self.zoneName = zoneName
self.zoneUrl = zoneUrl
def getDivision(self):
global rows
try:
response = requests.get(self.zoneUrl)
soup = BeautifulSoup(response.content, 'html5lib')
table = soup.findAll('table', id='mytable')
rows = table[0].findAll('tr')
except IndexError:
sleep(2)
division = []
for row in rows:
if row.text.find('T No.') == -1:
try:
cols = row.findAll('td')
str1 = cols[0].text.strip()
str2 = cols[1].text.strip()
str3 = cols[2].text.strip()
strurl = cols[2].findAll('a')[0].get('href')
str4 = cols[3].text.strip()
str5 = cols[4].text.strip()
str6 = cols[5].text.strip()
str7 = cols[6].text.strip()
divisionModel = DivisionModel.DivisionModel(self.zoneName, str2, str3, strurl, str4, str5, str6,
str7)
division.append(divisionModel)
except IndexError:
print("No Result")
return division