Я попытался использовать Beautiful Soup для того, чтобы разобрать HTML-код, и у меня возникли проблемы с следующим кодом.
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from html.parser import HTMLParser
from bs4 import BeautifulSoup
results = 20
driver = webdriver.Chrome()
driver.get('https://www.hydroshare.org/search')
element = WebDriverWait(driver,60).until(EC.presence_of_element_located((By.ID, 'items-discovered_wrapper')))
innerHTML = driver.execute_script("return document.body.innerHTML")
soup = BeautifulSoup(innerHTML,'html.parser')
table = soup.find('table',{'id':'items-discovered'})
print (type(table)) # Returns <class 'bs4.element.Tag'
children = table.findchildren() # TypeError: 'NoneType' Object is not callable
Я не могу сказать, почему тип распечатки (таблица) возвращает объект Tag, но затем, когда я пытаюсь запустить table.findchildren() (или любую другую функцию, разрешенную объектом Tag), каким-то образом эта таблица преобразуется в нуль. Я также набрал
print(table)
в результате чего получается строка HTML.
Кто-нибудь знает, почему это происходит или как это работает?
Я не могу сказать, почему printing type (table) возвращает объект Tag
Поскольку type
table
является тегом BS4.
Что касается поиска детей, то функция, которую вы хотите использовать, на самом деле .findChildren()
. Вы просто пропустили капитализацию "C". Итак, что вам действительно нужно в этой последней строке:
children = table.findChildren()
EDIT: Как заметил @abarnert, .findChildren()
технически лишен beautifulsoup4
, однако функция все еще существует. Новый способ получить тот же результат - использовать .find_all()
без указания какого-либо параметра. Обе функции работают и возвращают те же результаты. Поэтому было бы лучше использовать children = table.find_all()
Нет такого метода, как findchildren
, поэтому попытка вызвать это ошибка.
С большинством кода Python вы получаете более ясный AttributeError
говорящий, что findchildren
не существует. Но узлы BS4 имеют такой node.spam
ярлык, где вы можете написать node.spam
вместо node.find('spam')
. Таким образом, он вызывает find('findchildren')
, который возвращает None
, а затем вы пытаетесь назвать None
.
Что касается того, как это исправить... Я не уверен, что вы пытаетесь вызвать здесь (обычно такие ошибки, как этот, кто-то скопировал и вставил некоторый код BS3, который уже устарел в версии 3.0 и не существует в 4.x, но это не так.). Поэтому я могу только предположить, что вы прочитали документы, чтобы найти тот метод, который вам действительно нужен. Существует несколько способов поиска, повторения и т.д. Как непосредственных детей, так и всех потомков, и я предполагаю, что один из них - это то, что вы хотите.
findChildren
- это метод BS3, который сохранен только для упрощенияfindChildren
устаревшего кода. Не рекомендую его для нового кода в BS4.