-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathelibrary_parser_for_search.py
More file actions
150 lines (127 loc) · 5.81 KB
/
elibrary_parser_for_search.py
File metadata and controls
150 lines (127 loc) · 5.81 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import time
import re
import csv
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def open_elibrary_and_search(query):
"""
Открывает elibrary.ru, вводит поисковый запрос,
нажимает Enter для поиска и дожидается первой страницы результатов.
Возвращает объект WebDriver, уже стоящий на странице результатов #1.
"""
chrome_options = Options()
chrome_options.add_argument("--headless")
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get("https://elibrary.ru")
# Ожидаем поле ввода с name='ftext'
search_input = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.NAME, "ftext"))
)
search_input.send_keys(query)
search_input.send_keys(Keys.ENTER)
# Ожидаем появления таблицы с id="restab" (первая страница результатов)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "restab"))
)
time.sleep(1) # небольшая задержка
return driver
def parse_current_page(driver):
"""
Извлекает данные о статьях с текущей страницы, возвращает список словарей.
Каждая статья: title, authors, year, link
"""
soup = BeautifulSoup(driver.page_source, "html.parser")
table = soup.find("table", id="restab")
articles = []
if not table:
return articles
rows = table.find_all("tr", id=True)
for row in rows:
tds = row.find_all("td")
if len(tds) < 2:
continue
cell = tds[1]
# Название и ссылка
link_tag = cell.find("a", href=True)
if not link_tag:
continue
title = link_tag.get_text(strip=True)
link = link_tag["href"]
if link.startswith("/"):
link = "https://elibrary.ru" + link
# Авторы
authors_tag = cell.find("i")
authors = authors_tag.get_text(strip=True) if authors_tag else ""
# Год (первая 4-значная встреча)
text_block = cell.get_text(" ", strip=True)
year_match = re.search(r"\b(19|20)\d{2}\b", text_block)
year = year_match.group(0) if year_match else ""
articles.append({
"title": title,
"authors": authors,
"year": year,
"link": link
})
return articles
def go_to_next_page(driver):
"""
Ищет ссылку или кнопку "Следующая страница" и кликает по ней,
чтобы перейти на следующую страницу. Если удачно перешли, вернёт True,
иначе (ссылки нет) вернёт False.
"""
try:
# Жмем на >> для перехода на новую страницу:
next_link = driver.find_element(By.XPATH, "//a[contains(text(), '>>')]")
next_link.click()
# Ждем таблицу на новой странице,если не успевает загрузиться увеличить время
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "restab"))
)
time.sleep(1)
return True
except:
return False
def scrape_elibrary(query, max_pages=3, headless=False):
"""
- Открывает elibrary.ru, вводит query, жмет Enter.
- Парсит результаты с нескольких страниц (до max_pages или пока не закончится).
- Возвращает список словарей: title, authors, year, link
"""
driver = open_elibrary_and_search(query, headless=headless)
all_articles = []
try:
for page_num in range(1, max_pages+1):
# Парсим текущую страницу
page_data = parse_current_page(driver)
all_articles.extend(page_data)
print(f"Страница {page_num}, найдено статей: {len(page_data)}")
# Пытаемся перейти к следующей странице
ok = go_to_next_page(driver)
if not ok:
print("Следующей страницы нет, останавливаемся.")
break
finally:
driver.quit()
return all_articles
if __name__ == "__main__":
user_query = str(input("Введите запрос для поиска: "))
max_pages = 3 # Сколько страниц парсим
print(f"Поиск по запросу: {user_query}, максимум страниц: {max_pages}")
articles = scrape_elibrary(user_query, max_pages=max_pages, headless=False)
print(f"Всего собрано статей: {len(articles)}")
# Сохраняем в CSV с разделителем ;
with open("articles_semicolon.csv", "w", newline="", encoding="utf-8") as f:
fieldnames = ["title","authors","year","link"]
writer = csv.DictWriter(f, fieldnames=fieldnames, delimiter=';')
writer.writeheader()
for a in articles:
writer.writerow(a)
print("Данные сохранены в 'articles_semicolon.csv' с разделителем ';'")