Вывести при помощи парсера в формат JSON информацию о конкурсах из сайта РФФИ
Снова по парсерам. На этот раз мне нужно спарсить информацию о конкурсах из сайта РФФИ. Вот ссылка: https://www.rfbr.ru/rffi/ru/contest?CONTEST_STATUS_ID=-1&CONTEST_TYPE=-1&CONTEST_YEAR=-1 Нужно спарсить это в формат JSON или XLSX. В парсере должны быть название, дата проведения, статус конкурса (открыт или закрыт) и полное описание. Также должны быть и документы. Собственно, вот как должно получиться.
{
"Название": "",
"Статус": "",
"Время окончания приема заявок": "",
"Полное описание условий конкурса": ""
"Документы":
{
"Формы заявок":
"Договора и инструкции":
"Формы отчетов":
}
},
Я написал первую часть кода. Вот как он выглядит:
import requests
import json
from bs4 import BeautifulSoup
import chardet
import xlsxwriter
PAGES_COUNT = 10
OUT_FILENAME = 'out.json'
OUT_XLSX_FILENAME = 'out.xlsx'
def get_soup(url, **kwargs):
response = requests.get(url, **kwargs)
if response.status_code == 200:
soup = BeautifulSoup(response.text, features='html.parser')
else:
soup = None
return soup
def crawl_products(pages_count):
urls = []
fmt = 'https://www.rfbr.ru/rffi/ru/contest?CONTEST_ITEMS=7&order=2&page={page}'
for page_n in range(1, 1 + pages_count):
print('page: {}'.format(page_n))
page_url = fmt.format(page=page_n)
soup = get_soup(page_url)
if soup is None:
break
for tag in soup.select('.tr .link'):
href = tag.attrs['href']
url = 'https://www.rfbr.ru/rffi/ru/contest{}'.format(href)
urls.append(url)
return urls
def parse_products(urls):
data = []
for url in urls:
print('product: {}'.format(url))
soup = get_soup(url)
if soup is None:
break
name = soup.select_one('a.link').text.strip()
amount = soup.select_one('.ta-c').text.strip()
timestart = soup.select_one('.ta-c').text.strip()
fullrule = soup.select_one('p').text.strip()
item = {
'Название': name,
'Статус': amount,
'Время окончания приема заявок': timestart,
'Полное описание условий конкурса': fullrule,
}
data.append(item)
return data
def dump_to_json(filename, data, **kwargs):
kwargs.setdefault('ensure_ascii', False)
kwargs.setdefault('indent', 1)
with open(OUT_FILENAME, 'w') as f:
json.dump(data, f, **kwargs)
def dump_to_xlsx(filename, data):
if not len(data):
return None
with xlsxwriter.Workbook(filename) as workbook:
ws = workbook.add_worksheet()
bold = workbook.add_format({'bold': True})
headers = ['Название', 'Статус', 'Время окончания приема заявок', 'Полное описание условий конкурса']
for col, h in enumerate(headers):
ws.write_string(0, col, h, cell_format=bold)
for row, item in enumerate(data, start=1):
ws.write_string(row, 0, item['Название'])
ws.write_string(row, 1, item['Статус'])
ws.write_string(row, 2, item['Время окончания приема заявок'])
ws.write_string(row, 3, item['Полное описание условий конкурса'])
def main():
urls = crawl_products(PAGES_COUNT)
data = parse_products(urls)
dump_to_json(OUT_FILENAME, data)
dump_to_xlsx(OUT_XLSX_FILENAME, data)
with open(OUT_FILENAME, 'w') as f:
json.dump(data, f, ensure_ascii=False, indent=1)
if __name__ == '__main__':
main()
В целом, работает. Но... он не выводит то, что отмечено в таблице. А нужно, чтобы выводилось то, что написано в каждой ячейке таблицы в зависимости от столбца. Какой код мне нужно добавить? Что нужно заменить?