|
import requests |
|
from bs4 import BeautifulSoup |
|
import streamlit as st |
|
|
|
|
|
def load_css(): |
|
st.markdown(""" |
|
<style> |
|
body { |
|
font-family: Arial, sans-serif; |
|
background-color: #f8f9fa; |
|
} |
|
.search-bar { |
|
width: 50%; |
|
margin: 20px auto; |
|
display: flex; |
|
align-items: center; |
|
border: 1px solid #dfe1e5; |
|
border-radius: 24px; |
|
padding: 10px; |
|
background-color: #fff; |
|
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1); |
|
} |
|
.search-bar input { |
|
flex: 1; |
|
border: none; |
|
outline: none; |
|
font-size: 16px; |
|
padding: 5px; |
|
} |
|
.search-bar button { |
|
background: none; |
|
border: none; |
|
color: #4285f4; |
|
font-size: 18px; |
|
cursor: pointer; |
|
} |
|
.search-result { |
|
margin: 20px auto; |
|
width: 80%; |
|
padding: 15px; |
|
border: 1px solid #dfe1e5; |
|
border-radius: 8px; |
|
background-color: #fff; |
|
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1); |
|
} |
|
.search-result h3 { |
|
margin: 0; |
|
color: #1a0dab; |
|
font-size: 18px; |
|
} |
|
.search-result p { |
|
margin: 5px 0; |
|
color: #545454; |
|
font-size: 14px; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
def search_google(query, proxy=None): |
|
headers = { |
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' |
|
} |
|
url = f'https://www.google.com/search?q={query.replace(" ", "+")}&hl=en' |
|
proxies = {"http": proxy, "https": proxy} if proxy else None |
|
response = requests.get(url, headers=headers, proxies=proxies, timeout=10) |
|
if "detected unusual traffic" in response.text.lower(): |
|
return None, True |
|
return response.text, False |
|
|
|
|
|
def parse_search_results(html_content): |
|
soup = BeautifulSoup(html_content, 'html.parser') |
|
results = [] |
|
for g in soup.find_all('div', class_='tF2Cxc'): |
|
title = g.find('h3').text if g.find('h3') else "No title" |
|
link = g.find('a')['href'] if g.find('a') else "No link" |
|
snippet = g.find('span', class_='aCOpRe').text if g.find('span', class_='aCOpRe') else "No snippet" |
|
results.append({'title': title, 'link': link, 'snippet': snippet}) |
|
return results |
|
|
|
|
|
def main(): |
|
st.set_page_config(page_title="Google Search Clone with Secure Navigation", layout="centered") |
|
load_css() |
|
|
|
st.markdown('<div class="search-bar">', unsafe_allow_html=True) |
|
query = st.text_input("Enter your search query:", label_visibility="collapsed") |
|
search_button = st.button("Search") |
|
st.markdown('</div>', unsafe_allow_html=True) |
|
|
|
if search_button and query.strip(): |
|
with st.spinner("Searching..."): |
|
html_content, captcha_detected = search_google(query) |
|
|
|
if captcha_detected: |
|
st.error("CAPTCHA detected. Please try again later or reduce search frequency.") |
|
return |
|
|
|
if html_content: |
|
search_results = parse_search_results(html_content) |
|
for result in search_results: |
|
st.markdown(f""" |
|
<div class="search-result"> |
|
<h3><a href="{result['link']}" target="_blank">{result['title']}</a></h3> |
|
<p>{result['snippet']}</p> |
|
<a href="/safe_preview?url={result['link']}" target="_self">Secure Preview</a> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
if "safe_preview" in st.query_params: |
|
url = st.query_params.get("url", [None])[0] |
|
if url: |
|
try: |
|
response = requests.get(url, timeout=10) |
|
if response.status_code == 200: |
|
st.write(f"### Preview of: {url}") |
|
st.code(response.text[:2000], language='html') |
|
else: |
|
st.error(f"Failed to fetch the website. Status code: {response.status_code}") |
|
except Exception as e: |
|
st.error(f"Error fetching the website: {str(e)}") |
|
|
|
if __name__ == "__main__": |
|
main() |