Несколько классов и IndexError: список индексов вне диапазона ошибок - PullRequest
0 голосов
/ 31 марта 2020

Когда я пытаюсь напечатать пример из класса «предложение», вызывая код ниже

examp3 = soup1.find_all(class_='sentence')
print(examp3[0].get_text())

, это выдаст мне ошибку, как показано ниже

Traceback (most recent call last):
File "/home/hudacse6/WebScrap/webscrap.py", line 33, in <module>
print(examp3[0].get_text())
IndexError: list index out of range 

Вот изображение с веб-страницы, на которую я хочу позвонить и распечатать

class called pic

Как устранить эту ошибку?

Вот мой полный html .parser Code

import requests
from bs4 import BeautifulSoup

page1 = requests.get('https://www.vocabulary.com/dictionary/abet')
page2 = requests.get('https://www.thesaurus.com/browse/cite?s=t')
page3 = requests.get('https://dictionary.cambridge.org/dictionary/english/abet')
page4 = requests.get('https://www.merriam-webster.com/dictionary/abet')

soup1 = BeautifulSoup(page1.content, 'html.parser')
soup2 = BeautifulSoup(page2.content, 'html.parser')
soup3 = BeautifulSoup(page3.content, 'html.parser')
soup4 = BeautifulSoup(page4.content, 'html.parser')

synonyms2 = soup1.find_all(class_='short')
synonyms3 = soup1.find_all(class_='long')
print("Short Description of ABET: ", synonyms2[0].get_text(), "\n", )
print("Brief Description of ABET: ", synonyms3[0].get_text(), "\n", )

syn = soup2.find_all('a', class_='css-18rr30y etbu2a31')
find_syn = [syns.get_text() for syns in syn]
# print(syn[0].get_text())
print("Most relevant Synonyms of ABET: ", find_syn, "\n", )

print("Examples Of ABET: ")

exmp1 = soup3.find_all(class_='eg deg')
print(exmp1[0].get_text())

examp2 = soup4.find_all(class_='mw_t_sp')
print(examp2[0].get_text())

examp3 = soup1.find_all(class_='sentence')
print(examp3[0].get_text())

И я пытался вызывать одновременно несколько классов с одинаковыми именами, чтобы печатать тексты классов, используя приведенный ниже код, но только первый вызванный класс и print. Второй не работает.

 #soup.findAll(True, {'class':['class1', 'class2']}) --Main Code
 examp2 = soup4.findAll(True, {'class': ['mw_t_sp', 'ex-sent first-child t no-aq sents']})
 print(examp2[1].get_text())

Это только для печати

Примеры ABET:

способ совершения преступления

Вот пи c где я это назвал.

enter image description here

В чем проблема с приведенным выше кодом?

1 Ответ

1 голос
/ 31 марта 2020

Страница https://www.vocabulary.com/dictionary/abet загружает содержимое в разделе «Примеры использования», используя javascript.

BeautifulSoup не запускается javascript, как браузер, поэтому запрос get не содержит class_='sentence' элементов.

Ошибка «индекс списка вне диапазона», просто означает, что в списке нет элемента [0].

Возможно, вам потребуется выполнить синтаксический анализ json ответ (см. скриншот) или использование селена, подходы более сложные.

json response

Я могу помочь вам с ответом json.

Полная ссылка для получения ответа de json в соответствии с сетью devTools в chrome выглядит примерно так: https://corpus.vocabulary.com/api/1.0/examples.json?jsonp=jQuery112407918468215082872_1585769422264&query=abet&maxResults=24&startOffset=0&filter=0&_=1585769422265

Мы можем попытаться сделать его короче, упрощая , Эта ссылка работает нормально: https://corpus.vocabulary.com/api/1.0/examples.json?query=abet&maxResults=4

Итак:

import requests
from bs4 import BeautifulSoup
import json

def parse_vocabulary_com_examples (word):

    num_of_examples = 4
    url = "https://corpus.vocabulary.com/api/1.0/examples.json?query=" + word + "&maxResults=" + str(num_of_examples)

    page = requests.get(url)
    soup = BeautifulSoup(page.content, 'html.parser')
    dictionary = json.loads(str(soup))

    for i in range (0,num_of_examples):
        print("------------------------------------------------------")
        print("name:", dictionary["result"]["sentences"][i]["volume"]["corpus"]["name"])
        print("sentence:", dictionary["result"]["sentences"][i]["sentence"])
        print("datePublished:", dictionary["result"]["sentences"][i]["volume"]["dateAdded"][:10])

parse_vocabulary_com_examples("abet")

возвращает:

    ------------------------------------------------------
    name: Scientific American
    sentence: This is aided and abetted both by partisan media sympathizers and by journalists who share misinformation live and correct it later.
    datePublished: 2020-03-25
    ------------------------------------------------------
    name: Fox News
    sentence: That dependence was the result of the CCP’s ruthless tactics, abetted by bad decisions by American policymakers and business people over many years.
    datePublished: 2020-03-25
    ------------------------------------------------------
    name: New York Times
    sentence: The Syrian government bet on and abetted such outcomes.
    datePublished: 2020-03-22
    ------------------------------------------------------
    name: Washington Post
    sentence: We must not aid and abet the CCP’s efforts to stoke internal divisions and spread disinformation.
    datePublished: 2020-03-20

Очевидно, вам нужно интегрировать ее в вашем синтаксическом анализаторе l oop добавление элементов управления ошибками (нет результата, например, нет доступной даты или ограниченные результаты, меньше 4 или нет). Также соблюдайте политику очистки;)

Чтобы найти все вхождения класса:

import requests
from bs4 import BeautifulSoup

page4 = requests.get('https://www.merriam-webster.com/dictionary/abet')
soup4 = BeautifulSoup(page4.content, 'html.parser')
examples = soup4.findAll(True, {'class': 'ex-sent first-child t no-aq sents'})

print("Number of elements found:", len(examples))
for i in examples:
    print("------------------------------------------------------")
    print(i.text.strip())

return:

Number of elements found: 3
----------------------------------------------
abet the commission of a crime
----------------------------------------------
The singer was abetted by a skillful accompanist.
----------------------------------------------
accused of aiding and abetting a criminal

Можно попробовать следующее, но оно возвращает 26 совпадений то есть скрытые результаты под кнопкой «Подробнее». Обратите внимание, что поиск классов теперь является списком, это менее ограниченная форма, и поэтому он получает больше результатов. Кроме того, классы не могут содержать пробелы.

import requests
from bs4 import BeautifulSoup

page4 = requests.get('https://www.merriam-webster.com/dictionary/abet')

soup4 = BeautifulSoup(page4.content, 'html.parser')
examples = soup4.findAll(True, {'class': ['ex-sent', 'first-child', 't', 'no-aq', 'sents']})

print("Number of elements found:", len(examples))
for i in examples:
    print("----------------------------------------------")
    print(i.text.strip())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...