#python #beautifulsoup
Вопрос:
Я использую python и bs4 для очистки данных github, и я хочу очистить звезды пользователей с помощью этой функции
def total_stars(username):
try:
html = requests.get('https://github.com/' username).text
soup = BeautifulSoup(html, 'html.parser')
total_commit = soup.select_one(
'#js-pjax-container div.container-xl.px-3.px-md-4.px-lg-5 div div.flex-shrink-0.col-12.col-md-3.mb-4.mb-md-0 div div.js-profile-editable-replace div.d-flex.flex-column div.js-profile-editable-area.d-flex.flex-column.d-md-block div.flex-order-1.flex-md-order-none.mt-2.mt-md-0 div a:nth-child(3) span').text
print(total_stars)
return (total_commit)
except:
return (0)
эта функция работала раньше, но теперь она выдает мне ошибку, пожалуйста, если кто-то знает причину и как ее исправить, это будет очень полезно
AttributeError: 'NoneType' object has no attribute 'text'
Спасибо!
Комментарии:
1. Это происходит потому, что страница пользователя Github изменила макет с тех пор, как этот код работал. Почему бы не использовать API REST GitHub вместо очистки HTML?
Ответ №1:
Когда soup.select_one()
вы не можете найти нужный элемент, он возвращается None
.
Итак, ваше исключение исходит из этой строки(посмотрите .text
в конце).:
total_commit = soup.select_one(
'#js-pjax-container div.container-xl.px-3.px-md-4.px-lg-5 div div.flex-shrink-0.col-12.col-md-3.mb-4.mb-md-0 div div.js-profile-editable-replace div.d-flex.flex-column div.js-profile-editable-area.d-flex.flex-column.d-md-block div.flex-order-1.flex-md-order-none.mt-2.mt-md-0 div a:nth-child(3) span').text
Макеты веб-страниц могут измениться в любое время.
Старайтесь использовать идентификаторы как можно чаще. Они вряд ли изменятся (по сравнению с другими селекторами).
Комментарии:
1. как мне напрямую получить идентификаторы на вкладке «Проверка элементов» chrome?
2. @stark Да, найдите элемент там и посмотрите, есть ли у него (или у его ближайшего родителя) идентификатор.
3. это не работает
Ответ №2:
Что происходит?
Что — то странное в вашем образце кода- Кому вы собираетесь звонить? 😉 Вы используете сочетание имен переменных total_commits
, total_stars
и это тяжелое css selector
, что очень сбивает с толку.
Однако элемент, который вы пытаетесь выбрать, не существует или не может быть найден, и вы не смогли вызвать .text
None Type
Как это исправить?
Сделайте это как можно проще, найдите свою цель по href
содержимому tab=stars
и выберите ее <span>
:
soup.select_one('a[href*="tab=stars"] span')
Чтобы избежать каких-либо None Type
ошибок, просто проверьте, существует ли элемент, и получите его текст или установите total_stars
значение 0:
total_stars = soup.select_one('a[href*="tab=stars"] span').text if soup.select_one('a[href*="tab=stars"] span') else 0
Пример
def total_stars(username):
html = requests.get(f'https://github.com/{username}').text
soup = BeautifulSoup(html, 'html.parser')
total_stars = soup.select_one('a[href*="tab=stars"] span').text if soup.select_one('a[href*="tab=stars"] span') else 0
return (total_stars)
total_stars('fabpot')
Выход
188