Kims12 commited on
Commit
c131937
·
verified ·
1 Parent(s): d90cf0f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -23
app.py CHANGED
@@ -17,8 +17,10 @@ def scrap_naver_news(keyword):
17
  4) HTML 표로 정리
18
  5) BytesIO -> 임시파일로 저장 -> 다운로드 가능하도록 반환
19
  6) 신문사 "언론사 선정" 문구 제거
20
- 7) 엑셀 data URI 링크를 추가로 생성하여 HTML에 삽입
 
21
  """
 
22
  debug_msgs = []
23
 
24
  base_url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&ssc=tab.news.all&query="
@@ -32,30 +34,51 @@ def scrap_naver_news(keyword):
32
 
33
  soup = BeautifulSoup(response.text, "html.parser")
34
 
35
- # div.news_area 내부에 기사 정보가 존재(요청 예시 구조 참고)
36
  news_list = soup.select("div.news_area")
37
  debug_msgs.append(f"[디버그] news_area 추출 개수: {len(news_list)}")
38
 
39
  results = []
40
 
41
  for idx, news in enumerate(news_list):
42
- # 신문사
 
 
43
  try:
44
- press = news.select_one(".info.press").get_text(strip=True)
45
  # "언론사 선정" 문구 제거
46
- press = press.replace("언론사 선정", "").strip()
47
  except:
48
- press = "확인불가"
49
 
50
- # 날짜/발행일
 
 
 
51
  try:
52
  info_group = news.select_one(".info_group")
53
  info_all = info_group.select(".info")
54
- date = info_all[-1].get_text(strip=True) if info_all else "확인불가"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  except:
56
- date = "확인불가"
57
 
58
- # 제목 & 링크
 
 
59
  try:
60
  title_elem = news.select_one(".news_tit")
61
  title = title_elem.get("title", "").strip()
@@ -64,18 +87,21 @@ def scrap_naver_news(keyword):
64
  title = "제목확인불가"
65
  link = ""
66
 
67
- # 뉴스 간략정보
 
 
68
  try:
69
  desc_elem = news.select_one(".news_dsc .api_txt_lines")
70
  desc = desc_elem.get_text(strip=True) if desc_elem else "내용확인불가"
71
  except:
72
  desc = "내용확인불가"
73
 
74
- debug_msgs.append(f"[디버그] {idx+1}번째 기사 파싱결과 -> 신문사: {press}, 발행일: {date}, 제목: {title}, 링크: {link}")
75
 
 
76
  results.append({
77
- "신문사": press,
78
- "발행일": date,
79
  "제목": title,
80
  "뉴스간략정보": desc,
81
  "링크": link
@@ -104,7 +130,7 @@ def scrap_naver_news(keyword):
104
  table_html += f"<td style='padding: 5px;'>{row['발행일']}</td>"
105
  table_html += f"<td style='padding: 5px;'>{row['제목']}</td>"
106
  table_html += f"<td style='padding: 5px;'>{row['뉴스간략정보']}</td>"
107
- # 링크 클릭 능하도록 a 태그 삽입
108
  table_html += f"<td style='padding: 5px;'><a href='{row['링크']}' target='_blank'>바로가기</a></td>"
109
  table_html += "</tr>"
110
 
@@ -114,9 +140,27 @@ def scrap_naver_news(keyword):
114
  """
115
 
116
  # ------------------------------
117
- # 엑셀(Excel) 생성
 
 
 
 
118
  # ------------------------------
119
- df = pd.DataFrame(results)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  output_io = BytesIO()
121
  with pd.ExcelWriter(output_io, engine="openpyxl") as writer:
122
  df.to_excel(writer, index=False, sheet_name="네이버뉴스")
@@ -130,12 +174,10 @@ def scrap_naver_news(keyword):
130
  debug_msgs.append(f"[디버그] 엑셀 임시파일 생성 완료 -> {tmp_path}")
131
 
132
  # ------------------------------
133
- # 엑셀 다운로드 data URI 생성
134
  # ------------------------------
