Ok, I can do that. I was hoping if it was a generic issue that what I posted would be enough; if not, no worries…
here is the entire views.py file →
from django.shortcuts import render
from django.http import HttpResponse, Http404, HttpResponseRedirect
from .apis.weather.weather import location, weather
from .apis.news.news import articles
from .classes.search import SearchEngine
# from .classes.search import search_query
from .config import MAIN_MENU
engine = SearchEngine()
def index(request):
template = 'searchnet/index.html'
context = {
"location": location,
"weather": weather,
"menu": MAIN_MENU,
}
return render(request, template, context)
def search(request):
search_string = request.GET.get('search-for')
search_results = engine.google(search_string)
template = 'searchnet/results.html'
context = {
"location": location,
"weather": weather,
"menu": MAIN_MENU,
"search_results": search_results[:10],
"side_results": search_string[::-1],
}
# return HttpResponseRedirect(reverse('searchnet:results', args=(search_string,)))
return render(request, template, context)
def category(request, category_name):
template = 'searchnet/category.html'
context = {
"location": location,
"weather": weather,
"menu": MAIN_MENU,
"content": category_name,
}
return render(request, template, context)
Here’s the entire urls.py →
from django.urls import path
from . import views
app_name = 'searchnet'
urlpatterns = [
path('', views.index, name='index'),
path('search/', views.search, name='search'),
path('category/<str:category_name>/', views.category, name='category'),
]
Here’s results.html →
{% extends 'searchnet/base.html' %}
<!-- weather -->
{% block weather %}
<div class="text-color-third">{{ weather }} in {{ location }}</div>
{% endblock weather %}
<!-- register -->
{% block register %}
<a class="btn btn-sm btn-outline-secondary" href="#">Register</a>
{% endblock register %}
<!-- menu -->
{% block menu %}
<div class="nav-scroller py-1 mb-2">
<nav class="nav d-flex justify-content-between">
{% for category in menu %}
<a class="p-2 text-color-primary" href="{% url 'searchnet:category' category %}">{{ category }}</a>
{% endfor %}
</nav>
</div>
{% endblock menu %}
<!-- search -->
{% block search %}
<form action="{% url 'searchnet:search' %}" method="GET" class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3">
<input type="search" name="search-for" class="form-control" placeholder="Search.. " aria-label="Search">
</form>
{% endblock search %}
<!-- results -->
{% block front %}
<table class="results-table col-12 py-4">
<thead>
<tr>
<th><h4>Mainstream: </h4></th>
<th><h4>Sidestream: </h4></th>
</tr>
</thead>
<tbody>
{% for result in search_results %}
<tr class="results-row">
<td class="mainstream-data">
<div class="mainstream-content">
<p><a href="{{ result.url }}">{{ result.url }}</a></p>
<a href="{{ result.url }}">{{ result.title }}</a>
<p class="result-description">{{ result.description }}</p>
</div>
</td>
<td class="sidestream-data"><a href="">{{ side_results }}</a></td>
</tr>
<tr class="spacer-row"></tr>
{% endfor %}
</tbody>
</table>
{% endblock front %}
and index.html is exactly the same as results.html except the front block, which is →
{% block front %}
<div class="content-sidebar my-5">
<div class="row col-9">
<div class="row">
<div class="col-6 p-0">
<img src="{{ articles.2.urlToImage }}" alt="image pertaining to article" width=460 height=275><br />
</div>
<div class="col-4 p-2 bg-light">
<a href="{{ articles.2.url }}"><h5 class="text-color-black text-center">
{{ articles.2.title }}
</h5></a>
<a href="{{ articles.2.url }}">
<p class="text-size-16 text-center">{{ articles.2.description|slice:":160" }}...[To Source]</p>
</a>
</div>
</div>
<div class="row">
{% for article in articles|slice:"11:16" %}
<div class="card col-2 p-0" style="width: 153" >
<img class="card-img-top" src="{{ article.urlToImage }}" alt="Card image cap" width=153 height=76>
<div class="card-body">
<a href="{{ article.url }}"><h6 class="card-title text-size-14 text-weight-bold text-color-black text-center" data-bs-toggle="tooltip" title="{{ article.title }}">{{ article.title|slice:":45" }}...</h6></a>
</div>
</div>
{% endfor %}
</div>
</div>
<div>
<iframe width="auto" height="235" src="https://maphub.net/embed/188169?button=0&panel=1&panel_closed=1" frameborder="0"></iframe>
<div class="feed-buttons my-4">
<a href="#"><button type="button" name="reddit-button" class="btn reddit-color mx-2 px-2"><i class="fab fa-reddit" aria-hidden="true"></i>Reddit</button></a>
<a href="#"><button type="button" name="twitter-button" class="btn twitter-color mx-2 px-2"><i class="fa-brands fa-twitter" aria-hidden="true"></i>Twitter</button></a>
<a href="#"><button type="button" name="rss-button" class="btn rss-color mx-2 px-2"><i class="fa-solid fa-rss" aria-hidden="true"></i> RSS</button></a>
</div>
</div>
</div>
<h3>Off Track</h3>
<div class="row align-items-start py-5">
{% for lower_article in lower_articles|slice:"0:8" %}
<div class="row col-9">
{% comment %} <img class="mr-3" src="..." alt="Generic placeholder image"> {% endcomment %}
<div class="media-body border-left border-dark m-1 py-1 px-2"><a href="{{ lower_article.url }}">
<h5 class="mt-0">{{ lower_article.title }}</h5></a>
</div><br>
</div>
{% endfor %}
</div>
{% endblock front %}
I hope this clarifies it more, thanks for your response
EDIT: I just saw the part where you asked about SearchEngine object. That’s a personal class not a 3rd party one. In the interest of completion it looks like this →
from bs4 import BeautifulSoup
import metadata_parser
from requests import get
from urllib.parse import quote
from typing import List, Dict
class SearchEngine:
def __init__(self):
self.results = []
def google(self, query: str, max_results = 10, lang = "en", **proxies) -> List[Dict[str, str]]:
engine = get(f"https://www.google.com/search?q={quote(query, safe='')}&num={max_results}&hl={lang}", headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/61.0.3163.100 Safari/537.36'}, proxies = {}).text
part = BeautifulSoup(engine, "lxml").find_all("div", attrs={"class": "yuRUbf"})
return self.to_list(part)
...
def to_list(self, part):
"""
Generates a list of dictionaries for each result
"""
for i in range(len(part)):
title = part[i].find("h3").text
url = part[i].find("a", href = True)["href"]
description = SearchEngine.get_meta(url)
self.results.append({"title": title, "url": url, "description": description})
# self.results.append({"title": title, "url": url})
return self.results
@staticmethod
def get_meta(url):
page = metadata_parser.MetadataParser(url)
meta = page.metadata['meta']
try:
description = f"{meta['description'][:60]}..."
except KeyError:
description = "There is no description for this page"
return description
query = "jupiter"
def main():
engine = SearchEngine()
results = engine.google(query, localhost=3000)
# meta = engine.get_meta(results[0]['url'])
# print(f"description: {meta}")
# print(results)
for result in results:
# print(f"site_meta description: {engine.get_meta(result['url'])}\n")
print(result)
# print(__import__('sys').version_info)
if __name__ == '__main__':
main()