Download app.py from jay-analytics/Keyword_Ranking_System: direct link, hf CLI and curl.
- Browser
- Download file 4.83 kB
-
https://huggingface.co/spaces/jay-analytics/Keyword_Ranking_System/resolve/main/app.py
- Command line
-
hf download hf://spaces/jay-analytics/Keyword_Ranking_System/app.py
-
curl -L -o app.py https://huggingface.co/spaces/jay-analytics/Keyword_Ranking_System/resolve/main/app.py
4.83 kB
| import time | |
| import requests | |
| import pandas as pd | |
| import gradio as gr | |
| import os | |
| from urllib.parse import urlparse | |
| # ===================================================== | |
| # CONFIGURATION (HF SAFE) | |
| # ===================================================== | |
| HASDATA_API_KEY = os.getenv("HASDATA_API_KEY") # ✅ From Hugging Face Secrets | |
| HASDATA_ENDPOINT = "https://api.hasdata.com/scrape/google/serp" | |
| TARGET_DOMAIN = "rishabhsoft.com" | |
| COUNTRY = "us" # "us" or "in" | |
| LANGUAGE = "en" | |
| LOCATION = "United States" if COUNTRY == "us" else "India" | |
| MAX_PAGES = 10 # Top 100 | |
| RESULTS_PER_PAGE = 10 | |
| SLEEP_TIME = 1 | |
| if not HASDATA_API_KEY: | |
| raise ValueError("HASDATA_API_KEY is missing. Add it in Hugging Face Secrets.") | |
| # ===================================================== | |
| # HELPERS | |
| # ===================================================== | |
| def normalize_domain(url: str) -> str: | |
| try: | |
| return urlparse(url).netloc.replace("www.", "").lower() | |
| except Exception: | |
| return "" | |
| # ===================================================== | |
| # CORE RANK CHECK | |
| # ===================================================== | |
| def check_domain_rank(keyword: str) -> pd.DataFrame: | |
| keyword = keyword.strip() | |
| results = [] | |
| headers = { | |
| "x-api-key": HASDATA_API_KEY | |
| } | |
| for page in range(MAX_PAGES): | |
| start = page * RESULTS_PER_PAGE | |
| params = { | |
| "q": keyword, | |
| "gl": COUNTRY, | |
| "hl": LANGUAGE, | |
| "domain": "google.com", | |
| "location": LOCATION, | |
| "start": start, | |
| "num": RESULTS_PER_PAGE, | |
| "deviceType": "desktop" | |
| } | |
| response = requests.get( | |
| HASDATA_ENDPOINT, | |
| headers=headers, | |
| params=params, | |
| timeout=30 | |
| ) | |
| if response.status_code != 200: | |
| print(f"API Error [{response.status_code}]: {response.text}") | |
| break | |
| data = response.json() | |
| organic_results = ( | |
| data.get("organic_results") | |
| or data.get("organicResults") | |
| or [] | |
| ) | |
| for idx, item in enumerate(organic_results, start=1): | |
| url = item.get("link") or item.get("url") or "" | |
| if not url: | |
| continue | |
| domain = normalize_domain(url) | |
| if domain.endswith(TARGET_DOMAIN): | |
| results.append({ | |
| "Keyword": keyword, | |
| "Domain": f"https://www.{TARGET_DOMAIN}/", | |
| "Page": page + 1, | |
| "Position on Page": idx, | |
| "Absolute Rank": start + idx, | |
| "URL": url, | |
| "Title": item.get("title") | |
| }) | |
| if results: | |
| break | |
| time.sleep(SLEEP_TIME) | |
| if results: | |
| return pd.DataFrame(results) | |
| return pd.DataFrame([{ | |
| "Keyword": keyword, | |
| "Domain": f"https://www.{TARGET_DOMAIN}/", | |
| "Page": "Not Found", | |
| "Position on Page": "Not Found", | |
| "Absolute Rank": "Not Found", | |
| "URL": None, | |
| "Title": "Not ranking in top 100" | |
| }]) | |
| # ===================================================== | |
| # BULK EXCEL HANDLER | |
| # ===================================================== | |
| def run_bulk_excel(file): | |
| if file is None: | |
| return None, None | |
| df = pd.read_excel(file) | |
| if "keyword" not in df.columns: | |
| raise ValueError("Excel must contain a 'keyword' column") | |
| all_results = [] | |
| for kw in df["keyword"].dropna().unique(): | |
| all_results.append(check_domain_rank(str(kw))) | |
| final_df = pd.concat(all_results, ignore_index=True) | |
| output_file = "hasdata_keyword_ranking.xlsx" | |
| final_df.to_excel(output_file, index=False) | |
| return final_df, output_file | |
| # ===================================================== | |
| # GRADIO UI | |
| # ===================================================== | |
| with gr.Blocks(title="Hasdata Google Rank Checker") as demo: | |
| gr.Markdown("## 🔍 Google Keyword Rank Checker (Hasdata)") | |
| gr.Markdown(f"**Target Domain:** https://www.{TARGET_DOMAIN}/") | |
| gr.Markdown(f"**Country:** {COUNTRY.upper()} | **Device:** Desktop") | |
| excel_input = gr.File( | |
| label="Upload Excel (.xlsx) with 'keyword' column", | |
| file_types=[".xlsx"] | |
| ) | |
| run_btn = gr.Button("Check Rankings") | |
| output_table = gr.Dataframe( | |
| headers=[ | |
| "Keyword", | |
| "Domain", | |
| "Page", | |
| "Position on Page", | |
| "Absolute Rank", | |
| "URL", | |
| "Title" | |
| ], | |
| wrap=True | |
| ) | |
| download_file = gr.File(label="Download Result Excel") | |
| run_btn.click( | |
| fn=run_bulk_excel, | |
| inputs=excel_input, | |
| outputs=[output_table, download_file] | |
| ) | |
| demo.queue() | |
| demo.launch() | |