135
- # 다시 output_io 포인터를 처음으로 되돌려 base64 생성
136
  output_io.seek(0)
137
  excel_data_base64 = base64.b64encode(output_io.getvalue()).decode()
138
- # 클릭 시 다운로드(또는 Excel로 열기) 링크
139
  excel_download_html = f"""
140
  <br>
141
  <a
@@ -148,7 +190,7 @@ def scrap_naver_news(keyword):
148
  </a>
149
  """
150
 
151
- # table_html 뒤에 엑셀 다운로드 링크 추가
152
  table_html += excel_download_html
153
 
154
  return table_html, tmp_path, debug_msgs
@@ -165,7 +207,7 @@ def run_search(keyword):
165
  if file_path is None:
166
  return table_html, None, "\n".join(debug_info)
167
 
168
- # Gradio의 File 출력
169
  return table_html, file_path, "\n".join(debug_info)
170
 
171
  def launch_app():
@@ -184,7 +226,7 @@ def launch_app():
184
  # 엑셀 다운로드 (Gradio File 컴포넌트)
185
  download_file = gr.File(label="엑셀 다운로드")
186
 
187
- # 디버그 메
188
  debug_box = gr.Textbox(label="디버그 로그", lines=10)
189
 
190
  # 버튼 동작 정의
 
17
  4) HTML 표로 정리
18
  5) BytesIO -> 임시파일로 저장 -> 다운로드 가능하도록 반환
19
  6) 신문사 "언론사 선정" 문구 제거
20
+ 7) 발행일이 '네버뉴스'로 잘못 표기되는 경우 개선 (필요한 텍스트만 가져오기)
21
+ 8) 엑셀 파일 내 링크를 클릭 시 바로 이동 가능하도록 HYPERLINK 공식 적용
22
  """
23
+
24
  debug_msgs = []
25
 
26
  base_url = "https://search.naver.com/search.naver?sm=tab_hty.top&where=news&ssc=tab.news.all&query="
 
34
 
35
  soup = BeautifulSoup(response.text, "html.parser")
36
 
37
+ # div.news_area 내부에 기사 정보가 존재
38
  news_list = soup.select("div.news_area")
39
  debug_msgs.append(f"[디버그] news_area 추출 개수: {len(news_list)}")
40
 
41
  results = []
42
 
43
  for idx, news in enumerate(news_list):
44
+ # ------------------------------------------------------------------
45
+ # [1] 신문사
46
+ # ------------------------------------------------------------------
47
  try:
48
+ press_text = news.select_one(".info.press").get_text(strip=True)
49
  # "언론사 선정" 문구 제거
50
+ press_text = press_text.replace("언론사 선정", "").strip()
51
  except:
52
+ press_text = "확인불가"
53
 
54
+ # ------------------------------------------------------------------
55
+ # [2] 발행일 (네이버뉴스 등 불필요한 항목 제외)
56
+ # ------------------------------------------------------------------
57
+ date_text = "확인불가"
58
  try:
59
  info_group = news.select_one(".info_group")
60
  info_all = info_group.select(".info")
61
+ # 왼쪽부터 순서대로 확인하며 '언론사 선정', '네이버뉴스', a 태그(링크) 등은 건너뛰고
62
+ # 최초로 만나는 나머지 텍스트를 발행일로 간주
63
+ for info_item in info_all:
64
+ t = info_item.get_text(strip=True)
65
+ # 건너뛸 조건
66
+ if "언론사 선정" in t:
67
+ continue
68
+ if "네이버뉴스" in t:
69
+ continue
70
+ # a 태그는 press 링크, 네이버뉴스 링크 등인 경우가 많으므로 건너뜀
71
+ if info_item.name == "a":
72
+ continue
73
+ # 여기까지 왔다면 날짜일 가능성이 높음
74
+ date_text = t
75
+ break
76
  except:
77
+ pass
78
 
79
+ # ------------------------------------------------------------------
80
+ # [3] 제목 & 기사 링크
81
+ # ------------------------------------------------------------------
82
  try:
83
  title_elem = news.select_one(".news_tit")
84
  title = title_elem.get("title", "").strip()
 
87
  title = "제목확인불가"
88
  link = ""
89
 
90
+ # ------------------------------------------------------------------
91
+ # [4] 뉴스 간략정보
92
+ # ------------------------------------------------------------------
93
  try:
94
  desc_elem = news.select_one(".news_dsc .api_txt_lines")
95
  desc = desc_elem.get_text(strip=True) if desc_elem else "내용확인불가"
96
  except:
97
  desc = "내용확인불가"
98
 
99
+ debug_msgs.append(f"[디버그] {idx+1}번째 기사 파싱결과 -> 신문사: {press_text}, 발행일: {date_text}, 제목: {title}, 링크: {link}")
100
 
101
+ # 결과 리스트에 담기
102
  results.append({
103
+ "신문사": press_text,
104
+ "발행일": date_text,
105
  "제목": title,
106
  "뉴스간략정보": desc,
107
  "링크": link
 
130
  table_html += f"<td style='padding: 5px;'>{row['발행일']}</td>"
131
  table_html += f"<td style='padding: 5px;'>{row['제목']}</td>"
132
  table_html += f"<td style='padding: 5px;'>{row['뉴스간략정보']}</td>"
133
+ # HTML에서 링크 바로
134
  table_html += f"<td style='padding: 5px;'><a href='{row['링크']}' target='_blank'>바로가기</a></td>"
135
  table_html += "</tr>"
136
 
 
140
  """
