
    |iq              
          d Z ddlZddlZddlZddlZddlmZ ddlZddlm	Z	 ddl
mZ ddlZddlZej                            ej                            ej                            e          d                     ddlmZ  ej        d            ej        ej        d	
            ej        e          ZdZdZddiZdZdZdZ d Z!d Z" ed          Z#d Z$ e            Z%e%&                                Z'e'(                    d           e%)                                 d Z*d Z+d Z,	 	 e-                    d           e-                    d            e"            Z.e.a/ e+            \  Z0Z1e-                    d            e,            \  Z2Z3e-                    d           e-                    d e4e.                      e-                    de0            e-                    d e2            e-                    d!e0e2z               e-                    d"           e-                    d#           e15                                D ],\  Z6Z7d$e6vrd%nd&Z8e-                    d'e8 d(e6 d)e7 d*           -e-                    d+           e35                                D ]!\  Z6Z7e-                    d,e6 d)e7 d*           "d- e.D             Z9d. e.D             Z:e-                    d/           e-                    d0 e4e9           d1 e;d2 e9D                        d3           e-                    d4 e4e:           d1 e;d5 e:D                        d3           e-                    d6 e4e3           d1e2 d3           e-                    d7 e4e.           e4e3          z    d1e0e2z    d3           d8 e<            v re%=                                 dS dS # d8 e<            v re%=                                 w w xY w)9aX  
Web Scraper and Embedding Tool for Dr. Robert Young's Content

This module scrapes articles from multiple sources (case studies and Dr. Robert Young's blog)
and stores them in a database with vector embeddings for semantic search.

Features:
- Scrapes content from WordPress blog and case studies
- Extracts clean article content with noise filtering
- Generates semantic embeddings using sentence-transformers
- Stores structured data in MySQL database
- Handles rate limiting and respectful scraping practices
- Supports multiple content sources and categories

Scraping Sources:
1. Main WordPress Site: https://phoreveryoung.wordpress.com/
2. Dr. Robert Young Blog: https://drrobertyoung.com/blog/

Data Processing Pipeline:
1. Extract raw HTML content
2. Clean and filter relevant text
3. Generate vector embeddings
4. Store in database with metadata
    N)urljoin)BeautifulSoup)SentenceTransformerz..)get_connectionignorez)%(asctime)s - %(levelname)s - %(message)s)levelformatzhttps://drrobertyoung.com/blog/z$https://phoreveryoung.wordpress.com/z
User-AgentzMozilla/5.0 (MultiSiteBot/1.0)i,        c           	      n   t                      }d|  d}	 t                              d|             t          j        |t
          d          }t          |j        d          }|                    dt          j
        dt          j        |            d	          
          }|D ]}|                    d          }|rdt          j        |            d}t          j        ||          }	|	rT|	                    d          }
|
r=|
dvr9|  d|
 }|                    |           t                              d|            t                              dt          |           d|             t!          |          S # t"          $ r,}t                              d|  d|            g cY d}~S d}~ww xY w)z
    Discover subcategories within a main category
    
    Args:
        main_category_slug (str): Main category slug
    
    Returns:
        list: List of subcategory slugs
    -https://phoreveryoung.wordpress.com/category//u#   🔍 Discovering subcategories in:    headerstimeouthtml.parsera/https://phoreveryoung\.wordpress\.com/category/z/[^/"]+/hrefr   z
/([^/"]+)/r
   )feedpageu     📂 Found subcategory: u
   ✅ Found z subcategories in u,   ⚠️ Could not discover subcategories for : N)setloggerinforequestsgetHEADERSr   textfind_allrecompileescapesearchgroupaddlenlist	Exceptionwarning)main_category_slugsubcategoriesmain_category_urlresponsesoupsubcategory_linkslinkr   patternmatchsubcategoryfull_subcategory_pathes                LC:\Users\Aakash\Desktop\Scrapping\New folder (2)\scraper\scrape_and_embed.pydiscover_subcategoriesr:   A   s    EEM]HZ]]]N:LNNOOO< 17BOOOX]M:: !MM#BJfryI[?\?\fff5h 5hM i i & 	Z 	ZD88F##D 	ZvRYWiMjMjvvv	'400 Z"'++a..K" Z{:J'J Z3E0U0U0U0U-%))*?@@@$XAV$X$XYYY[]!3!3[[GY[[\\\M"""   _FX__\]__```						s   E'E> >
