Spaces:
Sleeping
Sleeping
Upload 5 files
Browse files- company_content_generator.py +93 -0
- crawl.py +52 -0
- marketed_blog.py +126 -0
- seo_keywords.py +142 -0
- seo_optimized_content_generator.py +64 -0
company_content_generator.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
import asyncio
|
| 3 |
+
from langchain_core.prompts import PromptTemplate
|
| 4 |
+
|
| 5 |
+
from crawl import marketing_crawling
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
company_prompt_template = PromptTemplate.from_template("""
|
| 9 |
+
# Task
|
| 10 |
+
This is the scraped content from the company website. Read this content and extract the key information in an easy-to-read, professional format.
|
| 11 |
+
|
| 12 |
+
#**Instructions:**
|
| 13 |
+
- Focus on the most important details and present them in a structured, clear format.
|
| 14 |
+
- Follow the example below for formatting and style.
|
| 15 |
+
- Organize the content into clear sections such as:
|
| 16 |
+
- **About the Company**
|
| 17 |
+
- **Services Offered** (with sub-sections for each service)
|
| 18 |
+
- **Why Choose the Company** (highlight unique selling points and certifications)
|
| 19 |
+
- **Company Information** (contact details, address, and other relevant details)
|
| 20 |
+
- Avoid irrelevant details, redundant information, and generic text.
|
| 21 |
+
- Use professional, concise language that is easy to understand.
|
| 22 |
+
- Ensure consistency in formatting and tone.
|
| 23 |
+
|
| 24 |
+
#**Example:**
|
| 25 |
+
|
| 26 |
+
#### **About All Solar Works**
|
| 27 |
+
All Solar Works specializes in **solar panels, battery storage, EV chargers, and electrical services** across Sussex, UK. They offer expert installation and high-quality solutions to help customers save money on energy bills while reducing their carbon footprint.
|
| 28 |
+
|
| 29 |
+
----------
|
| 30 |
+
|
| 31 |
+
### **Services Offered**
|
| 32 |
+
|
| 33 |
+
#### **1. Solar Panels**
|
| 34 |
+
- Install various solar panel systems to fit different budgets.
|
| 35 |
+
- Helps customers reduce bills and enjoy long-term savings.
|
| 36 |
+
- **Complete Solar Panel System Package includes:**
|
| 37 |
+
- **X** kWp Solar PV System
|
| 38 |
+
- **X** W Aiko Panels
|
| 39 |
+
- **X** kW Hybrid Inverter
|
| 40 |
+
- **Online Monitoring, DNO application, Warranty, and MCS certification**
|
| 41 |
+
- Available **with or without battery storage**.
|
| 42 |
+
|
| 43 |
+
#### **2. Battery Storage**
|
| 44 |
+
- Certified **Fox ESS Elite Installer**, ensuring top performance and reliability.
|
| 45 |
+
- Stores excess solar energy for use at night or during low sunlight hours.
|
| 46 |
+
|
| 47 |
+
#### **3. EV Charging Solutions**
|
| 48 |
+
- Install home and workplace **EV chargers**.
|
| 49 |
+
- Compatible with **all Type-2 electric vehicles**.
|
| 50 |
+
- Includes a dedicated app for full control over charging.
|
| 51 |
+
|
| 52 |
+
#### **4. Electrical Services**
|
| 53 |
+
- Professional and reliable services, including:
|
| 54 |
+
- **Rewiring, consumer unit replacement, additional power points, and more.**
|
| 55 |
+
|
| 56 |
+
----------
|
| 57 |
+
|
| 58 |
+
### **Why Choose All Solar Works?**
|
| 59 |
+
**Certified Fox ESS Elite Installer** – Ensures optimal battery storage performance.
|
| 60 |
+
**Customizable Solar Solutions** – Tailored to individual energy needs.
|
| 61 |
+
**Energy Independence** – Reduce reliance on the grid and lower bills.
|
| 62 |
+
**Long-Term Savings** – Financially beneficial with eco-friendly advantages.
|
| 63 |
+
|
| 64 |
+
----------
|
| 65 |
+
|
| 66 |
+
### **Company Information**
|
| 67 |
+
**Company Name:** All Solar Works
|
| 68 |
+
**Location:** Edgehill Close, Worthing, West Sussex, BN XX
|
| 69 |
+
**Contact:** info@allsolarworks.com | +44 XXX XXXX
|
| 70 |
+
**Operating Hours:** Monday – Friday (9 AM – 5 PM), Saturday (10 AM – 2 PM)
|
| 71 |
+
|
| 72 |
+
----------
|
| 73 |
+
|
| 74 |
+
Use this format and structure when extracting the content from the website. Ensure the final output is clean, structured, and easy to understand.
|
| 75 |
+
|
| 76 |
+
----------
|
| 77 |
+
|
| 78 |
+
**Company Information:**
|
| 79 |
+
{company_information}
|
| 80 |
+
|
| 81 |
+
""")
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def company_content(llm, state):
|
| 85 |
+
url = state["url"]
|
| 86 |
+
if sys.platform == "win32":
|
| 87 |
+
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
|
| 88 |
+
content = asyncio.run(marketing_crawling(url))
|
| 89 |
+
prompt = company_prompt_template.invoke({"company_information": content})
|
| 90 |
+
response = llm.invoke(prompt)
|
| 91 |
+
print(response.content)
|
| 92 |
+
return {"company_information": response.content}
|
| 93 |
+
|
crawl.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
+
from crawl4ai import AsyncWebCrawler
|
| 3 |
+
from crawl4ai.async_configs import BrowserConfig, CrawlerRunConfig
|
| 4 |
+
import re
|
| 5 |
+
|
| 6 |
+
def remove_links_and_pics(input_text):
|
| 7 |
+
# Remove all links (URLs)
|
| 8 |
+
text_without_links = re.sub(r'https?:\/\/[^\s<>]+|<https?:\/\/[^\s<>]+>', '', input_text)
|
| 9 |
+
|
| 10 |
+
# Remove all image references (markdown-style image syntax)
|
| 11 |
+
text_without_images = re.sub(r'!\[.*?\]\(.*?\)', '', text_without_links)
|
| 12 |
+
|
| 13 |
+
# Remove HTML tags
|
| 14 |
+
text_without_html = re.sub(r'<[^>]+>', '', text_without_images)
|
| 15 |
+
|
| 16 |
+
# Remove special characters and leave only text
|
| 17 |
+
text_without_special_chars = re.sub(r'[^a-zA-Z\s]', '', text_without_html)
|
| 18 |
+
|
| 19 |
+
# Remove special characters and leave only text
|
| 20 |
+
text_without_brackets = re.sub(r'\[.*?\]|\(.*?\)', '', text_without_special_chars)
|
| 21 |
+
|
| 22 |
+
return text_without_brackets.strip()
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
# Crawling for marketing
|
| 26 |
+
async def marketing_crawling(url):
|
| 27 |
+
browser_config = BrowserConfig() # Default browser configuration
|
| 28 |
+
run_config = CrawlerRunConfig() # Default crawl run configuration
|
| 29 |
+
|
| 30 |
+
async with AsyncWebCrawler(config=browser_config) as crawler:
|
| 31 |
+
result = await crawler.arun(
|
| 32 |
+
url = url,
|
| 33 |
+
config=run_config
|
| 34 |
+
)
|
| 35 |
+
cleaned_text = remove_links_and_pics(result.markdown) # type: ignore
|
| 36 |
+
return cleaned_text
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
# Crawling for SEO
|
| 40 |
+
async def seo_crawling(url):
|
| 41 |
+
browser_config = BrowserConfig() # Default browser configuration
|
| 42 |
+
run_config = CrawlerRunConfig() # Default crawl run configuration
|
| 43 |
+
|
| 44 |
+
async with AsyncWebCrawler(config=browser_config) as crawler:
|
| 45 |
+
result = await crawler.arun(
|
| 46 |
+
url = url,
|
| 47 |
+
config=run_config
|
| 48 |
+
)
|
| 49 |
+
text = result.markdown # type: ignore
|
| 50 |
+
return text
|
| 51 |
+
|
| 52 |
+
# asyncio.run(marketing_crawling("https://allsolarworks.com/"))
|
marketed_blog.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langchain_core.prompts import PromptTemplate
|
| 2 |
+
|
| 3 |
+
marketing_prompt_template = PromptTemplate.from_template("""
|
| 4 |
+
# **Role:**
|
| 5 |
+
You are an expert content marketer.
|
| 6 |
+
|
| 7 |
+
# **Task:**
|
| 8 |
+
Your task is to seamlessly integrate marketing elements for the company into the given blog post while maintaining the original structure and flow.
|
| 9 |
+
|
| 10 |
+
# **Instructions:**
|
| 11 |
+
|
| 12 |
+
## **1. Understand the Blog Content & Company Information:**
|
| 13 |
+
- Read and analyze the blog content carefully.
|
| 14 |
+
- Review the company’s information to determine how it aligns with the blog topic.
|
| 15 |
+
|
| 16 |
+
## **2. Incorporate Company Marketing Content:**
|
| 17 |
+
- Add relevant concise company information at a suitable section of the blog.
|
| 18 |
+
- Ensure the integration feels natural and does not disrupt the blog’s readability.
|
| 19 |
+
- Use a structured format with appropriate headings to match the blog’s tone and style.
|
| 20 |
+
- Use UK Grammar and Spelling for Company Marketing Content.
|
| 21 |
+
|
| 22 |
+
## **3. Formatting Guidelines:**
|
| 23 |
+
- Use **headings** to introduce company-related content in a way that fits the blog structure.
|
| 24 |
+
- Utilize **bullet points** for clarity and ease of reading.
|
| 25 |
+
- Maintain a professional and engaging tone throughout.
|
| 26 |
+
|
| 27 |
+
## **4. Call to Action (CTA):**
|
| 28 |
+
- Include a **CTA with a hyperlink** to the company’s relevant service page or contact page.
|
| 29 |
+
- Ensure the CTA is strategically placed for maximum engagement.
|
| 30 |
+
|
| 31 |
+
## **5. Preserve Blog Content Integrity:**
|
| 32 |
+
- Do **not** modify or remove any existing blog content.
|
| 33 |
+
- If the company’s information does **not** align with the blog’s topic, keep the blog unchanged.
|
| 34 |
+
|
| 35 |
+
## **6. Use the Example Blog as a Reference:**
|
| 36 |
+
- Follow the provided example format to ensure consistency.
|
| 37 |
+
|
| 38 |
+
---
|
| 39 |
+
|
| 40 |
+
## **Example Output:**
|
| 41 |
+
|
| 42 |
+
# What Are The Benefits Of Solar Panels?
|
| 43 |
+
Solar panels are a game-changing technology that allows you to harness the sun’s energy and convert it into electricity. They offer numerous advantages for homes and businesses, making them a popular choice for those seeking sustainable and cost-effective energy solutions. In this guide, we’ll discuss the key **benefits of solar panels** and why they’re an excellent investment for your future.
|
| 44 |
+
|
| 45 |
+
## **The Key Benefits of Solar Panels**
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
### **1. Lower Energy Costs**
|
| 49 |
+
|
| 50 |
+
Solar panels enable you to generate your own electricity, reducing your reliance on the national grid. This translates into significant savings on your energy bills. Over time, these savings can offset the initial cost of installation, making solar panels a financially smart choice.
|
| 51 |
+
|
| 52 |
+
### **2. Environmentally Friendly Energy**
|
| 53 |
+
|
| 54 |
+
**Solar power** is a clean, renewable energy source that doesn’t produce harmful greenhouse gas emissions. By installing solar panels, you’re taking a step towards reducing your carbon footprint and contributing to a healthier planet.
|
| 55 |
+
|
| 56 |
+
### **3. Energy Independence**
|
| 57 |
+
|
| 58 |
+
With solar panels , you can generate your own energy and reduce dependency on external suppliers. This protects you from rising energy prices and ensures a reliable power source, even in times of high demand.
|
| 59 |
+
|
| 60 |
+
### **4. Increased Property Value**
|
| 61 |
+
|
| 62 |
+
Homes and businesses with solar panels are often more attractive to buyers due to their energy efficiency and lower running costs. This added value can make solar panels a smart investment for property owners.
|
| 63 |
+
|
| 64 |
+
### **5. Minimal Maintenance Requirements**
|
| 65 |
+
|
| 66 |
+
Solar panels are designed to last for decades with minimal maintenance. Regular cleaning and occasional professional checks are typically enough to keep them running efficiently, making them a hassle-free energy solution.
|
| 67 |
+
|
| 68 |
+
### **6. Access to Incentives**
|
| 69 |
+
|
| 70 |
+
Many governments offer incentives, grants, or tax breaks to encourage the adoption of solar energy. These schemes can significantly reduce the upfront costs of installation, making [solar panels](https://allsolarworks.com/solar/) more accessible than ever before.
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
## **How Do Solar Panels Work?**
|
| 74 |
+
|
| 75 |
+
Solar panels are made of photovoltaic (PV) cells that convert sunlight into electricity. Here’s a simplified overview:
|
| 76 |
+
|
| 77 |
+
1. **Sunlight Absorption**: The PV cells capture sunlight and generate direct current (DC) electricity.
|
| 78 |
+
2. **Conversion to Usable Power**: An inverter converts the DC electricity into alternating current (AC), which powers your appliances.
|
| 79 |
+
3. **Energy Storage or Export**: Any excess energy can be stored in batteries or exported to the grid, providing additional financial benefits.
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
## **Why Switch to Solar Panels Now?**
|
| 84 |
+
|
| 85 |
+
The shift towards renewable energy sources has made solar technology more affordable and efficient. With the rising costs of traditional energy, there’s never been a better time to [invest in solar panels](https://allsolarworks.com/solar/). Modern panels can generate electricity even in less sunny climates, ensuring reliable performance year-round.
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
## **Why Choose All Solar Works?**
|
| 89 |
+
|
| 90 |
+
At All Solar Works, we specialise in providing tailored solar solutions that meet your unique energy needs. Here’s why you should choose us:
|
| 91 |
+
|
| 92 |
+
- **Expert Installation**: Our team has extensive experience in designing and installing high-quality solar systems.
|
| 93 |
+
- **Top-Tier Products**: We use only the best solar panels and components to ensure long-lasting performance.
|
| 94 |
+
- **Comprehensive Support**: From initial consultation to ongoing maintenance, we’re here to support you every step of the way.
|
| 95 |
+
|
| 96 |
+
[GET IN TOUCH](https://allsolarworks.com/contact-us/)
|
| 97 |
+
|
| 98 |
+
## **Ready to Embrace Solar Energy?**
|
| 99 |
+
|
| 100 |
+
Solar panels are an investment in a brighter, greener future. If you’re ready to experience the **benefits of solar energy** today. Our experts are on hand to answer your questions and help you find the perfect solar solution for your property
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
**Blog Content:**
|
| 104 |
+
```{blog}```
|
| 105 |
+
|
| 106 |
+
**Company Information:**
|
| 107 |
+
```{company_information}```
|
| 108 |
+
|
| 109 |
+
**Contact Us Page Link:**
|
| 110 |
+
```{link}```
|
| 111 |
+
|
| 112 |
+
""")
|
| 113 |
+
|
| 114 |
+
def marketed_blog(llm, state):
|
| 115 |
+
blog = state["blog_content"]
|
| 116 |
+
url = state["contact_us_url"]
|
| 117 |
+
company = state["company_information"]
|
| 118 |
+
|
| 119 |
+
print(url)
|
| 120 |
+
|
| 121 |
+
prompt = marketing_prompt_template.invoke({"company_information": company, "link": url, "blog":blog})
|
| 122 |
+
response = llm.invoke(prompt)
|
| 123 |
+
print(response.content)
|
| 124 |
+
return {"company_marketed_blog": response.content}
|
| 125 |
+
|
| 126 |
+
|
seo_keywords.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langchain_community.tools import TavilySearchResults
|
| 2 |
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
| 3 |
+
from langchain_core.prompts import PromptTemplate
|
| 4 |
+
from tavily import TavilyClient
|
| 5 |
+
import asyncio
|
| 6 |
+
import sys
|
| 7 |
+
|
| 8 |
+
import os
|
| 9 |
+
from dotenv import load_dotenv
|
| 10 |
+
|
| 11 |
+
# files
|
| 12 |
+
from crawl import seo_crawling
|
| 13 |
+
|
| 14 |
+
# Secret Key
|
| 15 |
+
load_dotenv(override=True)
|
| 16 |
+
tavily_api_key = os.getenv("TAVILY_API_KEY")
|
| 17 |
+
gemini_api_key = os.getenv("GEMINI_API_KEY")
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash-exp", api_key = gemini_api_key) # type: ignore
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
# def tavily_search(query: str):
|
| 24 |
+
|
| 25 |
+
# tavily = TavilySearchResults(
|
| 26 |
+
# max_results=10,
|
| 27 |
+
# search_depth="advanced",
|
| 28 |
+
# include_answer=True,
|
| 29 |
+
# include_images=True,
|
| 30 |
+
# include_links=True, # type: ignore
|
| 31 |
+
# api_key=tavily_api_key, # type: ignore
|
| 32 |
+
# )
|
| 33 |
+
|
| 34 |
+
# results = tavily.invoke({"query": f"{query}"})
|
| 35 |
+
# return results
|
| 36 |
+
|
| 37 |
+
# results = tavily_search("UK Air Source Heat Pump Market Trends 2025")
|
| 38 |
+
# print(results)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def tavily_search(query):
|
| 42 |
+
tavily_client = TavilyClient(api_key = tavily_api_key)
|
| 43 |
+
response = tavily_client.search(query, max_results=10)
|
| 44 |
+
# print(response["results"])
|
| 45 |
+
return response["results"]
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def match_title(title, titles):
|
| 49 |
+
title_prompt_template = PromptTemplate.from_template("""
|
| 50 |
+
Your task is to find the title in the List that semantically matches the User_title.
|
| 51 |
+
- Don't change the title name
|
| 52 |
+
- Don't give extra content. Only give the title name.
|
| 53 |
+
- Only give **One title**
|
| 54 |
+
|
| 55 |
+
List = {list}
|
| 56 |
+
User_title = {title}
|
| 57 |
+
|
| 58 |
+
""")
|
| 59 |
+
|
| 60 |
+
prompt = title_prompt_template.invoke({"list": titles, "title": title})
|
| 61 |
+
response = llm.invoke(prompt)
|
| 62 |
+
return response.content
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def keywords(content):
|
| 66 |
+
keywords_prompt_template = PromptTemplate.from_template("""
|
| 67 |
+
# **Instruction:**
|
| 68 |
+
Analyze the given text and extract keywords based on their relevance to SEO. Categorize them into the following three groups:
|
| 69 |
+
|
| 70 |
+
## **1. Primary Keywords (High-Impact, Industry-Specific):**
|
| 71 |
+
- Broad, high-volume search terms that are directly related to the main topic.
|
| 72 |
+
- Common industry terms that people search for when looking for services or information.
|
| 73 |
+
- Maximum **10-12 keywords**.
|
| 74 |
+
|
| 75 |
+
## **2. Secondary Keywords (Supporting SEO & Long-Tail Queries):**
|
| 76 |
+
- More specific, longer phrases related to the main topic.
|
| 77 |
+
- Keywords that provide contextual depth and support for primary keywords.
|
| 78 |
+
- Maximum **10-12 keywords**.
|
| 79 |
+
|
| 80 |
+
## **3. Local SEO Keywords (Boosting Regional Visibility):**
|
| 81 |
+
- Keywords that include location-specific terms.
|
| 82 |
+
- Phrases that help rank in local search results.
|
| 83 |
+
- Maximum **5-8 keywords**.
|
| 84 |
+
|
| 85 |
+
# Don't give the extra content only give the SEO keywords
|
| 86 |
+
|
| 87 |
+
# **Input:**
|
| 88 |
+
{text}
|
| 89 |
+
|
| 90 |
+
""")
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
prompt = keywords_prompt_template.invoke({"text": content})
|
| 94 |
+
response = llm.invoke(prompt)
|
| 95 |
+
return response.content
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def seo_keywords(state):
|
| 101 |
+
|
| 102 |
+
topic = state["final_topic"]
|
| 103 |
+
# topic = state
|
| 104 |
+
|
| 105 |
+
results = tavily_search(topic)
|
| 106 |
+
|
| 107 |
+
titles = []
|
| 108 |
+
titles_url = []
|
| 109 |
+
final_url = ""
|
| 110 |
+
|
| 111 |
+
for t in results:
|
| 112 |
+
titles.append(t['title'])
|
| 113 |
+
|
| 114 |
+
for t in results:
|
| 115 |
+
titles_url.append({
|
| 116 |
+
"title": t['title'],
|
| 117 |
+
"url": t['url']
|
| 118 |
+
})
|
| 119 |
+
|
| 120 |
+
print(titles)
|
| 121 |
+
print(titles_url)
|
| 122 |
+
|
| 123 |
+
text = match_title(topic, titles)
|
| 124 |
+
print(text)
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
for title in titles_url:
|
| 128 |
+
if title['title'] == text:
|
| 129 |
+
final_url = title['url']
|
| 130 |
+
|
| 131 |
+
print(final_url)
|
| 132 |
+
|
| 133 |
+
if sys.platform == "win32":
|
| 134 |
+
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
|
| 135 |
+
|
| 136 |
+
crawled_content = asyncio.run(seo_crawling(final_url))
|
| 137 |
+
response = keywords(crawled_content)
|
| 138 |
+
print(response)
|
| 139 |
+
return{"seo_keywords":response}
|
| 140 |
+
|
| 141 |
+
# a = seo_keywords("UK Air Source Heat Pump Market Trends 2025")
|
| 142 |
+
# print(a)
|
seo_optimized_content_generator.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langchain_core.prompts import PromptTemplate
|
| 2 |
+
|
| 3 |
+
def seo_optimized_content_with_marketing(llm, state):
|
| 4 |
+
|
| 5 |
+
keywords = state["seo_keywords"]
|
| 6 |
+
blog = state["company_marketed_blog"]
|
| 7 |
+
|
| 8 |
+
seo_prompt_template = PromptTemplate.from_template("""
|
| 9 |
+
You are an advanced SEO content optimizer and copywriting assistant. Your task is to enhance the given blog content by seamlessly integrating the most relevant provided keywords according Blog Content while maintaining readability, clarity, and natural flow. Ensure that the structure, tone, and coherence of the content remain intact.
|
| 10 |
+
|
| 11 |
+
### **Instructions:**
|
| 12 |
+
1. **Analyze the Blog Content:** Carefully read and understand the provided blog content.
|
| 13 |
+
2. **Strategic Relevant Keyword Placement:**
|
| 14 |
+
- Incorporate **Primary Keywords** in high-impact areas such as the title, introduction, key sections, and conclusion.
|
| 15 |
+
- Integrate **Secondary Keywords** naturally into relevant sections without making them seem forced.
|
| 16 |
+
- **Local Keywords** place them appropriately to optimize for local search visibility.
|
| 17 |
+
3. **Maintain Readability:** Ensure that the content remains engaging and human-like, avoiding keyword stuffing.
|
| 18 |
+
4. **Preserve Structure:** Keep the formatting, headings, and logical flow of the blog intact.
|
| 19 |
+
5. **Enhance SEO & Value:** Improve the content’s SEO potential while ensuring it remains informative, valuable, and easy to read.
|
| 20 |
+
6. **Don't include any Extra Information Only give the Blog Content**
|
| 21 |
+
7. Exclude the place keywords except **UK**.
|
| 22 |
+
8. Don't bold the placed keywords in the Blog.
|
| 23 |
+
|
| 24 |
+
### **Inputs:**
|
| 25 |
+
- **Blog Content:** {blog_content}
|
| 26 |
+
- **Keywords:** {keywords}
|
| 27 |
+
""")
|
| 28 |
+
|
| 29 |
+
prompt = seo_prompt_template.invoke({"blog_content": blog, "keywords":keywords})
|
| 30 |
+
response = llm.invoke(prompt)
|
| 31 |
+
|
| 32 |
+
return {"seo_optimized_blog":response.content}
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def simple_seo_optimized_content(llm, state):
|
| 36 |
+
|
| 37 |
+
keywords = state["seo_keywords"]
|
| 38 |
+
blog = state["blog_content"]
|
| 39 |
+
|
| 40 |
+
seo_prompt_template = PromptTemplate.from_template("""
|
| 41 |
+
You are an advanced SEO content optimizer and copywriting assistant. Your task is to enhance the given blog content by seamlessly integrating the most relevant provided keywords according Blog Content while maintaining readability, clarity, and natural flow. Ensure that the structure, tone, and coherence of the content remain intact.
|
| 42 |
+
|
| 43 |
+
### **Instructions:**
|
| 44 |
+
1. **Analyze the Blog Content:** Carefully read and understand the provided blog content.
|
| 45 |
+
2. **Strategic Relevant Keyword Placement:**
|
| 46 |
+
- Incorporate **Primary Keywords** in high-impact areas such as the title, introduction, key sections, and conclusion.
|
| 47 |
+
- Integrate **Secondary Keywords** naturally into relevant sections without making them seem forced.
|
| 48 |
+
- **Local Keywords** place them appropriately to optimize for local search visibility.
|
| 49 |
+
3. **Maintain Readability:** Ensure that the content remains engaging and human-like, avoiding keyword stuffing.
|
| 50 |
+
4. **Preserve Structure:** Keep the formatting, headings, and logical flow of the blog intact.
|
| 51 |
+
5. **Enhance SEO & Value:** Improve the content’s SEO potential while ensuring it remains informative, valuable, and easy to read.
|
| 52 |
+
6. **Don't include any Extra Information Only give the Blog Content**
|
| 53 |
+
7. Exclude the place keywords except **UK**.
|
| 54 |
+
8. Don't bold the placed keywords in the Blog.
|
| 55 |
+
|
| 56 |
+
### **Inputs:**
|
| 57 |
+
- **Blog Content:** {blog_content}
|
| 58 |
+
- **Keywords:** {keywords}
|
| 59 |
+
""")
|
| 60 |
+
|
| 61 |
+
prompt = seo_prompt_template.invoke({"blog_content": blog, "keywords":keywords})
|
| 62 |
+
response = llm.invoke(prompt)
|
| 63 |
+
|
| 64 |
+
return {"seo_optimized_blog":response.content}
|