Форум программистов, компьютерный форум, киберфорум
Python: Web
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
1 / 1 / 0
Регистрация: 20.10.2020
Сообщений: 50

Статус в парсере должен определяться автоматически

05.07.2023, 14:41. Показов 975. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть у меня код, который выводит парсер с сайта РФФИ. Причем в двух вариациях. Один из них переходит на ссылку конкурса. Другой - извлекает данные из таблиц со страницы "Конкурсы".

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import requests
import json
from bs4 import BeautifulSoup
import chardet
import xlsxwriter
import re
from datetime import date, timedelta
 
PAGES_COUNT = 1
OUT_FILENAME = 'out.json'
 
import warnings
warnings.filterwarnings("ignore")
 
 
def get_soup(url, **kwargs):
    response = requests.get(url, **kwargs, verify=False)
    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_STATUS_ID=-1&CONTEST_TYPE=-1&CONTEST_YEAR=-1&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
 
        for j in soup.find_all("main", {"class":"template__main"}):
            for jj in j.find_all("div", {"class":"sfc l-3 mt-5 mb-10 lh-xl"}):
                ja = re.sub(r'[^\x00-\x7f]', r'', str(jj))
                jo = re.sub(r'\<[^>]*\>', '', str(ja))
                ji = re.sub(r'_', '', str(jo))
                ju = re.sub(r'  ', '', str(ji))
                je = re.sub(r' :', '', str(ju))
                jy = je[13:]
                amount = jy
        rponse = requests.get(url, verify=False)
        sp = BeautifulSoup(rponse.text, "lxml")
        document = {}
        item = {}
        dcs = sp(attrs={"class": "list-in article"})
        for z in dcs:
            document[z.h2.text] = list(z.ol.stripped_strings)
            # document[z.h2.text] = tuple(z.ol.stripped_strings)
 
        # в одну строку с разделителем запятая
        for z in dcs:
            document[z.h2.text] = ', '.join(z.ol.stripped_strings)
        try:
            article = [l.get_text(strip=True) for l in soup.find_all("p") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        except:
            article = [l.get_text(strip=True) for l in soup.find_all("h3") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        for row in soup.select('td'):
            cols = row.select('td')
            cols = [c.text.strip() for c in cols]
        name = [i.get_text(strip=True) for i in soup.find_all("h1") if i.get_text(strip=True)]
        ame = str(name).replace("['", '').replace("']", '')
        item['Название'] = ame
        item['Статус'] = "Заявки не принимаются"
        item['Время окончания приема заявок'] = amount
        item['Полное описание условий конкурса'] = art
        item['Документы'] = document
        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', encoding="utf-8") as f:
        json.dump(data, f, **kwargs)
 
 
def main():
    urls = crawl_products(PAGES_COUNT)
    data = parse_products(urls)
    dump_to_json(OUT_FILENAME, data)
 
    with open(OUT_FILENAME, 'w', encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=1)
 
 
if __name__ == '__main__':
    main()
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
from bs4 import BeautifulSoup
import re
import os
from urllib.request import urlopen
import json
from urllib.parse import unquote
 
import warnings
warnings.filterwarnings("ignore")
 
BASE_URL = 'https://www.rfbr.ru/rffi/ru/contest'
 
session = requests.Session()
session.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0'
 
items = []
max_page = 82
for page in range(1, max_page + 1):
    url = f'{BASE_URL}/?page={page}' if page > 1 else BASE_URL
    print(url) 
    rs = session.get(url, verify=False)
    rs.raise_for_status() 
    soup = BeautifulSoup(rs.content, 'html.parser')
    for item in soup.select('.tr'):
        number = [d.get_text(strip=True) for d in item if d.get_text(strip=True)].pop(2)
        time = [d.get_text(strip=True) for d in item if d.get_text(strip=True)].pop(3)
        title = item.select_one("img").get('alt')
        items.append({
            'Название': number,
            'Статус': title,
            'Время окончания приема заявок': time,
        })
with open('out2.json', 'w', encoding='utf-8') as f:
    json.dump(items, f, indent=4, ensure_ascii=False)
Все эти коды выводят результаты в JSON

Результат первого кода:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
[
 {
  "Название": "Конкурс на лучшие научные проекты фундаментальных исследований в сфере общественно-политических наук, реализуемые молодыми учеными, проводимый совместно РФФИ и ЭИСИ",
  "Статус": "Заявки не принимаются",
  "Время окончания приема заявок": "15.03.2021 23:59",
  "Полное описание условий конкурса": "много текста",
  "Документы": {
   "Формы заявок": "Форма 4_опн_мол. Содержание проекта, Форма 6_опн. Предварительный бюджет проекта, Форма 1_опн. Данные о проекте, Форма 1en. Данные о проекте на английском языке, Форма 2. Данные о физическом лице, Форма 3. Сведения об Организации",
   "Договор и инструкции": "Инструкция по оформлению и отправке отчёта в КИАС РФФИ, Справочная информация для заполнения приложения «Сведения о выплатах, произведенных организацией...», Инструкция по оформлению договора о предоставлении гранта победителю конкурса и реализации научного проекта, Инструкция по оформлению заявки в КИАС РФФИ, Договор о предоставлении гранта победителю конкурса и реализации научного проекта, Инструкция по подтверждению согласия организации",
   "Формы отчетов": "Форма 503_опн_мол. Развернутый научный отчет по проекту, Форма 501(итог). Краткий научный отчет, Форма 506(итог). Финансовый отчет, Сведения о выплатах, произведенных организацией (DOCX), Краткая версия отчета о реализации научного проекта (DOCX), Форма 512. Данные о члене коллектива, Форма 511. Возможности практического использования результатов, Форма 509. Публикация по результатам проекта, Форма 502(итог). Краткий научный отчет на английском языке"
  }
 },
Результат второго кода
JavaScript
1
2
3
4
5
6
[
    {
        "Название": "Конкурс на лучшие научные проекты фундаментальных исследований в сфере общественно-политических наук, реализуемые молодыми учеными, проводимый совместно РФФИ и ЭИСИ",
        "Статус": "Заявки не принимаются",
        "Время окончания приема заявок": "15.03.2021 23:59"
    },
Вроде бы всё ничего. Но дело в том, что в первом коде массив "Статус" введен вручную. А нужно чтобы он выводил автоматически. То есть, выводил не только значение "Заявки не принимаются", но и "Конкурс завершен", если именно такой статус стоит в таблице. Я пробовал в первый код вставить элементы из второго, которые переключаются сразу на таблицу, а не на страницу того или иного кода. Вроде бы ошибок не было. Но там все время стояло одно и то же значение - "Заявки не принимаются". В иных случаях код просто прекращал работу.

Во втором коде как-раз происходит всё автоматически.

Как правильно перенести элементы из второго кода в первый, чтобы статус конкурса определялся автоматически по таблице?

Ссылки на конкурсы:
https://www.rfbr.ru/rffi/ru/contest
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.07.2023, 14:41
Ответы с готовыми решениями:

Съёмные диски перестали определяться автоматически.
Добрый день. Съёмные диски перестали определяться автоматически. Т.е. подключаю диск (выносной хард, флэшку) ничего не происходит....

Число пересчетов интеграла должно определяться автоматически и напрямую связано с заданной точностью вычислений
public class integral { public static double inIntegral(double x) { return Math.sqrt(1 - (7.0 / 16) * (Math.sin(x) *...

Автоматически Поменять Статус Во View
Здравствуйте! Делаю проект на LotusScript. Есть две формы &quot;Жилье&quot; и &quot;Клиент&quot;. В форме &quot;Жилье&quot; есть поле с номером телефона...

9
32 / 24 / 11
Регистрация: 03.06.2023
Сообщений: 56
05.07.2023, 20:21
Лучший ответ Сообщение было отмечено lochin2 как решение

Решение

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import requests
import json
from bs4 import BeautifulSoup
import re
from datetime import date, timedelta
 
PAGES_COUNT = 1
OUT_FILENAME = 'out.json'
 
import warnings
 
warnings.filterwarnings("ignore")
 
 
def get_soup(url, **kwargs):
    response = requests.get(url, **kwargs, verify=False)
    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_STATUS_ID=-1&CONTEST_TYPE=-1&CONTEST_YEAR=-1&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
 
        for j in soup.find_all("main", {"class": "template__main"}):
            for jj in j.find_all("div", {"class": "sfc l-3 mt-5 mb-10 lh-xl"}):
                ja = re.sub(r'[^\x00-\x7f]', r'', str(jj))
                jo = re.sub(r'\<[^>]*\>', '', str(ja))
                ji = re.sub(r'_', '', str(jo))
                ju = re.sub(r'  ', '', str(ji))
                je = re.sub(r' :', '', str(ju))
                jy = je[13:]
                amount = jy
        rponse = requests.get(url, verify=False)
        sp = BeautifulSoup(rponse.text, "lxml")
        document = {}
        item = {}
        dcs = sp(attrs={"class": "list-in article"})
        for z in dcs:
            document[z.h2.text] = list(z.ol.stripped_strings)
            # document[z.h2.text] = tuple(z.ol.stripped_strings)
 
        # в одну строку с разделителем запятая
        for z in dcs:
            document[z.h2.text] = ', '.join(z.ol.stripped_strings)
        try:
            article = [l.get_text(strip=True) for l in soup.find_all("p") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        except:
            article = [l.get_text(strip=True) for l in soup.find_all("h3") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        for row in soup.select('td'):
            cols = row.select('td')
            cols = [c.text.strip() for c in cols]
        name = [i.get_text(strip=True) for i in soup.find_all("h1") if i.get_text(strip=True)]
        ame = str(name).replace("['", '').replace("']", '')
        p = get_soup('https://www.rfbr.ru/rffi/ru/contest').find(string=ame)
        img_td = p.find_parent().find_parent().find_next_sibling()
        item['Название'] = ame
        item['Статус'] = img_td.select_one("img").get('alt')
        item['Время окончания приема заявок'] = amount
        item['Полное описание условий конкурса'] = art
        item['Документы'] = document
        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', encoding="utf-8") as f:
        json.dump(data, f, **kwargs)
 
 
def main():
    urls = crawl_products(PAGES_COUNT)
    data = parse_products(urls)
    dump_to_json(OUT_FILENAME, data)
 
    with open(OUT_FILENAME, 'w', encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=1)
 
 
if __name__ == '__main__':
    main()
0
1 / 1 / 0
Регистрация: 20.10.2020
Сообщений: 50
06.07.2023, 08:21  [ТС]
Спасибо. Работает. Правда только для одной страницы. А можно для нескольких?
А то у меня возникает ошибка:
Python
1
AttributeError: 'NoneType' object has no attribute 'find_parent'
0
32 / 24 / 11
Регистрация: 03.06.2023
Сообщений: 56
06.07.2023, 08:39
Хм? Можно подробнее, что Вы пытались сделать, когда возникла ошибка?
0
1 / 1 / 0
Регистрация: 20.10.2020
Сообщений: 50
06.07.2023, 08:42  [ТС]
Я просто ввёл для PAGES_COUNT значение 2 вместо 1. Ну чтобы извлекался парсинг из нескольких страниц, а не только из одной.
0
32 / 24 / 11
Регистрация: 03.06.2023
Сообщений: 56
06.07.2023, 09:22
Через минут 30, когда буду за компом, попробую разобраться

Добавлено через 36 минут
Исправил. Правда, пришлось немного изменить результат работы функции "crawl_products" т.к. нужна была страница, на которой находится элемент. Теперь эта функция возвращает список кортежей: [(url, page_n), ...]

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import requests
import json
from bs4 import BeautifulSoup
import re
from datetime import date, timedelta
 
PAGES_COUNT = 2
OUT_FILENAME = 'out.json'
 
import warnings
 
warnings.filterwarnings("ignore")
 
 
def get_soup(url, **kwargs):
    response = requests.get(url, **kwargs, verify=False)
    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_STATUS_ID=-1&CONTEST_TYPE=-1&CONTEST_YEAR=-1&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, page_n))
    return urls
 
 
def parse_products(urls):
    data = []
 
    for url in urls:
        print('product: {}'.format(url[0]))
 
        soup = get_soup(url[0])
        if soup is None:
            break
 
        for j in soup.find_all("main", {"class": "template__main"}):
            for jj in j.find_all("div", {"class": "sfc l-3 mt-5 mb-10 lh-xl"}):
                ja = re.sub(r'[^\x00-\x7f]', r'', str(jj))
                jo = re.sub(r'\<[^>]*\>', '', str(ja))
                ji = re.sub(r'_', '', str(jo))
                ju = re.sub(r'  ', '', str(ji))
                je = re.sub(r' :', '', str(ju))
                jy = je[13:]
                amount = jy
        rponse = requests.get(url[0], verify=False)
        sp = BeautifulSoup(rponse.text, "lxml")
        document = {}
        item = {}
        dcs = sp(attrs={"class": "list-in article"})
        for z in dcs:
            document[z.h2.text] = list(z.ol.stripped_strings)
            # document[z.h2.text] = tuple(z.ol.stripped_strings)
 
        # в одну строку с разделителем запятая
        for z in dcs:
            document[z.h2.text] = ', '.join(z.ol.stripped_strings)
        try:
            article = [l.get_text(strip=True) for l in soup.find_all("p") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        except:
            article = [l.get_text(strip=True) for l in soup.find_all("h3") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        for row in soup.select('td'):
            cols = row.select('td')
            cols = [c.text.strip() for c in cols]
        name = [i.get_text(strip=True) for i in soup.find_all("h1") if i.get_text(strip=True)]
        ame = str(name).replace("['", '').replace("']", '')
        _page = f'?page={url[1]}' if url[1] != 1 else ''
        p = get_soup(f'https://www.rfbr.ru/rffi/ru/contest{_page}').find(string=ame)
        img_td = p.find_parent().find_parent().find_next_sibling()
        item['Название'] = ame
        item['Статус'] = img_td.select_one("img").get('alt')
        item['Время окончания приема заявок'] = amount
        item['Полное описание условий конкурса'] = art
        item['Документы'] = document
        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', encoding="utf-8") as f:
        json.dump(data, f, **kwargs)
 
 
def main():
    urls = crawl_products(PAGES_COUNT)
    data = parse_products(urls)
    dump_to_json(OUT_FILENAME, data)
 
    with open(OUT_FILENAME, 'w', encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=1)
 
 
if __name__ == '__main__':
    main()
0
1 / 1 / 0
Регистрация: 20.10.2020
Сообщений: 50
06.07.2023, 10:32  [ТС]
Спасибо, работает.
Дальше я сам. Можете заниматься другим делом.
0
32 / 24 / 11
Регистрация: 03.06.2023
Сообщений: 56
06.07.2023, 10:57
Кажется, понял в чем ошибка. Вы используете strip=True там, где получаете name. Из-за этого при поиске текста на странице возвращается None, т.к. в первоначальном тексте справа еще есть пробелы (увидел это по одному из примеров и не уверен, что со всеми так, но это точно одна из причин ошибок). Еще я не совсем понимаю, зачем Вы используете replace для получения ame, потому что type(name) возвращает list, то есть Вы можете просто взять нулевой элемент и получить то же самое, вроде. Если это не так, то замените в моем коде 87 строку - item['Название'] = name[0].strip() - на первоначальный вариант, но уже после нахождения статуса, поскольку пробелы важны для его поиска

Добавлено через 2 минуты
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import requests
import json
from bs4 import BeautifulSoup
import re
from datetime import date, timedelta
 
PAGES_COUNT = 7
OUT_FILENAME = 'out.json'
 
import warnings
 
warnings.filterwarnings("ignore")
 
 
def get_soup(url, **kwargs):
    response = requests.get(url, **kwargs, verify=False)
    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_STATUS_ID=-1&CONTEST_TYPE=-1&CONTEST_YEAR=-1&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, page_n))
    return urls
 
 
def parse_products(urls):
    data = []
 
    for url in urls:
        print('product: {}'.format(url[0]))
 
        soup = get_soup(url[0])
        if soup is None:
            break
 
        for j in soup.find_all("main", {"class": "template__main"}):
            for jj in j.find_all("div", {"class": "sfc l-3 mt-5 mb-10 lh-xl"}):
                ja = re.sub(r'[^\x00-\x7f]', r'', str(jj))
                jo = re.sub(r'\<[^>]*\>', '', str(ja))
                ji = re.sub(r'_', '', str(jo))
                ju = re.sub(r'  ', '', str(ji))
                je = re.sub(r' :', '', str(ju))
                jy = je[13:]
                amount = jy
        rponse = requests.get(url[0], verify=False)
        sp = BeautifulSoup(rponse.text, "lxml")
        document = {}
        item = {}
        dcs = sp(attrs={"class": "list-in article"})
        for z in dcs:
            document[z.h2.text] = list(z.ol.stripped_strings)
            # document[z.h2.text] = tuple(z.ol.stripped_strings)
 
        # в одну строку с разделителем запятая
        for z in dcs:
            document[z.h2.text] = ', '.join(z.ol.stripped_strings)
        try:
            article = [l.get_text(strip=True) for l in soup.find_all("p") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        except:
            article = [l.get_text(strip=True) for l in soup.find_all("h3") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        for row in soup.select('td'):
            cols = row.select('td')
            cols = [c.text.strip() for c in cols]
        name = [i.get_text() for i in soup.find_all("h1") if i.get_text(strip=True)]
        _page = f'?page={url[1]}' if url[1] != 1 else ''
        p = get_soup(f'https://www.rfbr.ru/rffi/ru/contest{_page}').find(string=name[0])
        img_td = p.find_parent().find_parent().find_next_sibling()
 
        item['Название'] = name[0].strip()
        item['Статус'] = img_td.select_one("img").get('alt')
        item['Время окончания приема заявок'] = amount
        item['Полное описание условий конкурса'] = art
        item['Документы'] = document
        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', encoding="utf-8") as f:
        json.dump(data, f, **kwargs)
 
 
def main():
    urls = crawl_products(PAGES_COUNT)
    data = parse_products(urls)
    dump_to_json(OUT_FILENAME, data)
 
    with open(OUT_FILENAME, 'w', encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=1)
 
 
if __name__ == '__main__':
    main()
0
1 / 1 / 0
Регистрация: 20.10.2020
Сообщений: 50
06.07.2023, 11:12  [ТС]
Я решил сделать всё иначе, хотя спасибо за совет.
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import requests
import json
from bs4 import BeautifulSoup
import re
from datetime import date, timedelta
 
PAGES_COUNT = 82
OUT_FILENAME = 'out.json'
 
import warnings
 
warnings.filterwarnings("ignore")
 
 
def get_soup(url, **kwargs):
    response = requests.get(url, **kwargs, verify=False)
    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_STATUS_ID=-1&CONTEST_TYPE=-1&CONTEST_YEAR=-1&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, page_n))
    return urls
 
 
def parse_products(urls):
    data = []
 
    for url in urls:
        print('product: {}'.format(url[0]))
 
        soup = get_soup(url[0])
        if soup is None:
            break
 
        for j in soup.find_all("main", {"class": "template__main"}):
            for jj in j.find_all("div", {"class": "sfc l-3 mt-5 mb-10 lh-xl"}):
                ja = re.sub(r'[^\x00-\x7f]', r'', str(jj))
                jo = re.sub(r'\<[^>]*\>', '', str(ja))
                ji = re.sub(r'_', '', str(jo))
                ju = re.sub(r'  ', '', str(ji))
                je = re.sub(r' :', '', str(ju))
                jy = je[13:]
                amount = jy
        rponse = requests.get(url[0], verify=False)
        sp = BeautifulSoup(rponse.text, "lxml")
        document = {}
        item = {}
        dcs = sp(attrs={"class": "list-in article"})
        for z in dcs:
            document[z.h2.text] = list(z.ol.stripped_strings)
            # document[z.h2.text] = tuple(z.ol.stripped_strings)
 
        # в одну строку с разделителем запятая
        for z in dcs:
            document[z.h2.text] = ', '.join(z.ol.stripped_strings)
        try:
            article = [l.get_text(strip=True) for l in soup.find_all("p") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        except:
            article = [l.get_text(strip=True) for l in soup.find_all("h3") if l.get_text(strip=True)]
            art = str(article).replace("['", '').replace("']", '')
        for row in soup.select('td'):
            cols = row.select('td')
            cols = [c.text.strip() for c in cols]
        name = [i.get_text(strip=True) for i in soup.find_all("h1") if i.get_text(strip=True)]
        ame = str(name).replace("['", '').replace("']", '')
        _page = f'?page={url[1]}'
        p = get_soup(f'https://www.rfbr.ru/rffi/ru/contest{_page}')
        for img_td in p.select('.tr'):
            image = img_td.select_one("img").get('title')
        item['Название'] = ame
        item['Статус'] = image
        item['Время окончания приема заявок'] = amount
        item['Полное описание условий конкурса'] = art
        item['Документы'] = document
        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', encoding="utf-8") as f:
        json.dump(data, f, **kwargs)
 
 
def main():
    urls = crawl_products(PAGES_COUNT)
    data = parse_products(urls)
    dump_to_json(OUT_FILENAME, data)
 
    with open(OUT_FILENAME, 'w', encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=1)
 
 
if __name__ == '__main__':
    main()
Не стал использовать find_parents, а воспользовался старым проверенным select
0
32 / 24 / 11
Регистрация: 03.06.2023
Сообщений: 56
06.07.2023, 11:18
Не подумал об этом. Хороший вариант!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.07.2023, 11:18
Помогаю со студенческими работами здесь

Скрипт должен брать из БД токен, и устанавливать пользователю статус на страницу ВКонтакте
Уважаемые форумчани! Недавно стал осваивать php , вот мне понадобилось создать сервис АвтоСтатуса для ВКонтакте! Суть такова:...

как сделать возврат в джейсоне , джейсон должен быть с информацией про действие и статус этого действия
&lt;?php require_once $_SERVER . '/includes/setting.php'; $id = trim(filter_var($_POST, FILTER_SANITIZE_NUMBER_INT)); $first_name...

Размер окна должен автоматически подстраиваться под монитор
Столкнулся с одним вопросом..Вроде же всё в интерфейсе WPF измеряется в условных единицах.. Значит размер окна должен автоматически...

Столбец «рейтинг» в таблице «проекты» должен автоматически высчитываться
Помогите пожалуйста. вопрос жизни и смерти. надо диплом сдать через 3 часа. Столбец «рейтинг» в таблице «проекты» должен автоматически...

Ошибка в парсере
Вот код: #!/usr/bin/env python3 import time from urllib.request import urlopen from urllib.parse import urljoin from...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru