TypeError:“str”和“float”的实例之间不支持“<”Prettytable错误

2024-06-16 10:32:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我在尝试运行Py脚本时遇到上述错误。它还会在prettytable代码中抛出错误,这也很奇怪,因为我一直都很好地使用它。这基本上是一个网页抓取脚本,我在玩一个航空公司经理游戏时使用它

代码:

if "top" in str(r): # log-in was successful.
   if True: # just to make it collapsible
    def getHTML(url):
        return http.request('GET', url, headers={'Cookie': 'PHPSESSID='+phpSid}).data

    def findBetween1(s, start, end):
        try:
            return str((s.split(start))[1].split(end)[0])
        except:
            return ""

    def getHTMLthreaded(infoArray): # infoArray: [url, detail, detail]
        def getHTML(url):
            return http.request('GET', url, headers={'Cookie': 'PHPSESSID='+phpSid}).data

        with ThreadPoolExecutor(max_workers=threads) as executor:
            futureToURL = {executor.submit(getHTML, info): info for info in infoArray}
            responseResults = []
            for future in as_completed(futureToURL):
                responseResults.append(future.result()) # [data, url]

        return responseResults

    def median(lst):
        lst = [int(i) for i in lst]
        n = len(lst)
        s = sorted(lst)
        return int((sum(s[n//2-1:n//2+1])/2.0, s[n//2])[n % 2]) if n else None

acURLs = []
fleet = BeautifulSoup(getHTML('https://www.airline4.net/fleet.php?undefined'), "lxml").find_all(onclick=re.compile('Ajax')) # get a list of fleet

for acTypeId in fleet:
    acURLs.append('https://www.airline4.net/fleet.php?type='+findBetween1(str(acTypeId), 'type=', "'")) # for each fleet type, get a list of aircraft belonging to that type

acMenus = getHTMLthreaded(acURLs)

# t = PrettyTable([])
acIds = []
for acMenu in acMenus:
    acMenuItems = BeautifulSoup(acMenu, "lxml").find_all(onclick=re.compile('routes_main.php'))
    for thisAcMenu in acMenuItems:
        acIds.append('https://www.airline4.net/fleet_details.php?id='+findBetween1(str(thisAcMenu['onclick']), 'id=', "','"))

# acIds = ['https://www.airline4.net/fleet_details.php?id=1323552']

print('Sorting by "profit/pax", indicating how well the route actually profits.')
t = PrettyTable(['model', 'reg', 'chkH', 'wear', 'config', 'fn', 'route', u'$\u02dc', u'CO\u2082\u02dc', 'fuel', 'prof/pax', 'prof/hrs'])

acDetails = getHTMLthreaded(acIds)
for acDet in acDetails:
    acDet = BeautifulSoup(acDet, "lxml")

    mainTable = acDet.find(class_='col-sm-6 bg-light border').find_all(class_='m-text')
    seatLayout = acDet.find_all(class_='col-4 p-2 text-center exo')

    acType = str(mainTable[0].string)
    fleetReg = str(acDet.find(id='ff-name').string)
    chk = str(mainTable[2].string) # hours to check
    wear = str(mainTable[6].string) # wear percentage
    yS = str(seatLayout[0].find('br').next_sibling.strip().rjust(3))
    jS = str(seatLayout[1].find('br').next_sibling.strip().rjust(3))
    fS = str(seatLayout[2].find('br').next_sibling.strip().rjust(3))
    config = yS + "/" + jS + "/" + fS
    try: # in case the aircraft is not routed:
        routeReg = str(acDet.find(id='rr-name').string)
        stop = str(acDet.find(class_='xs-text pt-2')).replace('<div class="xs-text pt-2">Via<br/> ','').replace('</div>','')
        stop = "" if stop == "None" else "·" + stop
        route = str(acDet.find_all(class_='l-text exo')[0].string) + stop + "·" + str(acDet.find_all(class_='l-text exo')[1].string)

        inc, co2 = [], []
        for thisFlight in acDet.find_all(class_='row bg-light m-text p-1 border'):
            inc.append(str(thisFlight.find(class_='col-3 text-right text-success').find('b').string).replace('$', '').replace(',', ''))
            co2.append(str(thisFlight.find(class_='s-text').string).replace(' Quotas', '').replace(',', ''))
            prices = thisFlight.find_all(class_='col-3')[2]

        inc, co2 = median(inc), median(co2)
        fuel = str(acDet.find(class_='row bg-light m-text p-1 border').find_all(class_='s-text')[1].string).replace(' Lbs', '').replace(',', '')
        profit = inc - (co2 * co2Price / 1000) - (int(fuel) * fuelPrice / 1000)

        depTime = acDet.find_all(class_='col-6 bg-white border s-text')[0].string.strip().replace(' UTC', '').split(':')
        arrTime = acDet.find_all(class_='col-6 bg-white border s-text')[1].string.strip().replace(' UTC', '').split(':')

        depSec = int(depTime[0])*3600 + int(depTime[1])*60 + int(depTime[2])
        arrSec = int(arrTime[0])*3600 + int(arrTime[1])*60 + int(arrTime[2])
        hrsElapsed = ((86400 - (depSec - arrSec)) if depSec > arrSec else arrSec - depSec) / 3600

        profPax = round(profit / (int(yS) + int(jS)*2 + int(fS)*3),3)
        profHrs = round(profit / hrsElapsed, 3)

        t.add_row([acType, fleetReg, chk, wear, config, routeReg, route, inc, co2, fuel, profPax, profHrs])
    except: # only show the fleet details, but no other metrics
        # print(sys.exc_info()[0])
        t.add_row([acType, fleetReg, chk, wear, config, "", "", "", "", "", "", ""])

t.sortby = 'prof/pax'
print(t)

else:
print('Your e-mail and/or password was wrong.')

回溯:

Traceback (most recent call last):
  File "dX.py", line 123, in <module>
    print(t)
  File "C:\Users\SSM\AppData\Local\Programs\Python\Python38\lib\site-packages\prettytable.py", line 237, in __str__
    return self.__unicode__()
  File "C:\Users\SSM\AppData\Local\Programs\Python\Python38\lib\site-packages\prettytable.py", line 243, in __unicode__
    return self.get_string()
  File "C:\Users\SSM\AppData\Local\Programs\Python\Python38\lib\site-packages\prettytable.py", line 984, in get_string
    rows = self._get_rows(options)
  File "C:\Users\SSM\AppData\Local\Programs\Python\Python38\lib\site-packages\prettytable.py", line 933, in _get_rows
    rows.sort(reverse=options["reversesort"], key=options["sort_key"])
TypeError: '<' not supported between instances of 'str' and 'float'

Tags: textinurlforgetstringreturnall
1条回答
网友
1楼 · 发布于 2024-06-16 10:32:27

处理异常时,添加的默认值不能与浮点数进行比较:

except:
    t.add_row([acType, fleetReg, chk, wear, config, "", "", "", "", "", "", ""])
    #                       these are all strings   ^^  ^^  ^^  ^^  ^^  ^^  ^^

如果要对prof/pax列进行排序,则必须只为该列提供数值。也许0对你来说就足够了

except:
    t.add_row([acType, fleetReg, chk, wear, config, "", "", "", "", "", 0, ""])
    #                                        numeric value for profPax ^^

或者,您可以指定一个排序键,调用该键将排序列中的每个值转换为要比较的值。只有在排序时,才可以使用它将字符串替换为零

t.sort_key = lambda value: value or 0

这利用了""0都是false-y的事实,因此or将选择第二个值返回0

>>> value = ""
>>> value or 0
0

旁注:不加限制地使用except:很少是一个好主意。如果您的代码有零除法问题,只捕获该异常

except ZeroDivisionError:
     t.add_row([acType, fleetReg, chk, wear, config, "", "", "", "", "", "", ""])

你总是可以添加更多的例外;您的代码可能会引发ValueError(从int()转换等)和AttributeError(例如,从试图将None值视为漂亮的组元素来处理),因此您可以只捕获这3个

except (ZeroDivisionError, ValueError, AttributeError):
     t.add_row([acType, fleetReg, chk, wear, config, "", "", "", "", "", "", ""])

这使得以后更容易检测代码中的错误,并且如果需要很长时间才能捕捉到KeyboardInterrupt异常,则可以更容易地中断程序

相关问题 更多 >