如何处理通过应用isbnlib.meta返回的错误

2024-09-30 03:24:01 发布

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

我正在使用isbnlib.meta,当您输入isbn时,它会提取元数据(书名、作者、年份出版商等)。我有一个包含482000个ISBN的数据帧(列标题:isbn13)。当我运行这个函数时,我会得到一个类似NotValidISBNError的错误,它会停止代码的运行。我想发生的是,如果出现错误,代码将直接跳过该行并移到下一行

这是我现在的代码:

list_df[0]['publisher_isbnlib'] = list_df[0]['isbn13'].apply(lambda x: isbnlib.meta(x).get('Publisher', None))
list_df[0]['yearpublished_isbnlib'] = list_df[0]['isbn13'].apply(lambda x: isbnlib.meta(x).get('Year', None))
#list_df[0]['language_isbnlib'] = list_df[0]['isbn13'].apply(lambda x: isbnlib.meta(x).get('Language', None))
list_df[0]

list_df[0]是我试图通过数据帧进行分块后的前20000行。我刚刚手动输入了24次代码来处理每个块

我尝试了尝试:除了:但最终发生的是代码停止,我没有得到任何元数据报告

回溯:

---------------------------------------------------------------------------
NotValidISBNError                         Traceback (most recent call last)
<ipython-input-39-a06c45d36355> in <module>
----> 1 df['meta'] = df.isbn.apply(isbnlib.meta)

e:\Anaconda3\lib\site-packages\pandas\core\series.py in apply(self, func, convert_dtype, args, **kwds)
   4198             else:
   4199                 values = self.astype(object)._values
-> 4200                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   4201 
   4202         if len(mapped) and isinstance(mapped[0], Series):

pandas\_libs\lib.pyx in pandas._libs.lib.map_infer()

e:\Anaconda3\lib\site-packages\isbnlib\_ext.py in meta(isbn, service)
     23 def meta(isbn, service='default'):
     24     """Get metadata from Google Books ('goob'), Open Library ('openl'), ..."""
---> 25     return query(isbn, service) if isbn else {}
     26 
     27 

e:\Anaconda3\lib\site-packages\isbnlib\dev\_decorators.py in memoized_func(*args, **kwargs)
     22             return cch[key]
     23         else:
---> 24             value = func(*args, **kwargs)
     25             if value:
     26                 cch[key] = value

e:\Anaconda3\lib\site-packages\isbnlib\_metadata.py in query(isbn, service)
     18     if not ean:
     19         LOGGER.critical('%s is not a valid ISBN', isbn)
---> 20         raise NotValidISBNError(isbn)
     21     isbn = ean
     22     # only import when needed

NotValidISBNError: (abc) is not a valid ISBN

Tags: 数据代码indflibpackagessitemeta
2条回答
  • 当前用于提取isbn元数据的实现速度非常慢,效率也非常低。
    • 如上所述,有482000个唯一的isbn值,数据被多次下载(例如,在当前编写代码时,每列下载一次)
  • 最好一次下载所有元数据,然后作为一个单独的操作从dict中提取数据
  • 使用try-except块从无效的isbn值捕获错误。
    • 返回一个空的dict{},因为pd.json_normalize不能与NaNNone一起使用
    • 没有必要将isbn列分块
  • pd.json_normalize用于扩展从.meta返回的dict
  • 使用pandas.DataFrame.rename重命名列,使用pandas.DataFrame.drop删除列
  • 此实现将比当前实现快得多,并且对用于获取元数据的API发出的请求将少得多
  • 要从lists中提取值,例如'Authors'列,请使用df_meta = df_meta.explode('Authors');如果有多个作者,则将为列表中的每个其他作者创建一个新行
import pandas as pd  # version 1.1.3
import isbnlib  # version 3.10.3

# sample dataframe
df = pd.DataFrame({'isbn': ['9780446310789', 'abc', '9781491962299', '9781449355722']})

# function with try-except, for invalid isbn values
def get_meta(col: pd.Series) -> dict:
    try:
        return isbnlib.meta(col)
    except isbnlib.NotValidISBNError:
        return {}


# get the meta data for each isbn or an empty dict
df['meta'] = df.isbn.apply(get_meta)

# df
            isbn                                                                                                                                                                                                                                                   meta
0  9780446310789                                                                                   {'ISBN-13': '9780446310789', 'Title': 'To Kill A Mockingbird', 'Authors': ['Harper Lee'], 'Publisher': 'Grand Central Publishing', 'Year': '1988', 'Language': 'en'}
1            abc                                                                                                                                                                                                                                                     {}
2  9781491962299  {'ISBN-13': '9781491962299', 'Title': 'Hands-On Machine Learning With Scikit-Learn And TensorFlow - Techniques And Tools To Build Learning Machines', 'Authors': ['Aurélien Géron'], 'Publisher': "O'Reilly Media", 'Year': '2017', 'Language': 'en'}
3  9781449355722                                                                                                                  {'ISBN-13': '9781449355722', 'Title': 'Learning Python', 'Authors': ['Mark Lutz'], 'Publisher': '', 'Year': '2013', 'Language': 'en'}

# extract all the dicts in the meta column
df = df.join(pd.json_normalize(df.meta)).drop(columns=['meta'])

# extract values from the lists in the Authors column
df = df.explode('Authors')

# df
            isbn        ISBN-13                                                                                                         Title         Authors                 Publisher  Year Language
0  9780446310789  9780446310789                                                                                         To Kill A Mockingbird      Harper Lee  Grand Central Publishing  1988       en
1            abc            NaN                                                                                                           NaN             NaN                       NaN   NaN      NaN
2  9781491962299  9781491962299  Hands-On Machine Learning With Scikit-Learn And TensorFlow - Techniques And Tools To Build Learning Machines  Aurélien Géron            OReilly Media   2017       en
3  9781449355722  9781449355722                                                                                               Learning Python       Mark Lutz                            2013       en

在没有看到代码的情况下很难回答,但是try/except应该真的能够处理这个问题

我不是这里的专家,但看看下面的代码:

l = [0, 1, "a", 2, 3]

for item in l:
    try:
        print(item + 1)
    except TypeError as e:
        print(item, "is not integer")             

如果您尝试使用字符串进行加法,python会讨厌它,并使用TypeError退出。因此,您可以使用except捕获TypeError,并可能报告一些关于它的信息。当我运行此代码时:

1
2
a is not integer  # exception handled!
3
4

您应该能够使用except NotValidISBNError处理异常,然后报告您喜欢的任何元数据

通过异常处理,您可以变得更加复杂,但这是基本思想

相关问题 更多 >

    热门问题