F4!F/)F4/F4c            	         t                               d           	 t          j        t          t
          d          } t          | j        d          }t                      }|	                    dt          j        d                    }|D ]f}|                    d          }|rMd	|v rI|                    d	          d
                             d          }|rd|vr|                    |           g|	                    dt          j        d          d          }|D ]f}|                    d          }|rMd	|v rI|                    d	          d
                             d          }|rd|vr|                    |           g|	                    t          j        d                    }|D ]i}	|	                    dg           }
|
D ]N}|                    d          r7|dk    r1|                    dd          }|rd|vr|                    |           Ojt#          t%          |                    }t                               dt'          |           d           t)          |d          D ]&\  }}t                               d|dd|            '|                                }t                               d           |D ]:}t-          |          }|                    |           t1          j        d           ;t#          t%          t          |                              }t                               d           t                               dt'          |                      t'          |          }t'          |          |z
  }t                               d|            t                               d |            t                               d!           t)          |d          D ]1\  }}||v rd"nd#}t                               d|dd| d$|            2|S # t4          $ rE}t                               d%|            t                               d&           g d'cY d(}~S d(}~ww xY w))aI  
    Dynamically discover all categories and subcategories from the main WordPress page
    
    This function scrapes the main page and identifies all available categories
    and their subcategories by analyzing the HTML structure.
    
    Returns:
        list: List of category slugs to scrape (including subcategories)
    uF   🔍 DISCOVERING CATEGORIES AND SUBCATEGORIES FROM MAIN WORDPRESS PAGEr   r   r   r   r   r   r   
/category/r   ?zcategory tag)r   relzcategory-[\w-]+class_classz	category-category _u   ✅ DISCOVERED z MAIN CATEGORIES:r
     2dz. u"   
🔍 DISCOVERING SUBCATEGORIES...u   
✅ FINAL DISCOVERY COMPLETE!u1   📊 TOTAL CATEGORIES (including subcategories): u      • Main categories: u      • Subcategories: u    
📚 ALL DISCOVERED CATEGORIES:   📁   📂 u#   ❌ Failed to discover categories: u!   🔄 Using fallback category list)	zbefore-and-afterfunnyzalkaline-lifestyle-and-diethealthzhealth/nutritionresearchzproducts/waterzhealth/weight-lossretreatsN)r   r   r   r   MAIN_WORDPRESS_URLr    r   r!   r   r"   r#   r$   splitrstripr(   
startswithreplacesortedr*   r)   	enumeratecopyr:   extendtimesleepr+   error)r0   r1   categories_found	nav_linksr3   r   category_partarticle_linkscategory_elementselemclassesclscategory_namemain_categoriesicat!all_categories_with_subcategoriesmain_catsubcatsfinal_categories
main_count	sub_countprefixr8   s                           r9   discover_all_categoriesrn   k   s    KKXYYYW
< 2GRPPPX]M::55 MM#BJ7i,j,jMkk	 	8 	8D88F##D 8, 8 $

< 8 8 < C CC H H  8S%= 8$((777 c
;m0n0n  uC  D  D! 	8 	8D88F##D 8, 8 $

< 8 8 < C CC H H  8S%= 8$((777 !MM<N1O1OMPP% 	< 	<Dhhw++G < <>>+.. <3*3D <$'KKR$@$@M$ <M)A <(,,];;;	< !&6!7!788Mc/&:&:MMMNNN33 	, 	,FAsKK*Q***S**++++ -<,@,@,B,B)9:::' 	 	H,X66G-44W===JqMMMM "$s+L'M'M"N"NOO6777_L\H]H]__``` ))
())J6	;z;;<<<8Y889997888 0!44 	5 	5FAs"o5AVV6FKK3Q333V33c334444 
 
 
>1>>???7888

 

 

 
	
 
	
 
	
 
	
 
	
 
	
	
s   PP( (
Q72:Q2,Q72Q7zall-MiniLM-L6-v2c                 v   g d}d}|D ]}|                      |          }|r n|sdS |                    g dd          }g }|D ]^}|                    dd          t                    d	k     r-t	          fd
dD                       rI|                               _d                    |          S )a  
    Extract clean article content from a BeautifulSoup object
    
    This function attempts to find the main content of an article by trying various
    common HTML selectors and filtering out unwanted elements like navigation,
    advertisements, and footer content.
    
    Args:
        soup (BeautifulSoup): Parsed HTML document
        
    Returns:
        str: Cleaned article content or empty string if no content found
    )articlezdiv.entry-contentz'div.elementor-widget-theme-post-contentmainNrD   )ph1h2h3h4liT)	recursiverJ   strip   c              3   D   K   | ]}|                                 v V  d S )N)lower).0skipr!   s     r9   	<genexpr>z0extract_clean_article_content.<locals>.<genexpr>  s@        ttzz||#          )z