141
 
142
  # ------------------------------
143
+ # [엑셀(Excel) 생성 및 링크 클릭 가능 처리]
144
+ # ------------------------------
145
+ # 1) DataFrame 생성
146
+ # 2) '링크' 열에 엑셀 하이퍼링크 공식 삽입
147
+ # 예) =HYPERLINK("http://기사링크", "바로가기")
148
  # ------------------------------
149
+ df_list = []
150
+ for row in results:
151
+ # 엑셀용 링크(클릭 시 바로 이동)
152
+ excel_link_formula = f'=HYPERLINK("{row["링크"]}", "바로가기")'
153
+ df_list.append({
154
+ "신문사": row["신문사"],
155
+ "발행일": row["발행일"],
156
+ "제목": row["제목"],
157
+ "뉴스간략정보": row["뉴스간략정보"],
158
+ "링크": excel_link_formula # Excel 공식
159
+ })
160
+
161
+ df = pd.DataFrame(df_list)
162
+
163
+ # BytesIO에 저장
164
  output_io = BytesIO()
165
  with pd.ExcelWriter(output_io, engine="openpyxl") as writer:
166
  df.to_excel(writer, index=False, sheet_name="네이버뉴스")
 
174
  debug_msgs.append(f"[디버그] 엑셀 임시파일 생성 완료 -> {tmp_path}")
175
 
176
  # ------------------------------
177
+ # Gradio UI에서 직접 다운로드 가능한 data URI(선택사항)
178
  # ------------------------------
 
179
  output_io.seek(0)
180
  excel_data_base64 = base64.b64encode(output_io.getvalue()).decode()
 
181
  excel_download_html = f"""
182
  <br>
183
  <a
 
190
  </a>
191
  """
192
 
193
+ # 테이블 HTML 뒤에 다운로드 링크 추가
194
  table_html += excel_download_html
195
 
196
  return table_html, tmp_path, debug_msgs
 
207
  if file_path is None:
208
  return table_html, None, "\n".join(debug_info)
209
 
210
+ # Gradio의 File 컴포넌트 출력
211
  return table_html, file_path, "\n".join(debug_info)
212
 
213
  def launch_app():
 
226
  # 엑셀 다운로드 (Gradio File 컴포넌트)
227
  download_file = gr.File(label="엑셀 다운로드")
228
 
229
+ # 디버그 메
230
  debug_box = gr.Textbox(label="디버그 로그", lines=10)
231
 
232
  # 버튼 동작 정의