From cb7c463f981311192003fa8231da192079be07fb Mon Sep 17 00:00:00 2001 From: jwkim Date: Wed, 15 Jul 2026 09:08:56 +0900 Subject: [PATCH] =?UTF-8?q?feat(generator):=20AI=EB=B8=8C=EB=A6=AC?= =?UTF-8?q?=ED=95=91=20=ED=8F=B4=EB=A7=81=20=EC=95=88=EC=A0=95=ED=99=94=20?= =?UTF-8?q?+=20=EB=A6=AC=EB=B7=B0=20=EC=9A=94=EC=95=BD=20=ED=8F=B4?= =?UTF-8?q?=EB=B0=B1=20+=20=EB=B8=8C=EB=9E=9C=EB=93=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B3=A0=20(shorts=5Fall=20=EB=8F=99=EA=B8=B0=ED=99=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - naver.py: AI 브리핑이 하단 lazy-load 되는 특성 반영 — 섹션을 뷰에 올려 본문 불릿이 실제 로드될 때까지 스크롤·폴링(간헐 빈결과 수정). 리뷰 크롤·요약 함수(fetch_reviews/summarize_reviews) 추가. - main.py(3): AI 브리핑이 없는 가게는 방문자 리뷰를 긁어 Gemini로 요약해 소재로 사용하는 폴백 추가. - 각 엔진 fonts/brand_logo.png 추가(상단 밴드 제목 옆 로고 — 렌더에 필요). - emile 잔여물(generator/data/emile_*) 제거. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../generator/animation/fonts/brand_logo.png | Bin 0 -> 14971 bytes backend/generator/animation/main.py | 20 +- .../animation_greekroman/fonts/brand_logo.png | Bin 0 -> 14971 bytes .../generator/animation_greekroman/main.py | 20 +- .../animation_samgukji/fonts/brand_logo.png | Bin 0 -> 14971 bytes backend/generator/animation_samgukji/main.py | 20 +- backend/generator/naver.py | 176 +++++++++++++++++- 7 files changed, 219 insertions(+), 17 deletions(-) create mode 100644 backend/generator/animation/fonts/brand_logo.png create mode 100644 backend/generator/animation_greekroman/fonts/brand_logo.png create mode 100644 backend/generator/animation_samgukji/fonts/brand_logo.png diff --git a/backend/generator/animation/fonts/brand_logo.png b/backend/generator/animation/fonts/brand_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a0a5a944df917f0fea59f38e661e7ce7059b61d3 GIT binary patch literal 14971 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%0A98Wo8Y!aDT52 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%0A98Wo8Y!aDT52 zJO_D&ea6ADjmAfWEwwrlMC1Z9E^$q~YXR|n9-e65(y z4-DNE*~?aFZl9Q33TRI5Xw>!=cKkJXg?)XeOJ>01=<>=!uph3 zUu@yfjLeRWCI>%ssSywgnC;>alkl;Gpw`n&3l|divE0WtY>h1XgO}tV#?872?tgxc!f;8{&t8B<_3tpIxPQjxmLb;0ppuMkAi7Ey^z=AFe1^hJIGg=bSaFdwKCc;>9r94CowJ zzi_?uOMT5a&RJzejQAm`$KTOhJm`Ys8!SKgST8RKt%mywJOzUoLeAi~0L_1|187bu zJ@X7&_9$Of!hF_KCiEN^3Se7q&wBKD26&6bsRH`_9Z@Vo{e_>4lxalzcV*S18|;zv>rk7i8493J1SQeHr8otU2R7TgJ=> zsMFd&Su-s%W8^1MU(Hpkw++)bCh9O<1sn@oRrA&=6KA@M0G(cbyd^=fZq2B-s(t%3 zbOS@fgT>|evJun_vK7%j11nqKAZcerY)%<6r$z=rFkV|cXiV>a4JH}1pTwLD7}RTw z!8PJ-7G|AgKQn&hq#pZc_9wK-FMcV;&D7rd9pk^%YH2SSXWi$nG7^DjLk-zv4(cfW z7@Gy}7gg=CMB>>Pzk}ScD@EM_UNRc-*s20Hq;WsS27i2CZTOs}h({;ZoP9f&2 z^qmlt)oqq7Sw{>Q@+Pa+W{V~Ah@Xtdvw2yrHcJMKszx|r0-D*kmsM6hOF)I~uFcXq zvf0N9$MPp->~jz$y8c_s;=n=377T5Y9Pqs1CN=$GLVVQYY*VLU);TY~4}Y>5agTMC zgS@;3wtZ$-TRjy$BvufJd!fx8-L7Z%v)|X1T&>l9Io5LG-;UJ1cvD0j1E5jI{Cg=z@NCB`PYKVXk<4v;LW~bByDor(|PI;Cp%yL$}W)* zJ;l@(qQh|WycTJjBgfdMM{b zltf+XJS&_Uw?ZfG?9$O|O^P@E%n<0pJ@vJ=Qbf_83d%f_UAU^?SQ5Z)v6z|FvM!eC z0lV$e(N&mb(wzieoy_q^$bkhqu)7&s=<1?l-_oY2;JW&CKc=;RgVqmdAQ>uGfwj$f z>Fv;KW{KlfeuvWj&b8|gntPsRw zL=wyPmlHU)O8WO~DokBo4vl#!8+b&9gL6Um5dvPyPFB^(aPIA&&LlRZvU zhYrq>nUUXp-kzOLu>yzW=*En@`pN#2tX1TpLDX`4b2ognymijf|C z>c&Z~g8xo<=~??i&^blQKPow^{2&MthV->H&Cxk)bKm`EEJnIF2PLS5|*s*BJ?;T-{a*a>PZZzBxAV5Q>m4G!;eY)0;<@F9Di-{ zVuKvFI6)F>b1*ex(yA1bf!R|9xQ>yfr`fYfnJ!=YTb{_m)`BMom4^}H2wVuWn{LA%CVkOteK%W zQhy(hWYDd|t;@U6#9s(M-(A3cDL{Q-l~_AD)PNPjJ@=UkVKeU5BFAtWir-G<;`P|Q zcVWd~Z|zXo5z#`w7S7*(97;2@{i*9!NPm}Bu$W@da$eKz8Tqk#i^yRt z%-|mZ$soF>d)nb%$21cg_+EqHINWSOTR^MsocGLe%B??JjDp@(=_7aDm3+$s)-tBa z-rmLPLVK|xWJQ&K3`e=e%1rhJ_ess$(puS&W>{5z9tHO>b0ruY4x@XI8U2AneAUNmO7ume1S9;5beG6v`EEadGg%j&hy(^ z-3>>*g{m!lYLWwdjdbLkbkm}G=eN|ko~f8Fe`cDR;9m`bm4TBnv1_);6Dobchs&v4J@WhscsA9V8ve>3II~T8!d>N-Yr2<8 z%ncj8g8r)e3|JahGM`E+@UHgQ8dB~||D-*2a4bzy3FF=uEp_7O%Pyx&Botb;jT{lW$|R=qK+W zNa;mzEy8GH$k6X}Usf4%b7+{cbSQ57afJ<2YXD|C4oPa9-g|NcOVZMxM zIwj|;i^_p6p7WK;2=^wX2{zcc`y0vnXE&nV-{cS-d^2uvy7^W{Gg~&61TzX^GuD0| z4&suSuMu*jo8vY9ni?$pY<-R|M?_9A@lCDt7_w?5u@Y1qwOZmJpAX}obl)g>z4NGv zU^N9U{Pg`qYjlC(DQU+ALTK>BIelfq4gNLt7?^qQ??P0o@Ro@UZilxO%y0s)ZgiFjz(mlQzt07}t zd5j5((I zSIJ+;?c8obYX^AGb^XQa{%=vaYyWiaU!Ag_1^a$gxLYRcS$_t;$adf)jeSanDT+c> zLN-4nzX>X8pu=LM#^(DJ%~no|MOEO?nWxB;2%K$y6O(3{V*f_+v@2J3SwM^*6+C&vzLi+xfn=i8rPBeRYbhOdo0D zR`7I$Tlyh~v@V9qo{1Wf&}LIhD81}HM=exa{|uUG zGR0Z@tRQ>GtfH4{i(9qvF;|*RgSY0?Q7d8R(UHYMsuQ(=0yOqNc%gAtCCAA5cOk6I zu*r)~ng*XKyB|G71}at8rnq2Cc;YcM)yq&So-Oyz&m^nLvSubIjM1%c*@8BSr_zJ= zAjk-&Z!-03J%8RGifRyk49`m+am@}w74xFL3AJN#T$LHyVcjy0%}FV)P})ZYr%p3I zSvrz@VM=ifh-!2S)4|>DFv&>kI0mExuWhNC$D4Y&dnW`hdT7JOi98MTGWrVikIKB= z#i(%m?{;3Z1D~=y51cA22mYoQ_Sx8m&>`g31D>i=^(?WZ>B*cu8H2 zJ5ms2+{N|1&ZS4VCkV+9Fr0ggMt+Has|@(l(sxX5Gfmx_S#U|7hTg1dt?l{m^;<;r zoT$w<3&=ByS@PVf~7Z$}oVW18Z{Zg@V;p!`9CvuetKtYi`Z z9ek>bO9K{ddoX34B>5@4KhEkoqN^dPZTPX+_Bl4eNqf3H&LAL}ccaSm7SXLLCr)z`=^HChX404E!{9iel&&*7*m+@iSPp%fuxG_(d+#oAyvh!eVdwS)= zhO2bYms!jicD8lb99Cb>N2RwZC`vUEA>GxCVn;z1Zi)YsarlF>%&}t4q*1w=7E|z^Al`6on7B}39z>@Hh;TH>i<~%CZ)BLUc&2Loy$cv ztprK6XfxJw@ZYrn=EU^yg5VBx3;hT zMHB03g2zC&w{q=lM1M~+gZP}yPdHX+GCC3dWCMfJUjLTl>7P|=XNNi3KdnsIUI=Do z3RH-)l{@%dempP7c9Qvf1t?H?zAf8QqR(GVGkhW6I?M0)re{LBwD}qK;m5fQg-}tW zh!81-#o+sTip}}b+i3Sq=O;@!#aSu&ZGN503qK65++`QjxtIlez{ zYkW}-ZdNevohO4N$JQx5YhQpW;x`Gn9V&2XtPMR$H7wLb6zeot6KQPC^jPg_=NeAg z;@Ud$^6^kNepKUa*GkB7C5eQISD~&u?IaT?s>Gw2Lx1F4eAF2p@&XwjZN2u}__S*- z37`U0(@U$F@-+;5%{=#lBCa9DFVFYili%E;=$x4JGfR(7ulo$7&6{+B0-)`*q?<$7 zv*MPLS}RN0%4II;cZ;mF`7pQ|f9sEPWU>ZpbHQtzhrhazZ{4oJNFR)YeD5`?$osfX ztuuGp-#E12SGAUujNDeZ+Gy`1rSvC{!sM~z4_?#yT?UXgg#FUT zlC&45EsIhDE(c+Cf&%5#C-yvl2Wsvy(vIUi`qy0D5;@Zv5$F64zw4eR=GrKjMc?PE za&E4~A{BT1|BzGg-amM-^KmJztZ7o(pi`?yNE5bj zAX_mvHYlGf-&Ne06o##mDKniq_hY$Iot;VGKoiyRL)U0WO?l!&L~mMDGHo)9OY&B% z%a+jUq}1d=B;I>blvM?@MgB1BbW%V7g%U{dtySD6sktgsbz{OKtPy4`G~*6LB!ubr-C5lEz~CiXOZneUwJ(*J~r=t*(x43bW`dy}UfR>46dyAqe zBHlxp)bSFs7kPLZ@??OoSyvCd#O%IFwNy4UwQo#KFWp^BJethQJmOpE(fGTn;$Lz_ z;jf3!fGa4QU9 zX#hd;-dsjYubkFD{;X^nDLztaleChvB^K7PNWzn}aie{XLzYl>cntR%(MC4j}0(>42GP<)_< z=9m`wAd(u}u#QcPxL#$&an4&l(BE;70;+^a|B8N&8o2}amE7?isQTR~dT@ohXNpH? z>*@C?Zx*K7iS$&OUgGQIAYn9rEFLzVk2B^`B@wedm2E(>#V<=XiFyBc$5$%q)u|ao z^~2M}^S8lfyGJo)>8gHCxyO<_L8x|}HJdI?i_~juN{hE#sqV$XCM(Y~2N|ojFEMg} z+G%wVnBn;Lm|~4?i9Ow6(OsAP)vtQ;^bQ1(esd>;hT5CxYY?NrwSi_PbhvAV;?&0N zkv=ULUgu=&M7dDzQ-|Zbf75H&f!_R4?i?9A#e~7s0koEUQoG0c zfcbdDVa8-Jt?t{v`3WJFK(x40SQ zO}FgEqy5FJKlvj80C~#TVlq}|dO(ZNO~e=02_LT_zb3hW>c+2AjOl3zq{3Z#(7CU> zW}O7Y$`mC&In=oie?aPjP0%Jsot#&$@$L-DZT>D2s6bJc(J~HaGS=|&D&a&@j4agne?>jz#H>DuHWgL-{qivRgdh_~ zldscDP$)AT7p%tS=^(L}Ypl9z@pZm$13v7J<5)p~n(*zih3SnHevq4lR_}dBhP`?O z6rRR~2^@Ox*=R8C{2(?gy7{^N`E_BmfHwL5d(JvvC(;Id#^f%4NtOeU6Mungo({fL zHf@Xu_{WwM^%=Y@RVE*2qma=}^qbWAhTt=VU3EfOT^ zk5;8~_U=tgR3EWMKLSZAAC=HW8F;Ml$AZKllUBY0_h!>o@AnkQqY(TG5g_-UBzSMP&*&3)=${E;G7PKPN2EdRk zmZ&oprSuvWXQr{Yw_b8HgqAfP87N|OA0TjaT&^dMj6u<8Avj9I$lfF;rHCG_Nn_J7 z@8+A=kwa$zyrlognjD1wEASd-@Qq1`lxsKzj0}af%g@u%29(w($`T@z#4@6i^MNq- zq(lG^sjXa(0NP6gB|JX-xX%C>Ma*U_YA<(sh+gbPR5Bs1!J>f3#v}Bp>>};Ly`x+? z0TY$4)`i#Bg0O?0qG-wM6`6`vBhdfhTk4EJs+(5&i<(z>=!lM`lx-*iXkG^P>@y+0 z%P!A<6eQpM=}o$bpzNkczW%L<9{igt|3lOz)fcT1@ENS*4@Oj~Z;M5rY;iN!66DDA zXG(cf3V(vKcKum=_*;#uzFj$gCjU0;l6fX+5#E1dqmGh@p(2KBTk z(Wvzp71|F98oXML+9fqpr>;HmFx~SbG2r2cA;KIaK#bO`qmgc`&ZJV5u zr5>(Mae29*P3C!y>{Ab#z=k6TM*fQvGu*HVsBuYlUiBq*{T`oA*hSp;!(YgrtS=zI zlp-EvUy_iGdbSd?^Dp>5LfTD-%wx8OY~%V?YB%JO1rropcm%t)3UxA_T|bNM?!0?x zymvc0-LzBg6_kFllMyR#qm9GJIwpQ*RPjNo?eZ}SK6U8ae;BaIUr|w?43Y}4vFjxu zzFBq6>&hmg75f^!K%0ZpK&8B z5OR#=f28bh{6s?dbIXo77zET+lk`R}?U9{w53kw%)87+63^)2$TqpC;!p3n9KX^56 zr9?zkD)^isRhaXO7*CvZw0QkQ}!9nv_{xV?&Mr?;4BlLy?+ z-3gw+wi{rt*`Eh>P&fzVR<#AI7@Bk3OT#Kr(5jSHPf=MIY8=E~m@vpsTW)uWtnhss zv2};8_;-p`6b;Xt7O<|xwuHR}*)C6S;skW?O11T0;wI7XUnoO}q6x`_ieVydGm@y7 zo#%0byxbd6dV1d9%?riwLf7IEH~ADO6e%?|Mul#IbDQT~@hN)5OdtouvNP~^TX|sv zt2YtQmZ4@|xq~Spe0HU4FJjj%x1%(wRDI1%%OEvD+K%xXmGl0YmPT68PpofFvyRfj zMspz5uWN+IYe-sFqhgsnyliIFqTlCoCe{C)$pMks=YBv{bOY!wy%m?+o&K3DWb^6j%GErk+X_y9ykWMzVl9>(6s?05w6Y z1LGv_dH>$lCGYja{gB!~Dvev1f$^1zH4oT0VN!=j?Duem#zVm(*aj8(h;GU z{RV1n)}KckFB0_%#MrXe+^VFG%%3^skAxoSHRS~`-Rc)<~t)2BoPHMr_TKo zOkFDv&?mtPdq95~i2+sWkMDsFAd^6Cn{H{sTI5MIcY)HV07VLOg}+<4nUeGY4g&mN_up*-MFVN{ zmD5TY-MFxU{Wo;&ODkh>Sl6BORFKpzbG$A4E)F(^*(+W!!K|22a|%~?;~@6?9n@{? z5%Te~Ha#ETicLt4tF*~Ujy7y!I^c}~tnfULjNf*Ea>5>4&Dy&3aJ+4kI``@R7X>M( z)9=DcMIhUo4Ji%pan(ei_&Ht@^{MtHak?3K8^yT)RYfH#u0@SU9!*R#a=>SYk`#iG zj4A5z@911dEuhDTPJDPotIhqhS&NKztX)i4s=)CN$80x70fxg1PMfUp2rO!pPGo@C zW&D~>vwqZRu+W*hO8u!uw471UKZzYKXkxHp>WwIG{Yhy;lcIp35M1|V=RuHi6mLki z0gpjsVf$sVuH`#f!QA#ugAKF>?29=)Pl`C(mr{z;o#IrDRloe7xb!nJF+-mR{wB3O zDV%K@0LOpmN#5IZ-YzDAlAUsWPoRa-5)!(V35+L4d;+9~*E-H-UMtBO>i?|;49sJZ z?$IN5?&K|6n*(ht_DCf;=FBU>dj!)FRf1`r5Bm?L@>hXW&wzvT#YnHLciAI)U{!3y z7$HYfRY!r>{>SGjn$wy@^ppUThHFW7Px;Y422zTbxauF9&5EW(1yYHA3UcN=A4z9$ z#<8MkULN##_6b%!DAY=4|*#Jqy^D0h16pDOUSU; zA${6}Jb$Hem$$Un_AP4CfF!2xFm51b97N#uzj`=i+Lyw3uu1X22e6tfvhEr38AA{g z`MYf?R)MJdr<497);dsy3eUE5eg`D@B;E-EPI6g6Y6!J2X;8)}|F%FC)CYW84SqX2 zP{0P%f%J2q=-CCJHY(~|PTd}uj4;uy>BA=9@y!wLuDzytikZ|*Fec@JVI7fZlHc6u zaR3Ho1hDJJ%s(KI4BYpH{3kZA8?2}dd0Y(3d;!oT9WHHa9LESn*JMx09b}aqzU>NS z@sqMS4}=ZV0{CJXhUO0wFz5HDQe6Rop-do&ml&+2trosFGjNXV(twZ83AT^mpaOfg zYj%djPHN);!Re`El^UU<`9Oi+wi|Eqe$CVAy>1)}ACUwZ!#R~VqKCUWd*~elr<~(a zWX`6)!AkbxwP6fjL()|bsshfReMOAzCvLsBVLMFB%6-+`Vsf=cy0iMTy$R*E*bdEc zw2%4|!qPaOTs7Rd1@Z=%pu95uBXwN_{a9JI{3~#97)?LrcsQC|vvgkU4ubL3s1ZZ@ zIRfXH`4^=K{QjTBKLua@Qp+p$&EQ|6h4Y#ArFI^yln~g`fb)YYwHTd12i4Sc(EP!l z7HjIHhZhv&@;hpI(XV6>Us>UTZ3Bs=lz?O-&fNxN3k2bd%Zt3FR_@X!X1>TMR^D}m z-YnY9({Z@G=2;`${M#3^y}nA*O39J6QFG8CK&lkkJa!24bUAkn9=_^o*3bW~wkEJd6xtRJ`QQT8e_5_9WvW;1QbRp)fNTdUjCDeb-t$pJ`H!=_~cj@@a2? zEFdWIg=rQ@9{Qn%jjX7#HiMDM$Ry}Z9Nrs|V3nMIncf3{T5wz;h}Bfu>(Ed$ukZxz zkeVLIskBfND||hSji_JR*((o0s6Y}jY_)BBWQqpG%cew4TtDBhWXaVw#s**iWsqQX zQ)}Q+=^io)WS}P^O}mp1sBJw!s5sue$>MZ6vBC79jfWb6#||nJYP7PiQ-br%Zhc!k z0P}il+O+LUa;63Zm%+EOF>FLwudS{17?9f_2>skNt5jg7@GBd7)ppISZ1CYps<3=ExQG4RJral)pf$Ug{g3?&$G{)d zP#D{Cq6I?9gF43X!b)<^X2LVTnkL{kP9#_ry`=;{WM61%kTE^{`<$X<~)*_8*|tpY*>Y8xv~ zchMJWCPLKpX#akrF@gmE1r9zS*BS-19m{$br9K z8c!BI$@haz_+6uhs^<7e)EqMC4}2j5ex2#FhK(=Ae&kd($5VyLilE1m*@#h|oHn=T z>G08p`k}$x*sg>05oM-}5L9*A=5)=Iw#m7&wPn|_XNiV`j*$IHMnRieU=J3bfjaS$ zn{jFp=5N!Tau~q4eaEY!p6GyQmC&zqx!!G~Uq_n=c?G4N76i>fi_ZWPU&9k3@+&>i zbE*4mGDM$Y+GslK&rHr)Z}&_rCIvB`or+`#gG2@3R~!?$-+`!>(J}n%X~D(ru>C-m8$>eoPUa8#(p;>5{z#GV_=T@+l@oo^FOZ<1q9Hx@Q-V*E z(`6iy!UvvQe>)oZKtC?%=SCGx$zu9>Jr_8}*Y<9VR4Nm!2mZ#%y5P@?@Dr{8G%A*% zrl*{sPnVovwG;z-ue^=h>*$>`a23IAS~-F#zSqgy)7|Tj1<2!84(P@Tm)Ov;`hmm6>6g0J0uC>&B(NYLr(Xa* zy#p91B#lwf%)l2=j<))av;lC6xb402WFNLh=o7qzMJ!eT#~x1bFZOx7<_<1bSmrs~ zQSZG5kWRb7iKgVl#{7!H8H5mg`oY6BWDi%oMo}>O9N&q3&{oRceBo&G>UiBb2oz{WI1!9U=+uYHNQKE;B@iJp1=XWFG1A%D`^oyrDWK@ORG(LsR z6Xka zKYe+q#^cmSq1A$8tLI-)G;mx;hMjdLzfb>nKE=57FC7s;fq)2=`zJ8yo4oPbz{8B<30qe@#v6yW8@7e=2QVk``NA}xe4Iq zH^4HC0{>C;J6t788#fHZKlz`Ek?d2`JZ`@-!blO)%Ms|0xnicMa1uYvGH`d#0(<*D6+1aCXS250 zbKalQlj9$m%=dt=-mJQDb=O0E6y5Z|;Nkj4qw8`2?U!#rG&68jf%f(z?x9ETm5V0v zCV*pawXULdGm8c7i61bR8b}Zt8YYbbB~}yhW+*v9vGgcLlXYtfWAvb$UFpkcdA{2h zu`B2gY{WpoUbLB&V*xoIZW8n1v)>A!3u67L?9dYq7VSySO7b8@Ra3;b6fgOLV-(KR z+lBhgj;re_0iOV3S7XX&z)*h|FcylMx|hPmL@sy2+)dH;?x)f(kH`bc2#Wc%J_?gR zsrINsObX2b8|TS4@b2c$`_wC6g)Aoi`vffdT(2Fqv^Oo+GeIxIk}|GBntVX_q~1K| z@#;XH-I|Q@el>oYInFAMVf{(4M z*-u_);)gwoxqyc4G4d=HL%rL5K!L2B&5FeY8$)bk6C@3|pr974F0BkTWnJ#sm-fHi z(zX)=1=P0R*ole$Cv7W*ZY_!1I_uTWc;<~HUJE|54HzBHwL2dHGevfERt0R?azmX{ z!bMIt_?vXDxJ@+KKfwyc3NT}94eT@ow*V6ZCqS{{+qo7kft2MOBqsrA$H}=)Cu_*D zh|?^f)GE8&X2SOSQv@IO-!e$L;CUJFyflwHB*>)X(cezYe6JT>Za5-O)P`VZ++p{@ zdR{IcKl4_ceL$=|_n7<+jXWO$suRy8kg?LmOkZYn9&oUuvK@yN%3J}cve%f1^Uwb? zkTe0k`C))nu=Z3?>u+RNp%fQ002*$UKj1U*T=nJ1i~}`Repi{$4LUiVxVg95Hl(}O z3_LPH3d4S2^pdsTu)wPD-(ya>9~A!=wgo)_`z?SW{Z$l_M_u#++|SzrWPMvYrxJIDPxJAd)fB2 zo}4!U83cvBo@y8$<~=_@L(d`O#MBj3knmwiSGyN)vS#;SjExxFrP|95yEkXXM7WX% zD3u`;Dg(qq`J-&pxba-*RH;RIO;T|{TGnSC2z5J{n;e;y;+l{_M+C!nv{v(1&y(En z>As-O)*%+yxY8?7tQObAFaQ9dB^`Tr!;PVYlw1_Ad*_|FR&Pd#p=S6?FiB;+DRm6Z zO?B!r`CiWiLGaS(2~IedjN{R(>z}?C0Pw6K8zI$Q@{v7kQ&5(d>kR^a`fvurC1 zll_)kk-VdCXLP#hPtZO@rkhq|_OPzke&!XWcw#bv!cBzZ1Q+6D&vOiX+SHW|Jod~? zqLMjhqIjppss-Zsnv~W+Y2cdY56)3CWq7W6TtnHUxc`qVW;*__KrH6@>2>j2Ir!H_ z9J?W>p&qZ2OumX#zkW73u?+t;UAVEX%V2=p&R?NOM!~Kad9tJ~CK*O}EU^Lz1)lsi zWOAyX=3dOmmR3&;3^77Q(e~91T5vih@fpS7_FBpR?y=cO?i>l#GbD!#G0i)4@`8a; z$W_phq!r#xd5Zpo;3x_kGKmY`WQGvzkBc(MY&zn?ezSk|$3rmfFxYsT=A|x{&vASW zAN!+vsn||tfEmPUe?)xxnbSF%527NI@*kzjhn)Z<@?->fR!rFM?n+y*6Dg_Zj`!d) z*zcUIPYC}<8$M-Wt%kx@ZmBV;-V;J>NpoUSoT`3z#s3kmK>Uf|l-VL$Q@0dv;&jaw zqBxZO(u>QkzYU*@00;C5X?tJQ9!L&W`k&+)0ZGfw0GMo8j9i|BVmim;5*Iy81Es9x zs5RJ#%hEf=_QH|rBgFKP+Qn#*NMvlZ(1)do zJrFpuH417=aoLoyRdOGco1__uW2Ou~es9%^3yDS}Dpw^_@tJRYoWECqs^ zEcW`JaQ^e!C}T1CZs2?zow9L39iz0vhelr%;W7;r4^z*Zhp6&?X8{8%?&1r$Vlz9hpZ!e@~*u}e<5Dd0A{;F z2X0pH%XO4s<4{%9jr%&GtWI`yQ(sKvc@{K0SU;|;g z0BXN^{r!t2=Ik1atl}kdGuy|8_xazotk>jDoP;JnDLlADxWY25_8=KL!>~e^WSFs0 z)#NY141ewao)X7_H4Ha=sKAvGp&KQC0$fd=`DPq6`=6uMTWwe2chwIqYeF8g^!$O^ z1l@{6_m4h{dTK+lYH&6s-Tt;b-)md7+ zuF4UD@a5p67C8R zPpjV{Kd5+<5?C(*pb(0pe87OtmIilJ^;{R2xtw}ulYX3Q+E`0B-B)*>|EZefFPBIr z@&E~LL=V||-209qnG#InJ`{{`zO9fy8yoyfGua=UrB-@WN+?vG_xN|u( z6R#XYpYeB0pz?hETr|gjJ#L{w-*fzq64JZ}u`}}?7;~u@&@d#^B?NHcg55n&smOcB zG#q*=<(ZB3ZnM!KJ^IKU+8sSD8PmJgDE0X>x-5g^9!HhE1mAou6XYI_@eF)k-*J|e zr~8}LKwhpF5dNYK;T@8AwdH5RO=-hdM2BX%+8f_m(w-%akSWCjapsW3#iM1S7#z?& zbxi*cbwY51@%vJm$N9_u-GtMBMwsfKGg@=R9i;eop^B77y^+uHY;7`e)8z|v;EU_q zRRh)rcYKn`a8+KXH$ASoavROx0{;w|@XDYi?M=*9WBjQ?>)Kci_#0ZrtD>3N!F6B+ z|C&&?N6M43k2Nk2?a~-U*AA^qk@l??IDB3#-7ZG=tcpQ7ES$|+KPz#=;X-6`aDxeM zU}an(@d&NjO-gLBt(wfI&z(`Pd9@FJ3APeL!~b+}J-cOo@wOdhx94%wU9}&NN}k!A z2iK4F0i`~|O;XVVYaxr4_rEY{Nel6c9;xr zk?qCl#zr=(5mt{NbktU@Awu(2!BP1J+9{9ovV$xq+|XO@;4-iz>rf zZSXvC(_+B;2K&AR>K$zNzvq(ow=h40_7_L8}Ew3N$Z-FIvQ(q8U56L!lxoVWDL5`_#<0$1) zZEZ6QG2>H73X;4bf~M6inAFX>?mb6Mk2S@Odx!FTYqkBO{&7A2-Rq+Bmkmxz@0Z8N z4Y8SR8Ms%OrW%r{Wthib$y@Sef%*R1oXx)+T3~K%qpz|nwK!I;N>r>pKBii&R2>{v z^Gmm7h3`xk6g7%JyjwGYIA>r zq6gU{(&o-%+kP0ihf&)H+HtNP{(k8Pm*NNn7tu@qNG;O2ct7K=s(Kn7Z?9Or3yQLe zo9`MoR+u4RP#z>DIoH$K5AIVc;TNeoW zrtJ-IW0_NRh|aj;LkdxsR>SMLZwm*Lk3AC9ULPc*eYNN#%#yELZoiWR*{ZHxC3*I7 zpk5E^vTiwprA7f0`tRs~+T|`S{zzs9Wr8RH&c37v_;%7T_jjm@N?@9AQhDO#;=8jN zK}x!!hxA0-_9FiuI!{J?u&{CP)&;naEDCxnTy>P=Pb9;euiYvC%0A98Wo8Y!aDT52 zJO_D&ea6ADjmAfWEwwrlMC1Z9E^$q~YXR|n9-e65(y z4-DNE*~?aFZl9Q33TRI5Xw>!=cKkJXg?)XeOJ>01=<>=!uph3 zUu@yfjLeRWCI>%ssSywgnC;>alkl;Gpw`n&3l|divE0WtY>h1XgO}tV#?872?tgxc!f;8{&t8B<_3tpIxPQjxmLb;0ppuMkAi7Ey^z=AFe1^hJIGg=bSaFdwKCc;>9r94CowJ zzi_?uOMT5a&RJzejQAm`$KTOhJm`Ys8!SKgST8RKt%mywJOzUoLeAi~0L_1|187bu zJ@X7&_9$Of!hF_KCiEN^3Se7q&wBKD26&6bsRH`_9Z@Vo{e_>4lxalzcV*S18|;zv>rk7i8493J1SQeHr8otU2R7TgJ=> zsMFd&Su-s%W8^1MU(Hpkw++)bCh9O<1sn@oRrA&=6KA@M0G(cbyd^=fZq2B-s(t%3 zbOS@fgT>|evJun_vK7%j11nqKAZcerY)%<6r$z=rFkV|cXiV>a4JH}1pTwLD7}RTw z!8PJ-7G|AgKQn&hq#pZc_9wK-FMcV;&D7rd9pk^%YH2SSXWi$nG7^DjLk-zv4(cfW z7@Gy}7gg=CMB>>Pzk}ScD@EM_UNRc-*s20Hq;WsS27i2CZTOs}h({;ZoP9f&2 z^qmlt)oqq7Sw{>Q@+Pa+W{V~Ah@Xtdvw2yrHcJMKszx|r0-D*kmsM6hOF)I~uFcXq zvf0N9$MPp->~jz$y8c_s;=n=377T5Y9Pqs1CN=$GLVVQYY*VLU);TY~4}Y>5agTMC zgS@;3wtZ$-TRjy$BvufJd!fx8-L7Z%v)|X1T&>l9Io5LG-;UJ1cvD0j1E5jI{Cg=z@NCB`PYKVXk<4v;LW~bByDor(|PI;Cp%yL$}W)* zJ;l@(qQh|WycTJjBgfdMM{b zltf+XJS&_Uw?ZfG?9$O|O^P@E%n<0pJ@vJ=Qbf_83d%f_UAU^?SQ5Z)v6z|FvM!eC z0lV$e(N&mb(wzieoy_q^$bkhqu)7&s=<1?l-_oY2;JW&CKc=;RgVqmdAQ>uGfwj$f z>Fv;KW{KlfeuvWj&b8|gntPsRw zL=wyPmlHU)O8WO~ len(res.get("bullets", [])): + res = res2 + break + await browser.close() if not res.get("found"): @@ -191,6 +207,150 @@ def fetch_briefing(url, headful=False): return asyncio.run(_fetch(url, headful=headful)) +# ============================== 리뷰 크롤링 (브리핑 없을 때 폴백) ============================== + +# 방문자 리뷰 '본문' 셀렉터. 네이버가 난독 클래스(pui__…)를 자주 바꾸므로 우선순위대로 시도해 +# '충분히(3개+) 잡히는 첫 셀렉터'를 쓴다. ★ 최다매칭이 아님 — 작성자/메타 링크(a.pui__GStJHb 등)가 +# 더 많이 잡혀서 그걸 고르면 후기가 아니라 '작성자 이름·리뷰수'가 수집되는 문제가 있었다. +# 리뷰 본문 전용 클래스(.pui__vn15t2)를 최우선으로 둔다. +_REVIEW_JS = r"""() => { + const SELS = ['.pui__vn15t2', 'a.pui__xtsQN-', 'div.pui__vn15t2', 'span.pui__gfuUIT']; + const clean = s => (s || '').replace(/\s*더보기\s*$/,'').replace(/\s+/g,' ').trim(); + for (const sel of SELS) { + let els; + try { els = [...document.querySelectorAll(sel)]; } catch (e) { continue; } + const texts = els.map(e => clean(e.innerText)) + .filter(t => t.length >= 8 && /[가-힣]/.test(t)); + if (texts.length >= 3) return texts; + } + return []; +}""" + + +async def _fetch_reviews(url, max_reviews=30, headful=False): + """방문자 리뷰 탭에서 '더보기'를 모두 펼쳐 리뷰 본문을 수집. (가게이름, [리뷰문장…]) 반환.""" + async with async_playwright() as p: + browser, ctx, page = await _new_page(p, headful=headful) + + await page.goto(url, wait_until="domcontentloaded", timeout=30000) + await page.wait_for_timeout(2500) + cat, pid = extract_place(page.url) + if not pid: + await browser.close() + raise RuntimeError("place id 를 못 찾음.") + store = await _store_name(page) + + # 방문자 리뷰 탭으로 이동(구조에 따라 /review/visitor 또는 /review) + reviews, seen = [], set() + for tab in ("review/visitor", "review"): + try: + resp = await page.goto(f"https://m.place.naver.com/{cat}/{pid}/{tab}", + wait_until="domcontentloaded", timeout=25000) + except Exception: + continue + if resp and resp.status >= 400: + continue + await page.wait_for_timeout(2200) + + # 스크롤로 리뷰를 더 로드하면서, 매 라운드 '더보기'를 눌러 본문을 전부 펼친 뒤 수집. + stagnant = 0 + for _ in range(16): + # ★ 리뷰 '본문(.pui__vn15t2)' 안의 더보기만 클릭한다. + # 페이지 전체의 '더보기'를 무차별 클릭하면 사진/방문정보 더보기가 눌려 + # 리뷰 목록이 통째로 사라지는(0개 수집) 문제가 있었다 → 본문 내부로 한정. + try: + bodies = page.locator(".pui__vn15t2") + bn = await bodies.count() + for i in range(bn): + mb = bodies.nth(i).locator( + "xpath=.//*[normalize-space(text())='더보기']") + if await mb.count(): + try: + await mb.first.click(timeout=400) + except Exception: + pass + except Exception: + pass + await page.wait_for_timeout(400) + + for t in await page.evaluate(_REVIEW_JS): + if t not in seen: + seen.add(t); reviews.append(t) + + if len(reviews) >= max_reviews: + break + before = len(reviews) + # 무한스크롤 트리거: 문서 맨 아래로 점프 + 휠 + 대기(리뷰 추가 로드 유발) + try: + await page.evaluate("window.scrollTo(0, document.body.scrollHeight)") + except Exception: + pass + await page.mouse.wheel(0, 3200) + await page.wait_for_timeout(1100) + stagnant = stagnant + 1 if len(reviews) == before else 0 + if stagnant >= 4: # 4라운드 연속 새 리뷰 없음 → 끝까지 봤다고 판단 + break + + if reviews: # 이 탭에서 뭔가 건졌으면 다른 탭은 시도 안 함 + break + + await browser.close() + return store, reviews[:max_reviews] + + +def fetch_reviews(url, max_reviews=30, headful=False): + """동기 진입점. 방문자 리뷰 본문을 '더보기'까지 펼쳐 최대 max_reviews 개 수집. (가게이름, [리뷰…]).""" + return asyncio.run(_fetch_reviews(url, max_reviews=max_reviews, headful=headful)) + + +_REVIEW_SUMMARY_SCHEMA = { + "type": "object", + "properties": { + "bullets": {"type": "array", "items": {"type": "string"}, + "description": "가게 홍보 소재로 쓸 핵심 특징 불릿(각 한 문장)"}, + }, + "required": ["bullets"], +} + + +def summarize_reviews(client, store, reviews, model="gemini-2.5-flash", n=4): + """방문자 리뷰들을 Gemini 로 요약해 '브리핑 대체' 불릿 리스트로 반환(실패 시 빈 리스트). + AI 브리핑이 없는 가게에서, 브리핑과 같은 형식(짧은 특징 문장들)을 만들어 나레이션 근거로 쓴다.""" + reviews = [r for r in reviews if r][:40] + if not reviews: + return [] + joined = "\n".join(f"- {r}" for r in reviews) + sname = store or "이 가게" + prompt = ( + f"다음은 '{sname}'를 방문한 손님들이 남긴 실제 리뷰 모음이다.\n" + f"이 리뷰들을 종합해서, 가게를 홍보 영상 소재로 쓸 수 있도록 핵심 특징을 " + f"{n}개의 짧은 불릿으로 요약하라.\n" + f"- ★ 첫 번째 불릿은 반드시 가게 이름 '{sname}'(으)로 시작해, 이 가게가 어떤 곳/무슨 메뉴인지 " + f"한 문장으로 소개하라. (예: '{sname}은(는) …가 유명한 …맛집입니다.')\n" + f"- 나머지 불릿에도 맥락이 필요하면 '{sname}'을(를) 자연스럽게 써도 된다. 절대 'OO식당' 같은 " + "익명 표현으로 바꾸지 마라 — 반드시 실제 상호를 쓴다.\n" + "- 각 불릿은 한 문장. 메뉴/맛/분위기/서비스/특징 위주로.\n" + "- 여러 리뷰에서 반복되는 공통점을 우선. 한두 명만 말한 지엽적 내용은 제외.\n" + "- 리뷰에 없는 사실을 지어내지 마라(과장·거짓 금지).\n\n" + f"[리뷰]\n{joined}" + ) + try: + resp = client.models.generate_content( + model=model, contents=prompt, + config=types.GenerateContentConfig( + temperature=0.4, response_mime_type="application/json", + response_schema=_REVIEW_SUMMARY_SCHEMA), + ) + out, seen = [], set() + for b in json.loads(resp.text).get("bullets", []): + b = re.sub(r"\s+", " ", str(b)).strip() + if b and b not in seen: + seen.add(b); out.append(b) + return out + except Exception: + return [] + + # ============================== 사진 (크롤 + Gemini 비전 선별, 인물 제외) ============================== # 공식 대표사진 CDN(업체 등록)만 후보로 사용.