share thisrelatedauthorz	posted on	subscribe
navigationfooter	copyrightzall rights reservedzprivacy policyzterms of servicecookiemenur&   zleave a commentreplyzprevious postz	next postfacebooktwitterlinkedinemail
)
select_oner"   get_textr)   anyappendjoin)r1   	selectorscontent_rootselelementscontent_partselr!   s          @r9   extract_clean_article_contentr      s0     I L  s++ 	E	  r $$+++ %  H
 M # #{{3d{++ t99r> 	      1
      	 T""""99]###r   z
CREATE TABLE IF NOT EXISTS dr_young_all_articles (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    title TEXT,
    url TEXT UNIQUE,
    content LONGTEXT,
    embedding LONGTEXT
)
c                 	   d}d|  d}|}t                               d|             |r	 t          j        |t          d          }t          |j        d          }n8# t          $ r+}t                               d| d	|            Y d
}~nEd
}~ww xY w|	                    d          }|st           
                    d|            nt                               dt          |           d|            t          |d          D ]\\  }}	|	                    dd          }
|
s |
d         }t                              d|f           t                                          }t                                           |rt                               d|            	 t          j        |t          dd          }n7# t          $ r*}t           
                    d| d	|            Y d
}~d
}~ww xY wt          |j        d          }|                    d          }|sJ|	                    d          }|D ]&}|                    d          }|rd|vrd|vr|} n'|s
|r|d         }|r|                    d          nd }t                               d!|  d"| dt          |           d#|            t)          |          }t          |          t*          k     r0t                               d$| d%t          |           d&           t,                              |                                          }t                              d'|f           t                                          }t                                           |rG|\  }}||k    rt                               d(|            t                               d)|            t                              d*|||t3          |          f           t          j        }t6                                           |dz  }t                               d+|  d,| d-|            t;          j        t>                     ^|                    dd.          }|rtA          ||d                   nd
}|r6t                               d/|            t;          j        tB                     |t                               d0|  d	| d1           |S )2z
    Scrape a single category from phoreveryoung.wordpress.com
    
    Args:
        category_slug (str): The category slug (e.g., 'health/nutrition' or 'research')
    
    Returns:
        int: Number of articles successfully scraped and stored
    r   r   r   u   🚀 SCRAPING CATEGORY: r   r   r   u   ❌ Failed to fetch r   Nrp   u   ⚠️ No articles found on    📄 Found z articles on page: r
   r   Tr   r   0SELECT 1 FROM dr_young_all_articles WHERE url=%s)   ⏭️ Skipping existing article by URL: 
   Fr   r   verifyu   ⚠️ Failed to fetch article entry-titler@   rs   ry   zpHorever YoungBlogUntitledu   📝 [z] Processing article z: INSERTED    ⏭️ Content too short for  (z chars)ASELECT title, content FROM dr_young_all_articles WHERE title = %s:   ⏭️ Skipping exact duplicate (same title and content): -   📝 Same title but different content found: z
                INSERT INTO dr_young_all_articles
                (title, url, content, embedding)
                VALUES (%s, %s, %s, %s)
               ✅ [] INSERTED (ID: ): nextu   ➡️ Moving to next page: u   🏁 FINISHED CATEGORY 	 articles)"r   r   r   r   r    r   r!   r+   rZ   r"   r,   r)   rU   findcurexecutefetchonefetchalldebugr   r   MIN_CONTENT_LENGTHmodelencodetoliststr	lastrowidconncommitrX   rY   ARTICLE_DELAYr   
PAGE_DELAY)category_slugtotal_articlesbase_urlpage_urlr0   r1   r8   articlesre   art
title_linkurlresult
detail_resdetail_soup
title_elemh1_tagsrs   r!   titlecontent	embeddingexisting_titleexisting_contentinserted_id	next_links                             r9   scrape_single_categoryr   &  s|    NO}OOOHH
KK:=::;;;
 r#	|HgrJJJH >>DD 	 	 	LL???A??@@@EEEE	
 ==++ 	NND(DDEEEN#h--NNHNNOOO!,, Z	& Z	&FAs#D11J V$C KKJSFSSS\\^^FLLNNN NNNOOO	%\# 	  

    KKKKKLLL (
GGK %)))??J  
,%..t44!  B;;T;22D  0 < tAS %'
! ,g ,!(J7AQJ''d'333zE KKjjjQjjXjjchjjkkk 4K@@G7||00 [U[[c'll[[[\\\ W--4466I KK[^c]efff\\^^FLLNNN Z390 0#w. ZLL!e^c!e!efff LL!XQV!X!XYYY KK  gs9~~6	8 8 8 -KKKMMMaNKKVVV{VVuVVWWW J}%%%% IIc&I11	;DN78Yv%6777$ 	#KKAxAABBBJz"""e  r#h KKT-TT>TTTUUUs/   1A 
B( BB F>>
G2 G--G2c            	         d} g }i }t                               d           t                               dt          t                                t	          t          d          D ]\  }}t                               d| dt          t                     d|            	 t          |          }| |z  } |||<   t                               d| d	| d
           nQ# t          $ rD}t                               d| d	|            |                    |           d||<   Y d}~nd}~ww xY w|t          t                    k     r.t                               d           t          j
        d           t                               d           t                               d|             |rt                               d|            | |fS )aJ  
    Scrape all categories from phoreveryoung.wordpress.com
    
    This function scrapes articles from all identified categories,
    extracts their content, generates embeddings, and stores them in the database.
    
    Returns:
        tuple: (total_articles, category_stats_dict) - Total articles and per-category stats
    r   u#   🚀 STARTING FULL CATEGORY SCRAPERu!   📋 Total categories to scrape: r
   z
