Spaces:
Sleeping
Sleeping
File size: 11,940 Bytes
c2e82db e6219bc be40855 3d5bbcf be40855 3d5bbcf be40855 3d5bbcf c2e82db 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 c2e82db 3d5bbcf c2e82db 97cb158 3d5bbcf c2e82db 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf c2e82db 97cb158 3d5bbcf e6219bc 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 3d5bbcf 97cb158 | 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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | # app.py
import gradio as gr
import sys
import os
import subprocess
import json # Có thể cần nếu script scraper output JSON
# Thêm đường dẫn thư mục hiện tại vào sys.path để Python có thể tìm thấy script scraper
# Điều này hoạt động tốt khi script scraper được import trực tiếp
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# --- Tùy chọn 1: Thử import hàm trực tiếp từ script scraper ---
# Đây là cách ƯU TIÊN nếu script scraper của bạn có hàm dễ gọi (ví dụ: parse_listing)
# Thay thế 'yellowpages' bằng tên file .py thật của script scraper của bạn (KHÔNG có .py)
# Thay thế 'parse_listing_function' bằng tên hàm trong script của bạn nhận keyword và location
yellowpages_script_name = 'yellowpages' # Tên file script không kèm .py
scraper_function_name = 'parse_listing_function' # Tên hàm trong script
scraper_function = None
try:
# Import module (tên file)
scraper_module = __import__(yellowpages_script_name)
# Lấy hàm từ module
scraper_function = getattr(scraper_module, scraper_function_name, None)
if scraper_function is None:
print(f"Cảnh báo: Không tìm thấy hàm '{scraper_function_name}' trong file '{yellowpages_script_name}.py'.")
# Nếu không tìm thấy hàm, scraper_function vẫn là None
else:
print(f"Đã import thành công hàm '{scraper_function_name}' từ '{yellowpages_script_name}.py'.")
except ModuleNotFoundError:
print(f"Cảnh báo: Không tìm thấy file '{yellowpages_script_name}.py'. Sẽ thử chạy bằng subprocess.")
scraper_function = None # Đảm bảo hàm là None nếu import lỗi
except AttributeError:
print(f"Cảnh báo: Lỗi AttributeError khi import hàm '{scraper_function_name}' từ file '{yellowpages_script_name}.py'.")
scraper_function = None
except Exception as e:
print(f"Lỗi không xác định khi import script scraper: {e}")
scraper_function = None
# --- Tùy chọn 2: Hàm chạy script bằng subprocess (Nếu không import được hàm) ---
def run_scraper_via_cli(script_name_with_py, *args):
"""
Chạy script scraper như một tiến trình con từ dòng lệnh.
Args:
script_name_with_py: Tên file script bao gồm đuôi .py (ví dụ: 'yellowpages.py').
*args: Các đối số dòng lệnh cần truyền cho script.
Returns:
Output từ script (stdout) hoặc thông báo lỗi.
"""
print(f"Đang thử chạy script '{script_name_with_py}' qua command line với args: {args}")
try:
# Lệnh để chạy script
# subprocess.run sẽ tìm script trong PYTHONPATH hoặc PATH.
# Do đã thêm thư mục hiện tại vào sys.path, hy vọng python có thể tìm thấy script_name_with_py
command = [sys.executable, script_name_with_py] + list(args) # sys.executable đảm bảo dùng đúng python
print(f"Lệnh chạy: {' '.join(command)}")
result = subprocess.run(
command,
capture_output=True,
text=True, # Bắt output dưới dạng text
check=False # KHÔNG báo lỗi nếu script trả về mã lỗi khác 0, chỉ bắt output/error
)
# Kiểm tra mã trả về (return code)
if result.returncode != 0:
# Nếu có lỗi khi chạy script (ví dụ: lỗi cú pháp trong script, lỗi runtime trong script)
print(f"Script '{script_name_with_py}' trả về mã lỗi {result.returncode}")
print(f"Stderr:\n{result.stderr}")
print(f"Stdout:\n{result.stdout}")
# Cố gắng trả về lỗi từ stderr hoặc stdout
return f"Lỗi khi chạy script '{script_name_with_py}' (code {result.returncode}):\n{result.stderr or result.stdout or 'Không có thông báo lỗi cụ thể.'}"
# Trả về output chuẩn của script
# Script có thể in kết quả trực tiếp hoặc in JSON/CSV
print(f"Script '{script_name_with_py}' chạy thành công.")
print(f"Stdout:\n{result.stdout}")
# Có thể cần xử lý result.stdout ở đây nếu script in ra dữ liệu cấu trúc (JSON)
return result.stdout # Trả về toàn bộ stdout
except FileNotFoundError:
# Lỗi này xảy ra nếu 'python' hoặc 'script_name_with_py' không tìm thấy
# Lỗi 'script_name_with_py' không tìm thấy đã được báo ở trên nếu dùng import
# Nhưng vẫn giữ lại đây để an toàn
return f"Lỗi: Không tìm thấy file script '{script_name_with_py}' để chạy. Vui lòng đảm bảo file đã được upload."
except Exception as e:
# Các lỗi khác không mong muốn
import traceback
traceback.print_exc()
return f"Đã xảy ra lỗi không xác định khi chạy subprocess: {e}"
# Hàm chính được gọi từ Gradio interface
def scrape_data(scraper_choice, input1, input2=None):
"""
Hàm này nhận lựa chọn scraper và các input tương ứng, sau đó gọi phương thức cạo phù hợp.
"""
if scraper_choice == "Yellow Pages":
if not input1 or not input2:
return "Vui lòng nhập cả Từ khóa tìm kiếm và Địa điểm cho Yellow Pages."
print(f"Yêu cầu cạo Yellow Pages: Từ khóa='{input1}', Địa điểm='{input2}'")
# Ưu tiên dùng hàm import nếu có
if scraper_function:
print("Đang chạy bằng cách import hàm trực tiếp...")
try:
scraped_data = scraper_function(input1, input2)
# Định dạng kết quả từ list of dicts sang string
output_text = "Kết quả từ Yellow Pages:\n\n"
if not scraped_data:
return output_text + "Không tìm thấy kết quả nào."
# Nếu hàm trả về list of dicts, định dạng nó
if isinstance(scraped_data, list) and all(isinstance(item, dict) for item in scraped_data):
for i, item in enumerate(scraped_data):
output_text += f"--- {i+1} ---\n"
# Điều chỉnh các key này ('business_name', 'telephone', v.v.)
# để phù hợp với các key mà script scraper của bạn sử dụng
output_text += f"Name: {item.get('business_name', 'N/A')}\n"
output_text += f"Phone: {item.get('telephone', 'N/A')}\n"
output_text += f"Address: {item.get('street', 'N/A')}, {item.get('locality', 'N/A')}, {item.get('region', 'N/A')} {item.get('zipcode', 'N/A')}\n"
output_text += f"Website: {item.get('website', 'N/A')}\n"
output_text += f"Rating: {item.get('rating', 'N/A')}\n"
output_text += f"Rank: {item.get('rank', 'N/A')}\n"
output_text += f"URL: {item.get('url', 'N/A')}\n"
output_text += "------------\n"
return output_text
else:
# Nếu hàm trả về dạng khác (ví dụ: string báo lỗi)
return f"Kết quả trực tiếp từ hàm scraper:\n{scraped_data}"
except Exception as e:
import traceback
traceback.print_exc()
return f"Lỗi xảy ra khi gọi hàm scraper trực tiếp: {e}"
else:
# Nếu không import được hàm, dùng subprocess để chạy file .py
print("Đang chạy bằng subprocess...")
# Đảm bảo tên file đúng và đối số truyền vào phù hợp với script CLI
# Đối với script yellowpages.py trong repo ScrapeDataCom, cú pháp CLI có thể là:
# python yellowpages.py "keyword" "location"
return run_scraper_via_cli(f"{yellowpages_script_name}.py", input1, input2)
# --- Thêm các trường hợp cho scraper khác tại đây ---
# elif scraper_choice == "Google Search":
# if not input1:
# return "Vui lòng nhập Từ khóa tìm kiếm cho Google Search."
# print(f"Yêu cầu cạo Google Search: Từ khóa='{input1}'")
# # Cần tích hợp logic gọi script Google Search tương tự Yellow Pages
# # Ví dụ: return run_scraper_via_cli("googlesearch_results.py", input1)
# return "Chức năng Google Search chưa được tích hợp hoàn chỉnh."
#
# elif scraper_choice == "Amazon":
# if not input1:
# return "Vui lòng nhập URL sản phẩm hoặc từ khóa cho Amazon."
# print(f"Yêu cầu cạo Amazon: Input='{input1}'")
# # Cần tích hợp logic gọi script Amazon
# # Ví dụ: return run_scraper_via_cli("amazon_products.py", input1) # Giả định script Amazon nhận 1 đối số
# return "Chức năng Amazon chưa được tích hợp hoàn chỉnh."
else:
return "Vui lòng chọn một Scraper từ danh sách."
# Tạo giao diện Gradio
with gr.Blocks() as demo:
gr.Markdown("# Demo Các Web Scraper từ ScrapeDataCom")
gr.Markdown("Chọn một scraper và nhập các thông tin cần thiết. Kết quả sẽ hiển thị bên dưới.")
scraper_dropdown = gr.Dropdown(
["Yellow Pages"], # Thêm tên các scraper khác vào list này sau khi tích hợp
label="Chọn Scraper",
value="Yellow Pages" # Giá trị mặc định
)
# Các input fields. Có thể cần điều chỉnh hiển thị dựa trên lựa chọn dropdown
input_keyword = gr.Textbox(label="Từ khóa", placeholder="Ví dụ: restaurants")
input_location = gr.Textbox(label="Địa điểm", placeholder="Ví dụ: Boston,MA")
# input_generic = gr.Textbox(label="Input (URL hoặc Từ khóa)", placeholder="Nhập URL hoặc từ khóa tùy scraper", visible=False) # Input chung
run_button = gr.Button("Chạy Scraper")
output_text = gr.Textbox(label="Kết quả", lines=20, max_lines=50, interactive=False) # interactive=False để không cho chỉnh sửa
# Định nghĩa hành động khi nút được nhấn
run_button.click(
scrape_data,
inputs=[scraper_dropdown, input_keyword, input_location], # Truyền tất cả các input tiềm năng
outputs=output_text
)
# Ví dụ về cách thay đổi hiển thị input dựa trên dropdown (có thể phức tạp tùy vào số lượng scraper)
# def update_inputs(choice):
# if choice == "Yellow Pages":
# return gr.update(visible=True, label="Từ khóa"), gr.update(visible=True, label="Địa điểm"), gr.update(visible=False)
# elif choice == "Google Search":
# return gr.update(visible=True, label="Từ khóa"), gr.update(visible=False), gr.update(visible=False) # Giả sử Google chỉ cần từ khóa
# # Thêm các trường hợp khác
# return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True, label=f"Input cho {choice}") # Default case
#
# scraper_dropdown.change(
# update_inputs,
# inputs=scraper_dropdown,
# outputs=[input_keyword, input_location, input_generic] # Liệt kê tất cả input có thể thay đổi
# )
# Chạy ứng dụng Gradio
# Trong Hugging Face Space, dòng này sẽ tự động được gọi
# Khi chạy cục bộ, nó sẽ mở giao diện trong trình duyệt
iface = demo # Gán demo cho iface để tương thích với iface.launch() nếu cần, hoặc chỉ dùng demo.launch()
demo.launch() |