使用BS,在某些迭代python3中缺少行时循环标记

时间:2019-04-12 21:18:51

标签: python beautifulsoup

我正在尝试使用BS选择带有span-name * = nv标签的项目。但是,最多有2条“ span”行(我想要第二条),并且当缺少第二行时,我的循环返回了一个索引错误,而不仅仅是越过丢失的行。

如何告诉我的循环跳过丢失的行并在索引存在时返回?

https://www.imdb.com/list/ls047677021/


以下作品。但是,如果我将索引从0更改为1(这是我需要的),则会出现索引错误。我知道为什么会收到错误,但我不知道如何解决。

sauce = urllib.request.urlopen('https://www.imdb.com/list/ls047677021/').read()
soup = bs.BeautifulSoup(sauce, 'lxml')


gross=[]

for div in soup.find_all('div', class_='lister-item mode-detail'):
    money = div.select('span[name*=nv]')[0]['data-value']
    gross.append(money)

gross

gross=[]

for div in soup.find_all('div', class_='lister-item mode-detail'):
    money = div.select('span[name*=nv]')[1]['data-value']
    gross.append(money)

 gross

错误


IndexError                                Traceback (most recent call last)
<ipython-input-42-67c1c65a2cce> in <module>
      2 
      3 for div in soup.find_all('div', class_='lister-item mode-detail'):
----> 4     money = div.select('span[name*=nv]')[1]['data-value']
      5     gross.append(money)
      6 

IndexError: list index out of range

https://www.imdb.com/list/ls047677021/

我应该在字典中获取值列表。相反,我得到了一个错误(或者如果我更改了索引)或错误的数据。

2 个答案:

答案 0 :(得分:0)

编辑:这使用的是Beautiful Soup 4.7 +。

就我个人而言,我会进一步缩小选择范围。实际上,您可以使用更好的选择器来仅定位所需的对象。然后,您可以使用select_one,它只会返回您想要的元素。然后,您可以通过查看它是否为None(表示您没有)来检查是否得到它。

您可以通过两种方法获得此信息。首先,我将向您展示CSS级别4中的一项新功能::nth-child(an+b of s)。这将选择与您的选择器匹配的第二个跨度。 https://facelessuser.github.io/soupsieve/selectors/#:nth-child

CSS规范:https://drafts.csswg.org/selectors-4/#the-nth-child-pseudo

gross=[]

for div in soup.find_all('div', class_='lister-item mode-detail'):
    el = div.select_one(':nth-child(2 of span[name*=nv])')
    if el is not None:
        gross.append(el['data-value'])

print(gross)

或者您可以使用自定义:contains伪类将目标定位在Gross:跨度之后。 https://facelessuser.github.io/soupsieve/selectors/#:contains

gross=[]

for div in soup.find_all('div', class_='lister-item mode-detail'):
    el = div.select_one('span:contains("Gross:") + span[name*=nv]')
    if el is not None:
        gross.append(el['data-value'])

print(gross)

输出:

['678,815,482', '700,059,566', '324,591,735', '417,719,760', '145,443,742', '213,515,506', '220,159,104', '137,690,172', '608,581,744', '216,210,777', '216,648,740', '213,767,512', '188,024,361', '51,024,708', '159,555,901', '215,288,866', '117,443,149', '159,342,015', '139,377,762', '120,634,935', '32,732,301', '57,421,715', '46,874,505', '174,532,921', '44,069,456', '335,061,807', '53,542,417', '99,345,950', '59,185,715', '102,084,362', '50,072,235', '69,001,013', '18,095,701', '100,407,760', '44,936,545', '48,686,605', '67,796,355', '54,547,470', '30,014,539', '69,086,325', '17,839,115', '81,903,458', '100,478,608', '99,215,042', '59,839,515', '2,474,044', '167,510,016', '21,704,844', '44,947,622', '115,715,889', '36,108,758', '28,780,744', '11,871,365', '48,795,601', '45,495,662', '1,214,525', '40,826,341', '40,717,020', '32,015,231', '21,023,275', '270,620,950', '33,562,069', '29,819,114', '35,851,379', '34,017,028', '30,824,628', '58,032,443', '50,316,123', '36,343,858', '201,089,881', '31,445,012', '42,402,632', '54,858,851', '171,956,231', '30,569,484', '26,020,957', '14,841,338', '127,195,589', '42,469,946', '30,617,396', '2,523,610', '20,706,452', '6,708,147', '9,227,130', '67,347,895', '52,856,061', '115,253,424', '68,549,695', '77,339,130', '68,566,296']

对于Beautiful Soup 4.6及以下版本,您可以单独安装Beautiful Soup的新选择器库,即使它没有集成在4.6中也可以使用它。只需通过pippip install soupsieve安装即可。

import soupsieve as sv

gross=[]

for div in soup.find_all('div', class_='lister-item mode-detail'):
    el = sv.select_one(':nth-child(2 of span[name*=nv])', div)
    if el is not None:
        gross.append(el['data-value'])

print(gross)

答案 1 :(得分:0)

索引错误是因为您没有选择()您认为拥有的数据。您的span标记无法捕获所有内容。我会使用find()函数查找父容器,然后遍历标签以获取所需内容,然后使用select()函数,您的跨度选择根本不符合您想要的标签,请在对其进行质疑之前对其进行测试< / p>