[r   z] Processing category: u   ✅ Completed r   r   u   ❌ Failed to scrape category Nu#   ⏳ Waiting before next category...   u&   
🏁 FULL CATEGORY SCRAPING COMPLETEDu   📊 Total articles scraped: u   ⚠️ Failed categories: )r   r   r)   ALL_CATEGORIESrU   r   r+   rZ   r   rX   rY   r,   )r   failed_categoriescategory_statsre   rC   articles_countr8   s          r9   scrape_all_categoriesr     s    NN
KK5666
KKIC4G4GIIJJJ 33  8T!TTc.11TT(TTUUU	)3H==Nn,N'5N8$KKNNN^NNNOOOO 	) 	) 	)LLI(IIaIIJJJ$$X...'(N8$$$$$$	) s>""" 	KK>???JqMMM
KK9:::
KK@@@AAA IG4EGGHHH>))s   !:C
D*&:D%%D*c                     d} i }t                               d           	 t          j        t          t
          d          }t          |j        d          }|                    dt          j
        d                    }t                      }|D ]f}|                    d	          }|rMd
|v rI|                    d                              d          d         }|r|dvr|                    |           gt                               dt          |           dt!          |                      t          gd |D             z   }	n<# t"          $ r/}
t                               d|
            t          g}	Y d}
~
nd}
~
ww xY w|	D ],}t                               d|            	 t          j        |t
          d          }t          |j        d          }|                    t          j
        d                    }t                               dt          |           d           g }|D ]@}|                    dt          j
        d                    }|                    |           A|                    dt          j
        d                    }|                    |           t)          t          d |D                                 }t                               dt          |           d           |r/t                               dd |dd         D                         |t          k    r.|                    d                              d          d         nd}d}t-          |d           D ]\  }}|                    d	          }|st.                              d!|f           t.                                          }t.                                           |rt                               d"|            	 t          j        |t
          d#d$%          }t          |j        d          }n7# t"          $ r*}
t                               d&| d'|
            Y d}
~
d}
~
ww xY w|                    d(          p|                    d)          }|r|                    d*+          nd,}t=          |          }t          |          t>          k     rt                               d-|            t@          !                    |          "                                }t.                              d.|f           t.                                          }t.                                           |rG|\  }}||k    rt                               d/|            (t                               d0|            t.                              d1|||tG          |          f           t.          j$        }tJ          &                                 | d z  } |d z  }t                               d2| d3| d4|            tO          j(        tR                     |||<   n8# t"          $ r+}
t                               d5| d'|
            Y d}
~
d}
~
ww xY wtO          j(        tT                     .t                               d6|  d7           | |fS )8ar  
    Scrape articles from Dr. Robert Young's blog (https://drrobertyoung.com/blog/)
    
    This function scrapes articles from the main blog page and all category pages,
    extracts their content, generates embeddings, and stores them in the database.
    
    Returns:
        tuple: (total_articles, category_stats_dict) - Total articles and per-category stats
    r   u#   🚀 SCRAPING DR. ROBERT YOUNG BLOGr   r   r   r   z"https://drrobertyoung\.com/[^/]+/$r   r   drrobertyoung.comr   r=   )blogz
wp-contentzwp-adminu
   ✅ FOUND z BLOG CATEGORIES: c                     g | ]}d | d	S )zhttps://drrobertyoung.com/r    r~   rf   s     r9   
<listcomp>z(scrape_dr_young_blog.<locals>.<listcomp>  s%    /j/j/jX[0SS0S0S0S/j/j/jr   u(   ❌ Failed to discover blog categories: Nu   🔍 Scraping: postr@   r   z post elementszhttps://drrobertyoung\.com/z(https://drrobertyoung\.com/[^/]+/[^/]+/$c                     g | ]K                     d           d                     d           v .t          fddD                       ILS )r   r   c              3   F   K   | ]}|                     d           v V  dS )r   Nr   )r~   r   r3   s     r9   r   z2scrape_dr_young_blog.<locals>.<listcomp>.<genexpr>  sL       /l /lDttxx7G7G/G /l /l /l /l /l /lr   )r<   z/tag/z/page/#r>   z.jpgz.png)r   r   r~   r3   s    @r9   r   z(scrape_dr_young_blog.<locals>.<listcomp>  s     &m &m &mt'+xx'7'7&m':dhhv>N>N'N&m ,/ /l /l /l /l/j/l /l /l ,l ,l&md &m &m &mr   z potential articleszFirst 3 article links: c                 8    g | ]}|                     d           S r   r   r   s     r9   r   z(scrape_dr_young_blog.<locals>.<listcomp>#  s$    7g7g7gT8H8H7g7g7gr      	main_blogr
   r   r   r   Fr   u   ⚠️ Failed to fetch r   rs   r   Try   r   r   r   r   r   z
                    INSERT INTO dr_young_all_articles
                    (title, url, content, embedding)
                    VALUES (%s, %s, %s, %s)
                r   r   r   u   ❌ Failed to scrape u.   🏁 FINISHED DR. ROBERT YOUNG BLOG SCRAPING: r   )+r   r   r   r   DR_YOUNG_BLOG_URLr    r   r!   r"   r#   r$   r   rQ   rP   r(   r)   rT   r+   rZ   rW   r*   r   rU   r   r   r   r   r,   r   r   r   r   r   r   r   r   r   r   r   rX   rY   r   r   )r   r   r0   r1   category_links
categoriesr3   r   rC   urls_to_scraper8   r   post_elementsr^   r   linksdirect_post_linksrc   category_article_countre   article_urlr   r   r   r   r   r   r   r   r   r   s                                  r9   scrape_dr_young_blogr     s0    NN
KK5666-< 17BOOOX]M:: s<a1b1bccUU
" 	- 	-D88F##D -+t3 -;;s++11#66r: -0R R -NN8,,,XZXXF:DVDVXXYYY ,,/j/j_i/j/j/jj - - -CCCDDD+,-  o o+c++,,,j	|C"EEEH >>D !MMG1D1DMEEMKKHc-&8&8HHHIII M% , ,c
;Y0Z0Z[[$$U++++ !%c
Cn8o8o p p  !2333 ! &m &m} &m &m &m "n "n o oM KKMc-&8&8MMMNNN  ki7g7gUbcedeceUf7g7g7giijjj>AEV>VgCJJsOO11#66r::\gM%&"$]A66 @* @*4"hhv.."  NQ\P^___ LL!Z[!Z!Z[[[!)k7TV_d!e!e!eJ"/
"O"OKK    NN#O[#O#OA#O#OPPPHHHH
 )--d33]{7G7G}7G7]7]
;EU
++$+777: 8DDw<<"44 LL!H!H!HIII "LL1188::	 _bgaijjj ^7=4N$4'72 ^%ibg%i%ijjj  %\UZ%\%\]]]   ['3y>>B	D D D "m!#&!+&ZMZZ;ZZSXZZ[[[ 
=)))) -CN=)) 	 	 	LL;;;;;<<<HHHH	
 	
:
KKZZZZ[[[>))s\   D%E 
E?%E::E?%I"Y2P;:Y;
Q/ Q*%Y*Q//G/Y
Z) ZZu!   🚀 STARTING MULTI-SITE SCRAPINGz$
=== PHOREVERYOUNG.WORDPRESS.COM ===z
=== DRROBERTYOUNG.COM/BLOG ===u#   
🎉 MULTI-SITE SCRAPING COMPLETEDzWordPress Categories: zWordPress Articles: zBlog Articles: zTotal Articles Scraped: u"   
📋 DETAILED CATEGORY BREAKDOWN:z
WordPress Categories:r   rH   rI   rF   rJ   r   r   z"
Dr. Robert Young Blog Categories:u     📁 c                     g | ]}d |v|	S r   r   r   s     r9   r   r     s!    AAA#S.AAAAr   c                     g | ]}d |v |	S r   r   r   s     r9   r   r     s!    <<<<<<<r   u   
📊 SUMMARY:z  WordPress main categories: r   c              #   L   K   | ]}t                               |d           V   dS r   Nwp_category_statsr   r   s     r9   r   r     s6      EyEyhkFWF[F[\_abFcFcEyEyEyEyEyEyr   z
 articles)z  WordPress subcategories: c              #   L   K   | ]}t                               |d           V   dS r   r   r   s     r9   r   r     s6      BuBuehCTCXCXY\^_C`C`BuBuBuBuBuBur   z  Blog categories: z  Total categories: r   )>__doc__rX   loggingwarningsr#   urllib.parser   r   bs4r   sentence_transformersr   sysospathr   r   dirname__file__database.dbr   filterwarningsbasicConfigINFO	getLogger__name__r   r   rO   r    r   r   r   r:   rn   r   r   r   cursorr   r   r   r   r   r   r   all_categoriesr   wp_articlesr   blog_articlesblog_category_statsr)   itemsrC   countrm   	main_catssub_catssumglobalscloser   r   r9   <module>r     s   4    				                    5 5 5 5 5 5 


 				 RW__X66== > > > & & & & & &   ! ! !  
,6    
	8	$	$ 6 ; 9
: 
( ( (Tc
 c
 c
N 	.//:$ :$ :$z ~
kkmm      E E EP(* (* (*T]* ]* ]*H0 	
KK3444 KK7888,,..N#N%:%:%<%<"K" KK2333)=)=)?)?&M& KK6777
KK>^)<)<>>???
KK4{44555
KK1-11222
KKH;+FHHIII KK5666
KK)***,2244 @ @%h.:F>>>(>>e>>>????
KK5666.4466 < <%:h::%:::;;;; BAAAAI<<~<<<H
KK"###
KK  FI  F  F##EyEyoxEyEyEyByBy  F  F  F  G  G  G
KK  Bcc(mm  B  BssBuBultBuBuBu?u?u  B  B  B  C  C  C
KK[cc*=&>&>[[-[[[\\\
KK  Ass>':':SSAT=U=U'U  A  AYdgtYt  A  A  A  B  B  B  

 v 

s   ,JO# ##P