Как вычленить из section h4, p и a и добавить их в парсер?
Итак, на прошлый мой вопрос ответили. Теперь мне бы хотелось бы следующее. Хочу, чтобы из "#contacts" выводились имя (program ['nam']), телефон (program ['tel']) и email (program ['email']). (soup_b.find('h4', {'id': 'content-tab5'})) выводить саму "#contacts", но не элементы. Пробовал воспользоваться find('h4'), но вместо этого выводятся цифры. При попытке сделать find_all выскакивает ошибка "'NoneType' object has no attribute 'find_all'". Как правильно код написать? Скажите, пожалуйста.
Вот сам код.
import json
import codecs
import re
import time
from urllib.parse import quote, unquote
from urllib.request import urlopen
import requests
from bs4 import BeautifulSoup
from sys import getdefaultencoding
import yaml
import requests
import bleach
url = "https://fasie.ru"
page = urlopen(url)
html = page.read().decode("utf-8")
soup = BeautifulSoup(html, "html.parser")
div = soup.find_all('div', class_ = 'wrap')
programms_list = div[1].find('ul', class_='').find_all('ul', class_='')[1]
hrefs = programms_list.find_all('a')
download_links = set()
response = requests.get(url+'/programs')
parse_text = BeautifulSoup(response.text, 'html.parser')
links = set([x.get('href') for x in parse_text.find_all(href=re.compile('^/programs/'))])
programs = []
def main():
for h in hrefs:
program = {}
program['source'] = url
program['name'] = h.text.strip()
url_h = f"https://fasie.ru{h.get('href')}"
page_h = urlopen(url_h)
html_h = page_h.read().decode("utf-8")
soup_h = BeautifulSoup(html_h, "html.parser")
soup_b = BeautifulSoup(html_h, 'lxml')
description = soup_h.find('section', {'id': 'content-tab3'})
program['description'] = description.text.strip().replace('\n', '').replace('\t', '').replace('\r', '') if description else ''
program['program'] = str(soup_h.find('section', {'id': 'content-tab1'}).get_text()).replace('\n', ' ').replace('\t', ' ').replace('\r', ' ')
notag = str(soup_b.find('h4', {'id': 'content-tab5'}))
program['nam']
program['tel']
program['email']
sections = soup_h.find_all('section')
documents = []
for s in sections:
download_links.update(set([x.get('href') for x in s.find_all(href=re.compile('^/upload/docs'))]))
for link in download_links:
file_name = unquote(link).replace('%20', '').split('/')[-1]
response = requests.get(url+quote(link))
with open(file_name, 'wb') as f:
f.write(response.content)
document = {}
document['source'] = url+link.replace('%20', ' ')
document['path'] = file_name
document['name'] = file_name
document['extension'] = file_name.split('.')[-1]
document['size'] = len(response.content)
documents.append(document)
program['documents'] = documents
programs.append(program)
with open('output.json', 'w', encoding="utf-8") as f:
f.write(json.dumps(programs, indent=2, ensure_ascii=False))
main()
Ответы (1 шт):
В данном случае ситуация весьма не однозначная, ведь тег c id content-tab5 не всегда соответствует контактам. А сами контакты хранятся в таблицах и для разных программ структура этой таблицы и названия тегов различаются, где то таблица состоит из тегов td, а где то p. Проще всего с поиском email, ведь для всех программ он храниться в теге a. Для всех остальных данных Вам придётся лучше изучить структуру тегов сайта. Вот код, который в принципе решает Вашу проблему, но Вам нужно внимательно ознакомиться с тем, что он возвращает и как он работает, что бы убедится, что он собирает все данные которые Вас интересуют:
...
try:
notag = soup_b.find('div', class_='tabs').find('section', id='content-tab5').find_all('tr')
except AttributeError:
notag = soup_b.find('div', class_='tabs').find('section', id='content-tab4').find_all('p')
emails = []
names = []
tels = []
for n in notag:
try:
name=[i.text.replace('\n', ' ').replace('\t', ' ').replace('\r', ' ').replace(u'\xa0', u' ').replace(' ', '') for i in n.find_all('h4')]
if name==[]:
name=[i.text.replace('\n', ' ').replace('\t', ' ').replace('\r', ' ').replace(u'\xa0', u' '.replace(' ', '')) for i in n.find_all('b')]
for i in name:
if i==' ':
pass
else:
names.append(i)
email = n.find('a').text.replace('\n', ' ').replace('\t', ' ').replace('\r', ' ').replace(' ', '')
if email=='':
pass
else:
emails.append(email)
tel = [i.text.replace('\n', ' ').replace('\t', ' ').replace('\r', ' ').replace(u'\xa0', u' ').replace(' ', '') for i in n.find_all('nobr')]
for i in tel:
if i=='':
pass
else:
tels.append(i)
except AttributeError:
pass
program['email'] = emails
program['tel'] = tels
program['nam'] = names
print(f"emails - {program['email']}")
print(f"names - {program['nam']}")
print(f"tels - {program['tel']}")
print('-------------------------------------------------------')
...