Задать вопрос
@RG2

Как сделать так, чтобы в парсере выводилось определённое количество массивов contacts?

Есть код, который производит парсинг в JSON.
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
from string import ascii_letters
from array import *
import numpy as np


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 = {}
        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['source'] = url_h
        program['name'] = h.text.strip()
        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', ' ')
        try:
            notag = soup_b.find('section', id='content-tab5').find_all('tr') 
        except AttributeError:
            notag = soup_b.find('section', id='content-tab4').find_all('p')
        for n in notag:
            nams = []
            tels = []
            emails = []

            nam=[i.get_text(strip=True) for i in n.find_all('h4')]
            if nam==[]:
                nam=[i.get_text(strip=True) for i in n.find_all('b')]
            for i in nam:
                if i==' ':
                    pass
                else:
                    nams.append(i)
            email=[i.get_text(strip=True) for i in n.find_all('a')]
            for i in email:
                if i==' ':
                    pass
                else:
                    emails.append(i)
            tel=[i.get_text(strip=True) for i in n.find_all('nobr')]
            if tel==[]:
                number=[i.get_text(strip=True) for i in n.find_all('td')]
                gal=re.sub("[^0123456789\()+-]", '', str(number)).replace('[^a-zA-Z ]', '').replace('.', ' ').replace(')', ') ').replace('00() 0', '').encode('ascii', 'ignore').decode()
                tel=[gal]
            for i in tel:
                if i=='':
                    pass
                else:
                    tels.append(i)

        contact = {}   
        contact['namе'] = nams
        contact['email'] = emails
        contact['tel'] = tels
        program['contacts'] = contact
            

        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()


Нужно, чтобы в JSON был выведен парсер вот такого типа
[
  {
    "source": "Ссылка, откуда взята информация", // в данном случае ссылка fasie.ru
    "name": "ИнноШкольник",
    "description": "Информация из вкладки `О программе`",
    "program": "Данные из вкладки `Конкурсы, программы` в формате HTML",
    "contacts": [
      {
        "name": "Имя контакта",
        "tel": "Телефон",
        "email": "Почта контакта"
      }
    ],
    "documents": [
      {
        "source": "Ссылка на файл оригинальная, т.е откуда скачали",
        "path": "Относительный путь к файлу (уже скачанного)",
        "name": "Название файла",
        "extension": "Расширение файла (напр. pdf)",
        "size": 123 // Размер в байтах
      }
    ]
  }
]

Однако у меня есть проблема. Выводится только один контакт (ФИО, телефон и email). Вот пример:
{
    "source": "https://fasie.ru/programs/programma-umnik/",
    "name": "УМНИК",
    "description": "Сроки приема заявок и проведения конкурсов в рамках программы «УМНИК» устанавливаются отдельно для каждого региона. Подробная информация о мероприятиях и сроках их проведения по соответствующему региону представлена на сайте umnik.fasie.ru.",
    "program": "     Программа направлена на поддержку коммерчески ориентированных научно-технических проектов молодых исследователей.    Принимать участие в конкурсе по данной программе могут физические лица, от 18 до 30 лет включительно, являющиеся гражданами РФ, и ранее не побеждавшие в программе.    Параметры поддержки:    размер гранта – 500 тыс. рублей; срок выполнения НИР – не более 12 месяцев (2 этапа по 6 месяцев); направление расходов – проведение НИР.   Ожидаемые результаты:    подана заявка на регистрацию прав на результаты интеллектуальной деятельности, созданные в рамках выполнения НИР; разработан бизнес-план инновационного проекта либо подана заявка на участие в программе Фонда «Студенческий стартап»;  пройдена преакселерационная программа на базе организации, включенной в реестр аккредитованных Фондом преакселераторов, с целью проработки перспектив коммерческого использования результатов НИР;  составлена дорожная карта проекта.    При недостижении плановых показателей Фонд вправе потребовать возврата средств гранта.       Подробная информация о программе представлена в разделе «Документы» ",
    "contacts": {
      "namе": [
        "Киселев Виталий Юрьевич"
      ],
      "email": [
        "kiselev.vyu@fasie.ru"
      ],
      "tel": [
        "(495) 249-249-2189"
      ]
    },

Мне нужно, чтобы были выведены столько контактов, сколько они есть на каждой странице в каждом "#kontaktu". Как это сделать?
P.S. Команду print() не предлагать. Нужно, чтобы было выведено в файл output.json, а не в консоль.
  • Вопрос задан
  • 99 просмотров
Подписаться 1 Средний 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы