Используя BS, перебирая теги, когда строка отсутствует в некоторых итерациях python3 - PullRequest
1 голос
/ 13 апреля 2019

Я пытаюсь использовать 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

Error


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 голосов
/ 13 апреля 2019

ошибка индексации связана с тем, что вы не выбрали () те данные, которые, по вашему мнению, у вас есть. ваш тэг span просто не улавливает все я бы использовал функцию find (), чтобы найти родительский контейнер, а затем перебрать теги, чтобы получить то, что вы хотите, а затем использовать функцию select (), ваш выбор диапазона просто не соответствует тегам, которые вы хотите, протестируйте его, прежде чем задавать вопросы

0 голосов
/ 13 апреля 2019

РЕДАКТИРОВАТЬ: Это использует 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. Просто установите через pip: pip 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...