#python #if-statement #web-scraping #beautifulsoup
#python #if-statement #очистка веб-страниц #beautifulsoup
Вопрос:
Я пытаюсь найти и распечатать все теги h3, которые содержат интересующие меня месяцы. Для этого я попытался создать цикл for для моего объекта bs4( head
), и оператор if внутри него указывает на печать строки, которая удовлетворяет условию; что в данном случае было бы, если строка (месяц) находится в строке. Проблема, с которой я сталкиваюсь, заключается в том, что даже если указанные мной месяцы существуют в объекте / строках bs4, они не печатаются в моем операторе if.
Я попытался добавить год к месяцам, и это, казалось, решило проблему, хотя и не идеально. Кроме того, я протестировал логику своего метода, составив краткий список некоторых строк (вручную) и запустив цикл for с этим списком вместо объекта bs4( head
)
import requests
from bs4 import BeautifulSoup
page=requests.get('https://www.england.nhs.uk/statistics/statistical-work-areas/delayed-transfers-of-care/statistical-work-areas-delayed-transfers-of-care-delayed-transfers-of-care-data-2018-19/')
soup=BeautifulSoup(page.text,'html.parser')
text=soup.find(class_='rich-text')
head = text.find_all('h3')
for row in head:
for r1 in ['January','February']:
if r1 in row:
print(row)
else:
continue
Ожидаемые результаты
<h3>February 2019</h3>
<h3>January 2019</h3>
Результаты, которые я получаю, не существуют, поскольку ничего не распечатывается
Комментарии:
1. используйте
row.text
вместо этого, посколькуrow
это не строка
Ответ №1:
Это потому row
, что это не строковый тип, но это <class 'bs4.element.Tag'>
. Следовательно in
, проверка завершается неудачей.
Один обходной путь будет приведен к строке в проверке:
if r1 in str(row): # or row.text
Код:
for row in head:
for r1 in ['January','February']:
if r1 in str(row): # or row.text
print(row)
Я целенаправленно избегал else
to if
, потому что это не служит никакой цели.
Необязательно,
for row in head:
if any(r1 in row.text for r1 in ['January','February']):
print(row)
Комментарии:
1. Привет, Остин, спасибо за ответ, хотя я не уверен, почему работает код, который я изначально опубликовал, когда я добавляю year в список в моем операторе if, на данный момент строка по-прежнему является объектом bs4, а не строкой. Только когда я убираю год, он не может найти условие.
Ответ №2:
Другой способ получения ежемесячных публикаций DTOC с использованием bs4 4.7.1
import requests
from bs4 import BeautifulSoup as bs
url = 'https://www.england.nhs.uk/statistics/statistical-work-areas/delayed-transfers-of-care/statistical-work-areas-delayed-transfers-of-care-delayed-transfers-of-care-data-2018-19/'
r = requests.get(url)
soup = bs(r.content, 'lxml')
publications = [item.next_sibling.next_sibling.text for item in soup.select('#main-content p:has( h3)')][1:]
print(publications)
Для страницы:
#main-content p:has( h3)
фильтры для p
тегов с родительским элементом, имеющим id main-content
, которые имеют соседний h3
тег родственного элемента. [1:]
Игнорирует первый элемент в возвращаемом списке, поскольку это не месяц, а Statistical Press Notice
заголовок
Комментарии:
1. Не могли бы вы объяснить, как вы фильтруете публикации с помощью next_sibling, я пытался сделать это в обычном цикле for, включая next_sibling в каждую итерацию, но, похоже, это не работает, я получаю полный раздел, возвращающий, а не публикации
2. Я полностью понимаю, к чему вы клоните, но я изо всех сил пытаюсь понять, как
:has()
работает селектор css. Я понимаюh3
, что это даст нам следующий<h3>
тег, но я не уверен, как указание<p>
должно включать следующий<h3>
тег. Правильно ли я предполагаю, что происходит:has()
проверка тегаh3
, можно ли выполнить с любым из<p>
тегов, которые у нас были в нашем html, и если это возможно, то он будет соответствовать этим<p>
тегам?3. выберите только теги p, которые имеют (имеют) соседний тег h3 developer.mozilla.org/en-US/docs/Web/CSS/:has
4. итак, я попробовал ту же логику
soup.select('#main-content h3:has( a)')[2:]
, но я заменил p на тег h3, а соседний тег h3 на тег a. Но когда я пытаюсь напечатать что-нибудь вроде элемента или следующего родственного элемента в цикле for, я получаю пустое.5. все еще DTOCs ежемесячно? кстати, я работаю с этими файлами каждый второй четверг месяца 🙂