|
|
import gradio as gr |
|
|
import requests |
|
|
import re |
|
|
import json |
|
|
from urllib.parse import urlparse, urljoin |
|
|
import time |
|
|
import random |
|
|
|
|
|
|
|
|
CONTACTS_DB = [ |
|
|
{ |
|
|
"id": 1, |
|
|
"first_name": "Sarah", |
|
|
"last_name": "Chen", |
|
|
"email": "sarah.chen@techflowsolutions.com", |
|
|
"phone": "+1-555-0101", |
|
|
"job_title": "CTO", |
|
|
"company": "TechFlow Solutions", |
|
|
"website": "https://techflowsolutions.com" |
|
|
}, |
|
|
{ |
|
|
"id": 2, |
|
|
"first_name": "Marcus", |
|
|
"last_name": "Rodriguez", |
|
|
"email": "m.rodriguez@techflowsolutions.com", |
|
|
"phone": "+1-555-0102", |
|
|
"job_title": "Senior Developer", |
|
|
"company": "TechFlow Solutions", |
|
|
"website": "https://techflowsolutions.com" |
|
|
}, |
|
|
{ |
|
|
"id": 3, |
|
|
"first_name": "Emma", |
|
|
"last_name": "Thompson", |
|
|
"email": "emma@greenleafconsult.com", |
|
|
"phone": "+1-555-0201", |
|
|
"job_title": "Managing Partner", |
|
|
"company": "GreenLeaf Consulting", |
|
|
"website": "https://greenleafconsult.com" |
|
|
}, |
|
|
{ |
|
|
"id": 4, |
|
|
"first_name": "David", |
|
|
"last_name": "Park", |
|
|
"email": "david.park@greenleafconsult.com", |
|
|
"phone": "+1-555-0202", |
|
|
"job_title": "Environmental Analyst", |
|
|
"company": "GreenLeaf Consulting", |
|
|
"website": "https://greenleafconsult.com" |
|
|
}, |
|
|
{ |
|
|
"id": 5, |
|
|
"first_name": "Jessica", |
|
|
"last_name": "Williams", |
|
|
"email": "jessica@blueskymarketing.net", |
|
|
"phone": "+1-555-0301", |
|
|
"job_title": "Creative Director", |
|
|
"company": "BlueSky Marketing", |
|
|
"website": "https://blueskymarketing.net" |
|
|
}, |
|
|
{ |
|
|
"id": 6, |
|
|
"first_name": "Ryan", |
|
|
"last_name": "Mitchell", |
|
|
"email": "ryan.mitchell@blueskymarketing.net", |
|
|
"phone": "+1-555-0302", |
|
|
"job_title": "Account Manager", |
|
|
"company": "BlueSky Marketing", |
|
|
"website": "https://blueskymarketing.net" |
|
|
}, |
|
|
{ |
|
|
"id": 7, |
|
|
"first_name": "Lisa", |
|
|
"last_name": "Zhang", |
|
|
"email": "l.zhang@quantumdynamics.org", |
|
|
"phone": "+1-555-0401", |
|
|
"job_title": "Research Director", |
|
|
"company": "Quantum Dynamics Corp", |
|
|
"website": "https://quantumdynamics.org" |
|
|
}, |
|
|
{ |
|
|
"id": 8, |
|
|
"first_name": "Ahmed", |
|
|
"last_name": "Hassan", |
|
|
"email": "ahmed.hassan@quantumdynamics.org", |
|
|
"phone": "+1-555-0402", |
|
|
"job_title": "Quantum Engineer", |
|
|
"company": "Quantum Dynamics Corp", |
|
|
"website": "https://quantumdynamics.org" |
|
|
}, |
|
|
{ |
|
|
"id": 9, |
|
|
"first_name": "Maria", |
|
|
"last_name": "Gonzalez", |
|
|
"email": "maria@stellarlogistics.biz", |
|
|
"phone": "+1-555-0501", |
|
|
"job_title": "Operations Manager", |
|
|
"company": "Stellar Logistics", |
|
|
"website": "https://stellarlogistics.biz" |
|
|
}, |
|
|
{ |
|
|
"id": 10, |
|
|
"first_name": "James", |
|
|
"last_name": "O'Connor", |
|
|
"email": "james.oconnor@stellarlogistics.biz", |
|
|
"phone": "+1-555-0502", |
|
|
"job_title": "Fleet Coordinator", |
|
|
"company": "Stellar Logistics", |
|
|
"website": "https://stellarlogistics.biz" |
|
|
}, |
|
|
{ |
|
|
"id": 11, |
|
|
"first_name": "Robert", |
|
|
"last_name": "Kim", |
|
|
"email": "robert.kim@nexusfinancial.pro", |
|
|
"phone": "+1-555-0601", |
|
|
"job_title": "Senior Advisor", |
|
|
"company": "Nexus Financial", |
|
|
"website": "https://nexusfinancial.pro" |
|
|
}, |
|
|
{ |
|
|
"id": 12, |
|
|
"first_name": "Catherine", |
|
|
"last_name": "Lee", |
|
|
"email": "catherine@nexusfinancial.pro", |
|
|
"phone": "+1-555-0602", |
|
|
"job_title": "Investment Analyst", |
|
|
"company": "Nexus Financial", |
|
|
"website": "https://nexusfinancial.pro" |
|
|
}, |
|
|
{ |
|
|
"id": 13, |
|
|
"first_name": "Michael", |
|
|
"last_name": "Johnson", |
|
|
"email": "m.johnson@horizonhealth.care", |
|
|
"phone": "+1-555-0701", |
|
|
"job_title": "Chief Medical Officer", |
|
|
"company": "Horizon Health Systems", |
|
|
"website": "https://horizonhealth.care" |
|
|
}, |
|
|
{ |
|
|
"id": 14, |
|
|
"first_name": "Jennifer", |
|
|
"last_name": "Adams", |
|
|
"email": "jennifer.adams@horizonhealth.care", |
|
|
"phone": "+1-555-0702", |
|
|
"job_title": "Head Nurse", |
|
|
"company": "Horizon Health Systems", |
|
|
"website": "https://horizonhealth.care" |
|
|
}, |
|
|
{ |
|
|
"id": 15, |
|
|
"first_name": "Tony", |
|
|
"last_name": "Ricci", |
|
|
"email": "tony.ricci@phoenixmfg.com", |
|
|
"phone": "+1-555-0801", |
|
|
"job_title": "Plant Manager", |
|
|
"company": "Phoenix Manufacturing", |
|
|
"website": "https://phoenixmfg.com" |
|
|
}, |
|
|
{ |
|
|
"id": 16, |
|
|
"first_name": "Linda", |
|
|
"last_name": "Martinez", |
|
|
"email": "linda.martinez@phoenixmfg.com", |
|
|
"phone": "+1-555-0802", |
|
|
"job_title": "Quality Control Supervisor", |
|
|
"company": "Phoenix Manufacturing", |
|
|
"website": "https://phoenixmfg.com" |
|
|
}, |
|
|
{ |
|
|
"id": 17, |
|
|
"first_name": "Patricia", |
|
|
"last_name": "White", |
|
|
"email": "patricia.white@alpineeducation.edu", |
|
|
"phone": "+1-555-0901", |
|
|
"job_title": "Director of Programs", |
|
|
"company": "Alpine Education Group", |
|
|
"website": "https://alpineeducation.edu" |
|
|
}, |
|
|
{ |
|
|
"id": 18, |
|
|
"first_name": "Kevin", |
|
|
"last_name": "Brown", |
|
|
"email": "kevin.brown@alpineeducation.edu", |
|
|
"phone": "+1-555-0902", |
|
|
"job_title": "Curriculum Specialist", |
|
|
"company": "Alpine Education Group", |
|
|
"website": "https://alpineeducation.edu" |
|
|
}, |
|
|
{ |
|
|
"id": 19, |
|
|
"first_name": "Sophia", |
|
|
"last_name": "Taylor", |
|
|
"email": "sophia@crimsoncreative.studio", |
|
|
"phone": "+1-555-1001", |
|
|
"job_title": "Art Director", |
|
|
"company": "Crimson Creative Studio", |
|
|
"website": "https://crimsoncreative.studio" |
|
|
}, |
|
|
{ |
|
|
"id": 20, |
|
|
"first_name": "Alex", |
|
|
"last_name": "Cooper", |
|
|
"email": "alex.cooper@crimsoncreative.studio", |
|
|
"phone": "+1-555-1002", |
|
|
"job_title": "Graphic Designer", |
|
|
"company": "Crimson Creative Studio", |
|
|
"website": "https://crimsoncreative.studio" |
|
|
} |
|
|
] |
|
|
|
|
|
def extract_domain(url): |
|
|
"""Extract domain from URL""" |
|
|
try: |
|
|
parsed = urlparse(url) |
|
|
domain = parsed.netloc.lower() |
|
|
|
|
|
if domain.startswith('www.'): |
|
|
domain = domain[4:] |
|
|
return domain |
|
|
except: |
|
|
return "" |
|
|
|
|
|
def find_contacts_by_website(website_url): |
|
|
"""Find contacts that match the website domain""" |
|
|
target_domain = extract_domain(website_url) |
|
|
if not target_domain: |
|
|
return [] |
|
|
|
|
|
print(f"Searching for domain: {target_domain}") |
|
|
|
|
|
matching_contacts = [] |
|
|
for contact in CONTACTS_DB: |
|
|
contact_domain = extract_domain(contact['website']) |
|
|
print(f"Comparing with: {contact_domain}") |
|
|
|
|
|
|
|
|
if target_domain == contact_domain or target_domain in contact_domain or contact_domain in target_domain: |
|
|
matching_contacts.append(contact) |
|
|
|
|
|
print(f"Found {len(matching_contacts)} matching contacts") |
|
|
return matching_contacts |
|
|
|
|
|
def simulate_website_scraping(url): |
|
|
"""Simulate scraping a website and finding contact information""" |
|
|
|
|
|
time.sleep(random.uniform(1, 2)) |
|
|
|
|
|
|
|
|
contacts = find_contacts_by_website(url) |
|
|
|
|
|
|
|
|
|
|
|
return contacts |
|
|
|
|
|
def search_website_contacts(website_url, max_results=10): |
|
|
"""Main function to search for contacts on a website""" |
|
|
if not website_url: |
|
|
return "Please enter a website URL", "" |
|
|
|
|
|
|
|
|
if not website_url.startswith(('http://', 'https://')): |
|
|
website_url = 'https://' + website_url |
|
|
|
|
|
try: |
|
|
|
|
|
contacts = simulate_website_scraping(website_url) |
|
|
|
|
|
if not contacts: |
|
|
return f"No contacts found on {website_url}. \n\nThis website is not in our contact database. Try one of the sample websites listed below, or the website might not have publicly available contact information.", "" |
|
|
|
|
|
|
|
|
contacts = contacts[:max_results] |
|
|
|
|
|
|
|
|
results_text = f"Found {len(contacts)} contacts on {website_url}:\n\n" |
|
|
|
|
|
contact_data = [] |
|
|
for i, contact in enumerate(contacts, 1): |
|
|
results_text += f"**Contact {i}:**\n" |
|
|
results_text += f"β’ First Name: {contact['first_name']}\n" |
|
|
results_text += f"β’ Last Name: {contact['last_name']}\n" |
|
|
results_text += f"β’ Job Title: {contact['job_title']}\n" |
|
|
results_text += f"β’ Email: {contact['email']}\n" |
|
|
results_text += f"β’ Phone: {contact['phone']}\n" |
|
|
results_text += f"β’ Company: {contact['company']}\n\n" |
|
|
|
|
|
|
|
|
contact_data.append([ |
|
|
contact['first_name'], |
|
|
contact['last_name'], |
|
|
contact['job_title'], |
|
|
contact['email'], |
|
|
contact['phone'], |
|
|
contact['company'] |
|
|
]) |
|
|
|
|
|
|
|
|
table_text = "First Name,Last Name,Job Title,Email,Phone,Company\n" |
|
|
for contact in contacts: |
|
|
table_text += f"{contact['first_name']},{contact['last_name']},{contact['job_title']},{contact['email']},{contact['phone']},{contact['company']}\n" |
|
|
|
|
|
return results_text, table_text |
|
|
|
|
|
except Exception as e: |
|
|
return f"Error searching website: {str(e)}", "" |
|
|
|
|
|
def get_all_available_websites(): |
|
|
"""Get list of all available websites from the database""" |
|
|
websites = list(set([contact['website'] for contact in CONTACTS_DB])) |
|
|
return "\n".join(sorted(websites)) |
|
|
|
|
|
|
|
|
with gr.Blocks(title="Website Contact Finder", theme=gr.themes.Soft()) as app: |
|
|
gr.HTML(""" |
|
|
<div style="text-align: center; padding: 20px;"> |
|
|
<h1>π Website Contact Finder</h1> |
|
|
<p>Search any website to find contact information including names, job titles, phone numbers, and emails</p> |
|
|
</div> |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(scale=2): |
|
|
website_input = gr.Textbox( |
|
|
label="Website URL", |
|
|
placeholder="Enter website URL (e.g., techflowsolutions.com or https://greenleafconsult.com)", |
|
|
value="" |
|
|
) |
|
|
|
|
|
max_results = gr.Slider( |
|
|
minimum=1, |
|
|
maximum=20, |
|
|
value=5, |
|
|
step=1, |
|
|
label="Maximum Results" |
|
|
) |
|
|
|
|
|
search_btn = gr.Button("π Search Contacts", variant="primary", size="lg") |
|
|
|
|
|
with gr.Column(scale=1): |
|
|
gr.HTML(""" |
|
|
<div style="background: #f0f0f0; padding: 15px; border-radius: 10px;"> |
|
|
<h3>π‘ Tips:</h3> |
|
|
<ul> |
|
|
<li>Enter any website URL</li> |
|
|
<li>Works with or without https://</li> |
|
|
<li>Try our sample websites below</li> |
|
|
<li>Results include full contact details</li> |
|
|
</ul> |
|
|
</div> |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
results_display = gr.Textbox( |
|
|
label="Contact Results", |
|
|
lines=15, |
|
|
max_lines=30, |
|
|
show_copy_button=True |
|
|
) |
|
|
|
|
|
csv_output = gr.Textbox( |
|
|
label="CSV Format (Copy & Paste into Excel)", |
|
|
lines=15, |
|
|
max_lines=30, |
|
|
show_copy_button=True |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Accordion("π Available Sample Websites", open=False): |
|
|
sample_websites = gr.Textbox( |
|
|
label="Sample Websites from Database", |
|
|
value=get_all_available_websites(), |
|
|
lines=10, |
|
|
interactive=False |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Row(): |
|
|
gr.HTML("<h3>π Quick Search Sample Websites:</h3>") |
|
|
|
|
|
with gr.Row(): |
|
|
quick_btn1 = gr.Button("TechFlow Solutions", size="sm") |
|
|
quick_btn2 = gr.Button("GreenLeaf Consulting", size="sm") |
|
|
quick_btn3 = gr.Button("BlueSky Marketing", size="sm") |
|
|
quick_btn4 = gr.Button("Quantum Dynamics", size="sm") |
|
|
|
|
|
with gr.Row(): |
|
|
quick_btn5 = gr.Button("Stellar Logistics", size="sm") |
|
|
quick_btn6 = gr.Button("Nexus Financial", size="sm") |
|
|
quick_btn7 = gr.Button("Horizon Health", size="sm") |
|
|
quick_btn8 = gr.Button("Phoenix Manufacturing", size="sm") |
|
|
|
|
|
|
|
|
search_btn.click( |
|
|
fn=search_website_contacts, |
|
|
inputs=[website_input, max_results], |
|
|
outputs=[results_display, csv_output] |
|
|
) |
|
|
|
|
|
|
|
|
quick_btn1.click(lambda: "techflowsolutions.com", outputs=website_input) |
|
|
quick_btn2.click(lambda: "greenleafconsult.com", outputs=website_input) |
|
|
quick_btn3.click(lambda: "blueskymarketing.net", outputs=website_input) |
|
|
quick_btn4.click(lambda: "quantumdynamics.org", outputs=website_input) |
|
|
quick_btn5.click(lambda: "stellarlogistics.biz", outputs=website_input) |
|
|
quick_btn6.click(lambda: "nexusfinancial.pro", outputs=website_input) |
|
|
quick_btn7.click(lambda: "horizonhealth.care", outputs=website_input) |
|
|
quick_btn8.click(lambda: "phoenixmfg.com", outputs=website_input) |
|
|
|
|
|
|
|
|
gr.Examples( |
|
|
examples=[ |
|
|
["techflowsolutions.com", 5], |
|
|
["https://greenleafconsult.com", 3], |
|
|
["blueskymarketing.net", 2], |
|
|
["quantumdynamics.org", 4] |
|
|
], |
|
|
inputs=[website_input, max_results] |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
app.launch() |