From ac4e056e3e6b875674031ac24a2a629be8ccaccc Mon Sep 17 00:00:00 2001 From: Cerys Date: Fri, 10 Apr 2026 11:36:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A7=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__pycache__/agatameble.cpython-312.pyc | Bin 9012 -> 0 bytes .../ancientnutrition.cpython-312.pyc | Bin 16042 -> 0 bytes .../__pycache__/bricomarche.cpython-312.pyc | Bin 8314 -> 0 bytes .../__pycache__/condom69.cpython-312.pyc | Bin 6494 -> 0 bytes lib/module/__pycache__/dk_one.cpython-312.pyc | Bin 9556 -> 0 bytes .../__pycache__/example.cpython-312.pyc | Bin 3169 -> 0 bytes .../friskybusiness.cpython-312.pyc | Bin 7272 -> 0 bytes .../peek_cloppenburg.cpython-312.pyc | Bin 10669 -> 0 bytes .../peek_cloppenburg_nl.cpython-312.pyc | Bin 10508 -> 0 bytes .../__pycache__/ssfshop.cpython-312.pyc | Bin 15858 -> 0 bytes .../__pycache__/taketoys.cpython-312.pyc | Bin 6105 -> 0 bytes .../__pycache__/tfashion.cpython-312.pyc | Bin 6840 -> 0 bytes lib/module/agatameble.py | 176 --------- lib/module/ancientnutrition.py | 325 --------------- lib/module/bricomarche.py | 201 ---------- lib/module/condom69.py | 136 ------- lib/module/dk_one.py | 210 ---------- lib/module/friskybusiness.py | 141 ------- lib/module/peek_cloppenburg.py | 217 ---------- lib/module/peek_cloppenburg_nl.py | 213 ---------- lib/module/ssfshop.py | 371 ------------------ lib/module/taketoys.py | 131 ------- lib/module/tfashion.py | 140 ------- 23 files changed, 2261 deletions(-) delete mode 100644 lib/module/__pycache__/agatameble.cpython-312.pyc delete mode 100644 lib/module/__pycache__/ancientnutrition.cpython-312.pyc delete mode 100644 lib/module/__pycache__/bricomarche.cpython-312.pyc delete mode 100644 lib/module/__pycache__/condom69.cpython-312.pyc delete mode 100644 lib/module/__pycache__/dk_one.cpython-312.pyc delete mode 100644 lib/module/__pycache__/example.cpython-312.pyc delete mode 100644 lib/module/__pycache__/friskybusiness.cpython-312.pyc delete mode 100644 lib/module/__pycache__/peek_cloppenburg.cpython-312.pyc delete mode 100644 lib/module/__pycache__/peek_cloppenburg_nl.cpython-312.pyc delete mode 100644 lib/module/__pycache__/ssfshop.cpython-312.pyc delete mode 100644 lib/module/__pycache__/taketoys.cpython-312.pyc delete mode 100644 lib/module/__pycache__/tfashion.cpython-312.pyc delete mode 100644 lib/module/agatameble.py delete mode 100644 lib/module/ancientnutrition.py delete mode 100644 lib/module/bricomarche.py delete mode 100644 lib/module/condom69.py delete mode 100644 lib/module/dk_one.py delete mode 100644 lib/module/friskybusiness.py delete mode 100644 lib/module/peek_cloppenburg.py delete mode 100644 lib/module/peek_cloppenburg_nl.py delete mode 100644 lib/module/ssfshop.py delete mode 100644 lib/module/taketoys.py delete mode 100644 lib/module/tfashion.py diff --git a/lib/module/__pycache__/agatameble.cpython-312.pyc b/lib/module/__pycache__/agatameble.cpython-312.pyc deleted file mode 100644 index 2c884674880286d231e524d16fc6a2db77875753..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9012 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 M&1e6Ja9siaAJSkZs{jB1 diff --git a/lib/module/__pycache__/ancientnutrition.cpython-312.pyc b/lib/module/__pycache__/ancientnutrition.cpython-312.pyc deleted file mode 100644 index 1ea323ff8e23d21116ad2b09e2c21c3f7fe51b89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16042 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 Z0y91kcS&&FQp@t=Hy-~rhG?$%{{u452x9;M diff --git a/lib/module/__pycache__/bricomarche.cpython-312.pyc b/lib/module/__pycache__/bricomarche.cpython-312.pyc deleted file mode 100644 index b171261952f402320779d6c13e461579b97eb580..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8314 zcmeHMYit`=cD_Rn->;EHy(sEMSr1BKr({DGLXVdZ8QoHVAVfu&~33<2L(8$3=SqP)qc3+c|euQTV|dwI@x&U|UJnGuw~uKO%_rwO5d#|^dU^2C#AAXX8L zXd;Xv#557nOlt_-)`YbYa+-|jrgchN8`eh*(*^=*&^V&W_YkdPh!CYREI#jObM&<7 zs@`jOj2m8!Y~W^tG{bVTj=ws~aJc7kjE(qtPBumuj`LrEPC_Q9n5$f%$PA%^q#@}2 z5y;A*X@W-68k(5a#?fVh*1Tt&CTT6BWAt?}=duQ*Bc}}@pT4A*r1j8igdS7KS^9z; z4XX?=Zi%A>V%mBhd5yC5ydv`17(EweWXmNs7>GsuY+!~75G4!@Kx37kEI{=Ev5NS@ zV1f|PUxESx3Xz4*0zrf5w3gQ1CGX^wB=AgqVM2ijnF?fqpmlfhQV{4W^6Jk$#!MdL zzEfUO)?Etnff?C6A7kHQSYLE5B3rq6+~*5~{oIV~V42I|Ic~;xiH*&34EwBphUaIw zqkVnz^YgtW%J$BN`@A|?$IZ<$tZel8g3%!F^U2m(HWp$6yf5mHFtV2SUy`*~7#>cR zMwWHA5!fa9?%iayLFhd736f>}$NyxUnja#&i*5AQL z1!YMu5Ftm7F0BRKhln-^`VY}x6{H{#U!l$k?NO=XQ_!o@!2Q;S%IR-ZXDk^6!zjA= zB}iZtjL*^DB$%F~y%}cwG1^;p(cY|TPwNB=>_N$I5Tq@qnW>`%wCJ`}Phw z-!AYl<;F1=bB@G(IQ&Cw-dR`|*0utSvu~Tmi;de1?C*_N!ZPlM;8EU1Qmrd)dt|hh z7||_bzf|kKX}n>)X}e)dwZEFKeJyT#==R3XNcA0=`fjnlJ2{!IKLYJ)Po}y^lZ5FM~>*MQ#$&uttayr#Auw@;5 zXm#f7``XNwwd0YyGvn?N-94$^(X@Lke)g;8o)xRq)SYSS6Px-r%;}~fXuH}ou5QuQ zojjFx^{*Hdq4tUO`!e;1#QH-U=Qmr^^~YC?64j8Q_KMWrq+$K)2C>n(;o3Z~`Re9m zs%?CWI{nDgoALCEp8k!qY0nEQj<4Deubh+G`ZH}u#I_@w=5*VO&~EO{H1~_m{Trv! z%|j~_QcGW^<&fBNDAO`5whV8c|GYKba%yE#a<*igouacdIguRN@NXJ77C*1}eBkr0 zFGjuyeQ_b>oqpha{c98I_||V6sHHbsff~B9U5IK(8Qp9>K1FNk2?p}k8U_$5;E-P_ zev2lSG_(eM$RF&x1OjY;R?t9A3fdjktvr`<7O!9v%OM$B|5hjbc;DDXs&Y7|#0KrM z>JPMoyj|HRsLH|ClF>3g>~g_F6BrSYCS<}`O=Vc}EC((_*jVi-ck*oo^X(YJ%@D@2 zI|^O&lR7~M-lSjg)cWUm9s^(ie0g>h!4PWL(FIM~tlE6_3AX<*iFgPhaz!YdFl|vz zQww`Rp2s@^pnMUK1)!Mnds7B6{r|1Y?P@vXRC?>c?;dSM1bR)`>jmv=XrAy|&#@TD zJ*J^r)SsAzDC*dvp*mnOnEOmbMUwLO8+Wx``5Rw{qk=Uzx-kH@!wqg^(Wtd zjDI>NP5^oE^d)B-UTnDcZ~CE3p{ON|5j z(~f;&kWrkU>~gJKFE1X2NfqJsxq#ViY{}_y7JEYpCw0=-`c3ztlBiBs!nbh zMp6)Pi&iTJ3h z!kNUGwKHqSlhqq!^6iaRHecQxPt}cXS;r(t!+Y7fAK6C!W^{Fe>KD&52EB2&Q~5GYDSH70cJ9hg}r#}dN8 zeMc$h=8CS7FSxCcd&fd(3WZ>M30x4ZUn1eX6(6-#JFG1+Lq&K0G_hD1E zqwK=H5aNZJcPxOWdLx$fyR0s_+a&{!4V+TIHJ8)FqH-&z!-r^>Ro4G$RS28X9fh_P z69E7N3-=X=59^of_2+U8vv&$fE2r6 z2^~~96rZ8PMOvkJ?6{OtPRq~{b+q^t?DQTi5IigMPiOvFm48;_=iM4L`KM|RfY44W zV<0DJxa1HVg86NNBd!?*b2;e*M{(^n7li4v5TI|{AH^17AGxEb=Lqk#oJTo$0YKwX z4qg=6Z>Vj4KxMEOu?Lr^=kw(U)fEDzO8EmK$GQAi?p-umqTZqAiFu^HTY)|xWv=b5 zJr__p<0rmYI9`47_fX+1EL<*>AVc{aDRdS}F-HfPJpwlQMFp{H%I5Qmmmfz`Wqy>; z%h8oLk;)VY*=Cimc_>06-#tILtssa1ua_CDzaRms*;vYZchRwkUAg?^u z%F#KjRiI^ij#ROh0t`94ofvSvTY|QVtQPxsL0dt{;q(rNV*!7dJKl>ST5-`CV5xjS zfb6hTS0A5zROh}~d!shx`5vTvT_c+K>vqGfhE(4e4$SQm<;qYkBGs}E z(f(o4b9jSEdxkTfQPDG+8hbhQ%A0AA{{eLg&`%@AH_pbCwLyu<+2im=_5`j@;tHpa zWwcnp-Ur~ThJg=8nAjY@Xz9gSsvzty-7fDHf)E3aLPEnK&;KXIUQ>Mi=Cn z2*>)dbeC|4UfC`V&QuvUW0`zACb5@crngZx?)0lM|uCCw;3n&|AA+5&ooDvqu=ECHcWYgF}fSJWni>wQTV;tk% zlM5BF&g^TrdJ|V~;0m&`h`k7vY*O|RC;3V?%z_UpcgZ+4u)vp4)<=A_pZ6;Q$)>_S z%BI4FlnEwx*Kq`f@A|fKvgG3DA_>fP*DwPQP5~e8XJ9iSg1xmR@V{fNFjb8F@^@+am`&8fDbE$6U0^G`pRdIUgUhpL+4%Zj5C-fOZh8xn?P zd%~VExHNiCtsqno}!e){Nli zY`9@qx20=);}Z{^b!)HTNG3UuZa9=_7!(@@Q|_aiga2^s?~Z*@n;!ahX6O}h=#|Wn zPaN{4-n^We38jbLN*xWST#>Xh3PR~oU1NOW-&~z(S66)MKk6E9Hr;5Fs_UhyI$S$z z@E;Ja)~61m%O0Nuy{l{ErxfGz^b~=p%9W#k@xAqy`;J!0)3#!M-ywB&t(do{Hfe7k zezr($9V_Msl;@E;+^Y=dqAna~wTsU7jI&2{_S|JYiG3W)^qv-bPfPB$bw+gWlUnyB zUlCgmON|{#gV?xV@^mMsM9+ZK)S0Xmn-0Qh^i2>?kiM@PzIIjBK+MzLmt5Ft8(1?* z^?Q?3_v?>H?v9MRS9JF#uRd@Oeyv08gOFVG?8{c8w*88bSxRfFkgSg7iNwUUDcBYz zZu%zsvKAsKnX39-wwbV1$&~YVPcLW?RredDGc_q^27&IX>ALBC3q*yL?zNF0?@L)5 zzsc%gIz(&__tfXR{wr&NCBMs31bz`EIqD!_e8yqB^wG%CiDC59`j$y6`suOWNfP~2 z_b6`s+~&r07d2%@KOfdi654yDX40g+r`JROJ*#QTpuJa3O&-wPYqv~kwD%5ZCQs<@ z^*ez6Qlo>>FU^`Mht_MuUoLTq9KKwdeZJgRNBkAj=lkxQKb#w3t3Vdz+oMckvjR4Z zXW65;^G|SvEfV`(TrEK*+wxyH157yV^LYst13C^Pj@<8>#SxrRVavyzg6f<1kW|_H z?wO~gQFka??b0=@A4+O(4L(6YW(Qn4SF%3~v}@zgruI{%+m#)7htRp!U%u_T<@-;B z>73)i+|PN4U_!4;OUigR|iA8e>7emg& za*B{2qa0u5Yk_e%w?)U<1Te-ram`R=wFE)@0yX^twf-yG`;;8j60Vgat0%6X_$|V; H!r{LG6}1f- diff --git a/lib/module/__pycache__/condom69.cpython-312.pyc b/lib/module/__pycache__/condom69.cpython-312.pyc deleted file mode 100644 index 401330274ac0f5bc4050f47bda0dcdab00600b26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6494 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 Pb?f-e8Llo?D6tbr|B1e*d(?6koKXnXDq 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 diff --git a/lib/module/__pycache__/ssfshop.cpython-312.pyc b/lib/module/__pycache__/ssfshop.cpython-312.pyc deleted file mode 100644 index fc05670d0656731d3adfdf702b3f0f9fa3d6a7c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15858 zcmdseTW}j!mRL95PXZ!A5(M}F0RkjQ0^myzlAZ8l1>TXCL+7G$Ha zUVK9rQi!98KiLn#&+r=<0yp=p;!*4$!Zf1Tyok>$z6qEBAtZz!i9XCv700e(cJYL- z9s2)T4>b?kMXY$*7xvDviYr0t5=prOOAD+jbOq(Py?#$2nJl8qVdh;9R^)l|!>gGWDvI zmgyOlHlwPeRdtN6nyE1|MiWzS$tp2<&2KS@T=4{IW2}TC!%I})86?Z0fJ1U0gg3BR zEC#5ZN7Xky^QhLQhrmC~FBp!NVpAzf&hxakp^Omltzv?x-~blK&!5Avm@q1wM@zox zA%un6qNr#d!Mo`pM1>k+sKM>fXRFMspG~6_AtodrqQ!wHCW%T2>7^D7qws5oqWHWf zm%lNLir>WuSyb{a_Fe%Z91Cyb>&&AS+w?>wJY;|$VM$!b`5G~4RC)kA?*?dOQP~SH zA&<&mfC&ZE_+2oej4BC59up&5U_!xTf)GcQfDbW02OPWR5p6Y7C130R%bBW5%`}c* zbHjXb;ArZJh<+{{UJUiQTvx7Kaq?T)8(eTj4lFNv!gB+zx$uJDH60|bx(MIpv)j+R z=1324a4yw#e#484cII;6wd8mCec#FUg*~$^_5lwonghj{&yLF%e|iSmb7bud7>7s$Ypo9k7zG0Ac%zb|kJ6|z!P28~!5iXc|Ys>4@;8(VKo zvMQ7+wnizgHHx6tAr-)5+VD_S2*7PHNB1*8M(Uqo!9OTR+duTjzy#mG7`Rl4rWIv9QJE!j=kE%i-x%H~h&7gp2{YwauJjIlXmY@>~BYlqXuosh0F zXR4a%s^&FGy2`aO!c&OQyPmuI^Z`Sofx@`&JGyn(9RVJ&ldg0?)6>s7$oV zlpIO+t_`lutxcsGcimU@K2+&)!XPnsU)B7mwk1>Rplcl|=izki*vgU5O^&#VX=uwd zxabDgx+2}s4{3ufV`!rdZEFY9hVHnOgRh-7wr7kzw6SM>@{T2K+!L2E6~@H!y^3Z= zSIcPYGTJ6u+q5Q4UR}r6Th zpK4G1h8y0B)wO2#X(ITrhF0eN*0iXcG5Y=+Ba1L_e1c!rsDlOGY$igTN zToL3Mgu?d<5(!5VRp`TFBKcMlvcv(V6!-s-0};cx9>rV0^?d0FQVt}{S&%RwYvz^t z4mZ4r0w?EWP${WdkZ4iSWh5dayxv@q;N)xh62SBptYea=naRf$#^9G!Ex!C`KRo-GfDmEZDAKiFn0{Nk| z%O}1@hp33!=3SyFG7vrn2ls)!2fT^rrQ9ROBt;m_OayVSSb!hd_TSr%qW>i*MWd*K^xcw+oQ+G>$Q-7=OW?k~t zbWQil;m_-u<8r34_5Hfrb!%7CjlJ{)*~-MIU{c7W*}h|3esjKM)09BVUa!}fdH9dMGbZ+TjVX)EHrfACsz+dYk$ z(N<=)nAVVz)jZXpg1$d^J*m5=v7!Q1t^k^;s}puwWm!24lZX$lj;y)(#Ssy+UM+bEC|)%PF}fJX#4oJJU7%wUm_y;JP#l<$@{F+5^&uuD1Th)FQo60I z&=#GpHa#&}7)d+s*`j^n>QNFhMWOc+7n^xB`ArX@go|BXobqjBayj-wI8=P?QaJe0 zBPj$}RKTxwOc_S}jeF*6`B?ECl}2SzSUV6s@~Gk?^@sV3XG{g+S`GhY@UPht^JN8y zORcG

NXUriX_RN2`js>ZXU#@~vaqs20TaL7=j2(QWgH?{0dCZH2n!(Q>LXT3$*N z6Xkp@qJpE@@_=9!kChX;X!&KF5);ra0zJpdqndf^rXe61EwqR0-60VME85K0iWcTd zROEy#Q8kOl)LUY%nule+)ZF!aX{;hz0dwyJsB}?vNvL!sskVmip(MTxd@28i8Fj-2 zP7TUAu>n>d4r-MfW>>-2BaGbaK7d0;1z|*3oPW{U0_>X~qK@wm)B$`yrSMSC*Nas} zs{jv|01wqb-@>RQT3u?F@cS-WS-Kn@ptdUGX4AbHRt)1Q6~?z?*g4qQF@3D&c~C_4 zyrS}XV@37cajs2-U0Z-7-IlZz7f?H*8c+`j&bv73RK^U^@>TrOPB?)49qgX%KZJQB zt!}~fUchmm;UX|z$sJWV-V=H5zBRoQ4Ii2K)tN7~){TX=u6P0Uz4=_4F&Fyzdrvd4 z3#BF3#lqtt&*_XWls$jXWZ;I~R9V19j(3HlmGjTv<)C`xc6n{AZbLr>o|Wf;-O;)i z^aGqR&n@bsWhHrcdDIxKjp}EGNcu(%g!Siz>l|?8M&Jx1&ucj=DA^8Fk8!~@{njmK z@lx%eO_vA@eEdTE{LzoXPw0jC;qk1G)o;Laf#(m5S+z>OBo->?p0L#&a9G+*f zACKo;%N(A6&<^l??WbFhn8Wf9S|y+1^@S4@%oeHL|H+mdv{198ytnaG{z7?NiuX42 ztz(TuOH}19oaP8S%tGZZoU5ZsNLBLkCfW!xaTH{dIjWj(=W~niQZyen@a3h>qw^rs zHa}5wDM`;`_oLPi^NJ&W4zP2^fR6wA*_lMu&&;C?Apc{4+_Hi4EJPbR1MvN9C{goy zoXo9_Ld|8tvH;bNsyEcz)B}MTK%IeMUZGdOojm?;V#z|ZbMWM002m$lv@`#9q4!4} zALdO_{G8wnW+AvTzzNs{V@=VfsPZx%!mr7q%2I0>Z7R0CW`JGrCvbLrmNGPe?ZSP7 zqiHz1Y<~EY6+obx#4MoFJA=g~*B&ej&tO+@l#a?{3NG(bF%Qz>Ykyfx!wsc^%lpG( z9#IS97pQm^`rnF%xiX~m=AIWr8j$AT3^(#;GGbtfFAOfV15+zE-E~Lz3dQSuY0$+XzU>E}i%qnJgowyt&NPdUl_W7%+qKa&%$# zpUmkcb48q9G8g6blAO9Ugj7(Ra`KH0n#p2!k?t)tlRmJDId}VmUXMSt z$BERL#YQhfpP^+4z6G07jdA7huPY6Su0K2z$C*0Qt?n0G%PHj07E|){xOQ(%Qz9x&O{YX7^Eg_tDg` zm(#mX(dJX1YENgyP&X^XboD7!T~5gd+#6uvA1y>Uf&}Ko5oF%SLPUsHl>`{i2^k?L z6rclA5o)50(EMBjB!YvAT^q%SZ9f;qL`CwQ&ufYJ&e5AFhuf`)sDMA+&jlY<^3p9P z1_MKZbc-!`9vYLttw~B$MJ1ri5JaVu7?|>_5Xa9Gsw`X}YoeOa^LH^Q1@0G<6E#se zn6L#g1!#m6s2%YCG9TP9_%xDWK%~vU?-8NG2zJ9n#0i#8zYk1FzF@#L9|{KAO~@4L zn)h7xfco6G7;ZPUx?1~9uMBiJJ31q-$ed$nqCGO#k1~4O$p9DG1rf){elETf#b27_ z;yWUWOC-7I@c4a~$w!Im9hUv?l*9|!1R$$&RVkVL=9JLjQ7WO(4ElLsBUzAJ2t zO}1!OOfD>jud*U@c;Q0)0I=y_hCWnmS4Z_^XQ{?oRFYMahz0=vf!_+c%=;V>{c9Y+Ci8PIn-b+EdX=siL zE|9Lyo*ho;0(zbF%y=jt-(;AWEtW-^$X#U5w3p~|O!w~G;pp*tx*fZEr#l?pUE2w= zgXo;;p6+1FP9GUR1ZMUVLC>+^u<_7UCEtvZ+513&nbGykr5ez#9ot*ue%kJty zxkr3p)(8b>!X_A*EYyz(_I5<%=KO@sb`2{T^m@s~a72@PJH~;7EOADSpJR|NO2LI{ z*@yfJ06uC5WPOeJD%kota3>Z3bQzUf@DP}nf+283KwFN2GdKp$1?S;KO`!m6n;3Nw z1zgY2Dzq33gh*D7>bsFh0AGSdw16R2l8dmoj}=}buTn$MZnI-Rp06tri_W);bo^+h zo^L^*j(-gSaP&up!;Ix5Q{T#%PB4aU##qmo?TopFF}tz?tl@%yF&$)@dYC#7)6~M) zIv+P|t1ep^$+lqi%}kw*scT?r>L1I+y0Vo6U=Y%qZp5y~Qq~KpxnSyY1PnM60utGA zf`Ws>#~3y&7!iU!M}J5Nt^;}#azl7mvoiXqN)Iju8eL+P27^&`eZ1_E!IB)lZ)lB6 z9@f++UP(6okug5V)HWrLCx;Tw_z+WFm+-#*D&y)*NRyIe=(dv9w?EL=J(gnzYgULE z+ra3gGp0U}^+{uhA_fqP8HKIS}@r^o4;&Rgfe?Cq2_I`^YPizD?rZo7-3* z>VcFw{))V1p7D=4+YN<_oTwiCAzYXcPOTnKKK?x@aGUNp> zLF5L*5eF*_EiSR*+=%j^pKx>0hzglkLyp{PFQJnU5(NX_{ABf;pZtT!*zW+>j)LnC za^XQUb@@Hhq#rrLcwq}(V)15fr$l7@UZqaJxSWGee%x})BE`Ai9OdYJkRm;iN=qL= zImzwZV;(BJ;PD^uU5=>oo<+XE;!-$*_Jt#`z#Xz!d~z20h3C=U@8tPve&5$fBHM9R z8ul%aL1?3M=GcMBKWkbFaN>$2BAVRP(HuC(BB~CWfi-%1>8c~V91hvVIlPLIX*xtL zK`C_^0#?EuheAtbkjUZk_dWs-r*HmbC2}~A&L8+vEqHu^=TOYEDCNLm@gto3)Hi(R zz-Sc6t;xL!9_lp&Sque;NfZI)3i7j{-Y8Lo=Xh^DE6w|mveE!~#mzZXfwX2NS2#J# z3Ku-f6hbPiK*n+~ymO=$f-^=qXLoNxg}_G_{NU5;4|>9s6^)0s7b_n@#&+at#fmxd z$Q^ersDcdz+`;z^6hkusjtkCFA@CE1+Ch*z+>w}@o(UBz3f&!JC5w3*{_rxAiNHAR z%{gN~hl!)8&j1R-CncH!==E{jGI*#=NHDUF?a}Z5aei( zhlg`IEA+#qBpjJ^0<|LY?c%%Y&N-;%a=Tf1$QL1V1Izd*D=&~4D=!@VS)9yWE8v2K znJyN*9-b4~x8dHwiDmG!m)(`C&oLPn;1OS&q3t8BF_BQwx4!+lxp!?MaunTaklB`eZp))iq^G%1uf zfaCFv(d(liBqoxbw9dLR{KK3_P-o=&NaAQ(*PhWqtlvMNefI+X;uv^kV9FVp7b|AAqaK>^4}2%+hI z!7zG_2u4v`%V8AOjS1rN$1==lPa9fS#(rH>f2-kU15;&WDr-;(zSi)Ah{5tyBQun( z9M0-65UmHfdm9&I1!|ZXT+O7{rHQh%wmGA1qqS{oN7CB9jCLQb-FIKRzi_b&rR&0R z#pjJ}@lnQPf4}T@890%cdgG%Hs!dFj`xqzPpuq$WT;&kd#EXo_op=t$;NvcOID!VW@B^>N&NamM%O~? zTJGywvsKtO9d~1`ct_1Nw61mDd@a+^MK^S<_oo~7##NtNT=B67J$vtp@4lKDIYp10 zO81dX&43RnG zqtEzKm#(A_E+>@9u}o7B4L|+%b^ks6&|@Li@e&R<;HHkJiUO9>8uLSL87$8DI8$v( z4&AE;ryt`j=}l=;eqRsgH_Q9d+tM{n+O#WU8lX)B3GsvG?dj&73DqN5JI!s)x-f0( zSwBvjb|%C?hcynS)$xnw51Lb52UEw6uQjJzPh?t8(XFRarvvHMU}7vQ!J6#}`hI;N9T}<1K^;bUFlWE&Sx9v&oJ(g}eo*4h!)t^*8*f;jcaBA{GX3|Sfdei%e zq;hR6)4rRApJ{;UKggqv?mwOBzd-k2_^kgT-Lx|~zHWVR;(Y3YH$^UH$R(Ow0>WR$ zxlJ>P4-1lG>&i^WJ{o>agLm8SH5~;U?e-uXb?nY6gq3?4YwP=GZ=YSSNL#nBduZ#f zgaUSIotfWdGimc|#(ar3UrPDIY4cLX9HGq-wBv@j9mhFa9T0FHN27u%%7dnk9#=NV@e^Xxql^RtQmi6!ilkKz>+o1ig+5j-wvhPN2{_DM-ixB)u`w zpRR6RYrI$8#`NsX^bFHI!=Lqx(6t?j@ip7S26J-9yRWVt|HrR0yZ8T#@joB`%L%$^ z7huT7G&wU(+v%q5jB6Luwfm0$lkrsN8K!dwvwaWKwdb)?veO3NR#=+>Hv?mMwj670 z%a}T8Qzz5b!#H={X-_#u7)KY=*~d8hpnA6%syAAGQ;lsuglBD7jU}VE(|S8&X=iL5 z$#Z~H#@@x)x}a{G;cqcXjq&j;4tqCy8OI#EGVKF&`@m=Idtvv)$CI{))rQ25w_i;j z|3|MgJ$=6#|9Je*CjPf()djP-tNO&B>O9NOs^_`0a>6|BjHeu<{H!{Pvw94(8hUnC zHkeBC0za!3ZdQPS8e_H%bL_*P_VIfy$04?DYexbDiHC`_t}UZ;(K=VEV_#Y~n9+^U zx{>=j;E9&^Ww&K1`%>C;8Cayv9zXofQO2=r?MVFaeVv_Y=|*qs=S_};jM1Aj`c_)s zn$dUC`p#ckf93kvmFXI%yT+N8j$f!hP$yq!%*~9=#aOJMG3!2pKf%P^hTmdhz`PK% zIsD z?(U>}$I{!!Q`?WEoD;Nu0!lcpY@>CyjLt#p93PRt2!0UEI1kazLrkqTNz%3LKniQ8 zXv=n{zIjbb*LN`HwzVnH6B{Z76L+ zTe%LgP5Djvd&+OK0=%;Bfxh-T#%R5#vwoko;fO1?zdQDQwhBjlrRDuow@yxJvtpPLqt!huH|DecE~|tl-)FTrLW`Es)PQg0ccI;&@%)#TL9s`N{VTii zf*$+VqCp`f{z}$!!G!(QZac*P+O}VDp%wc#9p#YtL}2mA~z2HKf@C$6D`Qb{zWoawnS2mwlp(xcJLGsMRA;-Nh#Hqed>?EV}3vKWgLR zo%Nn=!ml(46<_J((;DGd^;%D_;47zcS|R+ZS1>IVf7P#n_}?hRQ2ICJg6V4EGoPCw z#f}jEpUePOZ*1ifk7{gsiY5=Rj+OQzEukeYeri_IxKVHskKtfo5kzs&3h&PuH%jT8 zi^dQzeF#dKKDID?6ucYY;{XZNDdBzk>}O@y4uG}1@DW<6PeK6)CHyj>f9ZSh5dyE} z=DvHBO+;#WEx~4u9=ef5dY^lx&MRN?x|qBkCjVIxg)BLg0R@~tc|F7;Iv4+iMW|&C z6u@>T-1Rp)nCC9Eji?oOJGGz~y5CYrRSy>?&t;Okpt5Q=cQJIM&!^mOxM(AbJS+A4 za`!2DVIWqL%VWhJt_aZrcWuhuk7P)HhhW+CNhP1{2Wkxc4BCLnrRX4@s_ecm>tV{P zZnRu)xzT>TJ=HLkE3tP`{62{}cuP3<88?^u24yOZxqQWSpvm+z?;{%iS(1WaHxk zgw@c?5PbV4##Ge4G5%B}6)UpkHgR3DXH9s!_X!5k>@nORHmr4LF?g-_+!1~Z`4G+S zdPyWUBrRDCz1OV2aDCuLYyF{;}9=}ef|)qBjG+T z<7kB#t*PuH&v)awmXNWJ=8ykB$`sl3PDzgFs$y^P@MFJH5RU&p#BLUjZ z-jPRIp^>5sX*j#HGrPBsZ)Wz-Hk$=O`Dpl)@cpd_eTgfTVk|Qc#(-Hy9O8&5iV+h; z%rIdfaNQ6kW7Gr{Gfo%@WI!W`Bd;Ki;)w`bF;e}#MQZ$ndEV$V-NzN5K{1QdVU8C> z#VE~B^CE7!m=Iz?NmS?s(@n257>0F4JNGsvxJG)GLZcB5V$W!Mr(=Bj2ZPmA{a{ zJxzKCory3yt23POR(Tc#nnym<*!?z;-N%-OeUxIn5SBtyie)w-T;hd5d?u!_;w)|p zgrY%lO4%at7o#)cRN#V;m=$>;>70_JY4M=nU-`;C;-ueaRE*-xG%qN0AP|m+r9ePo zr-ej>4@rS|FvcsS6uh92le`4`NQr#(qQV5!A;dsHG{9^+E`Q@ce(>B`bt2-q7kFV_ zJXbyf=c3^Y=VI#Wp3{e&o)?}1y<}tU;_s;pkC$6K4CK*ebeFa*m~(VXk#!W<)*Rbf zbT$=T?xLro*w$IHBF6O)nHWpSju_iDdV#*iF0k3go;!5!12BLTlfX+eLj1Aq#7nJi zCkK;XMw2K7n}`qI<`O9%?%H;asBB8gARF-Zy3uj8NSp_&DN-gQm7`pv#8J8qB~uan zeVa;kt5ZhkL2nX6HDdj48)xFox9|o)Ntt9KV$=9qDjRPij+RX~(K}>i76g*ERQg05 z6|VX#o2otGi|VZc!x`SU=wq9uhKjaquIL^|=VgS>!TeHmijkS`Ss9CL`JR=rLXZDr zW$Lb+m18TjuPdiHTScB?pRlsl%F1#knT7SOxvp2=qToziWho>R05kTnWbfQ`P?|dI zpORux|AhoM@1Np>fRTPK{N@||=kbp}9(>b36ZJ>K_wl{I{~stxv!)kRs42M43gK6X zK85H^TD5ky`+J09mclVUF(WBN?+o6rfBfmHLUi~n0!BfF;-kE%kU$kGC`p1sN&K9o zm<4`18VvD@DL6gN$2kE5lR}HYo{V2iC=3sv!V5u(_t}IdEVG56GMNzO12aNYRBVYj zABaJ(fI0wMTUFFrG#tN#g^C%=KuMu7qvDE9noZPbGq@U#bNrmb)=IQm)ex4chA@K- ziTK!e)E1!yPj)LnR^YJ-C)*waobSjnD2aYp{L84=;!fM{wRl(P8}y3phAq46Ouprn zw5{m%WwvFGZFv3Zmx`XQf~P0v>B*eTd-g-UX?vlmE7#POG3A^5>5*b{XQ8<}*W6ub z-kWRQyVkH4$~PZOpD41f0^5;eJ61?4dt#+ZLnSUyxj$F zU(VZ?iGBE^thX=k9Z8?M+cUU!{x3Z*7ulkFSHazr zbN6J1^X`E~vpU7zoTs{tzGL-8J9qyxpx(Dy(;4V?`SI%aL0&u3>8cvFj^b%KZ6~qYW#6h&kfhZm0M*s z0zJ`EJ(mo456-;&ZS|0&YWE5AtAo*1^e52OXeT1j>nKjnk*}lKCwV3vzpG!*>8OqU z5TNfMATRbe^}a(#=?Dafn+r!**83&`e`JX0=w9t9*P`8i3Q3I>Sp*}+rXt}3q83@- zOW0Yac4uV+Af;t2X+AOy@!{cpNjnCq!{bwl*^XF3-~}9h3fnR90!eo72_>R^b7J5A z4$O$LzCo3VPWBCSge5-KH!EOV6O#1vQgE`{cQ`2E0BQyYY8_v#{{cV^qoaUlu9(D- zkcdVVMoI)OBqS*j6S{D_F%%7lE-BP(Ff0kXaQALZdN9FoDf9wS$S5E8nN*Avp2ZE8 z$wYz^HIyv#Dnv3`J4VDZi-8my((p?|E;~l1s)eNIJFrz1?gd@(??3>vXtojqU1t~H zT0NU>?AxIC6dRkoem$L<8EDH$kRQ_iJ#cS}D@(gnwEu`XYC7gXA3F@koaAFr zqX&0y0pPrCTSjRcWDmp@8p5^ufKeyBk@X<&7q$gkT}Z)OwyD&+XjM3ntd;Kd@~G;F zDUv}jX1xopU!4?WLMbBv7ge{P9&XkP?$iLYo^|~~*VTe7D`jR-%~xP&xv4y1-a0VV z%gHKGlQKU+y9!m!n}&mG6{;dS#8i863`goO6ly@MZKgE8(O=)LELuMgiL@h8vtJh`BvRrM86hw zGYmcJ0k4SaMFO(k1HA7KAYw=0hp4gS>F-4Bv0yk}6R(%U_Q!wJKpw~R18PiP3GJaJ z$!G?{u}Os#g^-WZ{0ZLgs#Ae<+!Bs~11$Rvjn{mK&MS=GMRj2!PCBszxm@Ev^e$p@ z;0gXC3{n1`L(xPi7!{w}gPl%QX%tL~KLi3c*)|Pu{z~;C(jdeRh2)?>zk1to3eiYN(*_+-*rsZIyu$*rC67{Seiq&_^`K6r~rn)XZ!VMtqyQdj~U^7Dvdj`Ont^{qqX zCB-xgxkzGGA!ETg0k5xO0ZRc055Sfh8wftNH5BE8@c_>2AV&kL?d5Ke3HZb-%m@wz z)P%}{ldk}dO+>|{F14tbrvuTj2rpyI&|HY0mcofR4muJd@3U(G#Tjf0Ki3JbV0)&i zeK?~M#&HY&Ug2d-Ud7}r5XFkmskW11B@n@Drx3h$TI|pZpBBA5Uvq4<$O89&V%UL& zC&7mJ0bE@;9uEy>rmgf8!~@r&3(3Z7Y@=menKq zmVrXcGr5*$7L9O{8a>OSOQY9Qd1qh2*`IUvr-$w}G^UTMI(M7f3eCP;voF*6$FBFf zvi(E(-NS|5FXnc?m~Vb*kt)#$MjKfgxqc$=+*xq$&N+8yp3XZ53eIP9PB_9J_UE0$ z1?O1KIrf>DJ@abbc{V*%Y-vrO{F}Qw@7|q$@hex`O8brWVw0!X=)%<5jQ@afcRt)g zyY1=Gk`uLWPmf+bUEHxNJ-WeeD|YnY-`3)`PW;|<$%T_wUxbfxxFNoI zR60!%w#LsL&TmU>nR&PyIb2^OBh#*}iKAheSz>-|g=ne4d;RFIdb4cXqmmJNLzH&+ zDNniS-z6)kd|Pr5cpOJjji0^|Ct>S8@-_?|Kp*Y(4E3Oot*yX+?AtTck3MNWMnL6L zmt**8^l6V_$WMOSXT&Z2hN1oBr-LegfEgYnZ#(1^-DVi>HQw&nf_c9Y zOP@9jA0mA={HlnPba+*?1OnPaAbw#C1b#XbjA{}Adj<7HP@(W$fa@v=!a>|Pj0wI* zLJ*TnKonc~^)bXpqk({r5O7=|VlSedV*x)BsRS#E$ALV$f{G2TmtT5F(Z;?~lh@d~ zI+!8fJ@5blTRPNibY})i2!7TE*U1l{8Q4<)L8E*1mEQ;64g3oMtKybwb`0K)sSr*{ zaO|kva^s8?j*2Q!XwN8S4Rb|R<2|HltM3x@A#E9+6W#=MJa4fTNQoo};tSON1?qfA U{fr>oi%%~fSvvAhgn3o{zfN9MaR2}S diff --git a/lib/module/__pycache__/tfashion.cpython-312.pyc b/lib/module/__pycache__/tfashion.cpython-312.pyc deleted file mode 100644 index efab6ad742486e6ae5e6e183a49990b2ffc505d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6840 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 Ul!5SMU%xr=;l$Sn(<=M_07jV|yZ`_I diff --git a/lib/module/agatameble.py b/lib/module/agatameble.py deleted file mode 100644 index 47bf346..0000000 --- a/lib/module/agatameble.py +++ /dev/null @@ -1,176 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "agatameble" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 30, - worker_num = 1, - switch_clash = False, - reflush_browser = False - ) - - def get_category_urls(self) -> list[str]: - category_urls = [] - - self.tab.get('https://www.agatameble.pl/') - one_menu_eles = self.tab.eles('xpath=//*[@id="root"]/main/div[5]/div[3]/nav/div') - for one_menu_ele in one_menu_eles: - one_link_ele = one_menu_ele.ele('@tag()=a') - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - two_menu_eles = one_menu_ele.eles('xpath=div/div[1]/div') - for two_menu_ele in two_menu_eles: - two_link_ele = two_menu_ele.ele('@tag()=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - three_menu_eles = two_menu_ele.eles('xpath=ul/li') - for three_menu_ele in three_menu_eles: - three_link_ele = three_menu_ele.ele('@tag()=a') - three_url = three_link_ele.attr('href') - three_name = three_link_ele.text.replace('/', '-') - category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - self.tab.get(f"{category_url}") - goods_urls = [] - - while True: - try: - self.tab.scroll.to_bottom() - self.tab.ele('xpath=//*[@id="contentContainer"]/div/article/div[2]/div[2]/div/div/a').click() - except: - break - - goods_eles = self.tab.eles('xpath=//*[@id="contentContainer"]/div/article/div[2]/div[2]/section/div/div/div') - for goods_ele in goods_eles: - goods_link_ele = goods_ele.ele('xpath=a') - goods_urls.append(goods_link_ele.attr('href')) - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - - tab.ele('xpath=//*[@id="contentContainer"]/form/div[1]/section/div/div[2]/button[1]').click() - image_eles = tab.eles('xpath=//*[@id="root"]/div/section/div[2]/div/aside/div[2]/div/div/div/div[1]/div/div/div/div') - for image_ele in image_eles: - image_link_ele = image_ele.ele('xpath=div/img[2]') - image_urls.append(image_link_ele.attr('src').replace('width=', '').replace('height=', '')) - - return image_urls - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - brand = '' - try: - brand = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1/div[1]', timeout=10).text - except: - pass - if brand == '': - title = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1').text - else: - title = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1/div[2]').text - - desc = "" - desc_eles = tab.eles('xpath=//*[@id="contentContainer"]/form/div[1]/div/div')[:3] - for desc_ele in desc_eles: - desc += formats.clean_html(desc_ele.html) - - price = float(f"{tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/section[2]/div[1]/div[2]/span[1]').text}.{tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/section[2]/div[1]/div[2]/span[3]').text}") - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - m_data = [] - attr_items = [] - color_urls = [url] - color_eles = tab.eles('xpath=//*[@id="contentContainer"]/form/div[2]/div[2]/div/ul/li') - for color_ele in color_eles[1:]: - color_link_ele = color_ele.ele('xpath=a') - color_urls.append(color_link_ele.attr('href')) - if len(color_urls) > 1: - m_data = ["Color"] - - if len(color_urls) > 1: - for color_url in color_urls: - color_images = main_images - if color_url != url: - tab.get(color_url) - if brand == '': - title = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1').text - else: - title = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1/div[2]').text - color_images = get_image_urls() - - price = float(f"{tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/section[2]/div[1]/div[2]/span[1]').text}.{tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/section[2]/div[1]/div[2]/span[3]').text}") - old_price = price - - try: - item_name = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[2]/div/ul/li[1]/div[2]/p').text - except: - continue - attr_items.append({ - 'url': color_url, - 'items': [item_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - - if len(attr_items) == 0: - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - else: - goods_info.attr = 'M' - goods_info.attr_items = m_data - for attr_item in attr_items: - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - url=attr_item['url'], - attr_items=attr_item['items'], - price=attr_item['price'], - old_price=attr_item['old_price'], - images=attr_item['images'], - )) - for image_url in attr_item['images']: - if image_url not in main_images: - main_images.append(image_url) - goods_info.images = main_images - goods_info.p_urls = color_urls - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info diff --git a/lib/module/ancientnutrition.py b/lib/module/ancientnutrition.py deleted file mode 100644 index 41970d2..0000000 --- a/lib/module/ancientnutrition.py +++ /dev/null @@ -1,325 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "ancientnutrition" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 30, - worker_num = 1, - switch_clash = False, - reflush_browser = False - ) - - def get_category_urls(self) -> list[str]: - category_urls = [] - - self.tab.get('https://ancientnutrition.com/') - one_menu_eles = self.tab.eles('xpath=//*[@id="__next"]/div[4]/div[1]/div[1]/div') - for index, one_menu_ele in enumerate(one_menu_eles[1:]): - one_link_ele = one_menu_ele.ele('xpath=div/a') - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - print(index+2) - two_menu_eles = self.tab.eles(f'xpath=//*[@id="__next"]/div[4]/div[{index+2}]/div/div/div[2]/div/a') - for two_menu_ele in two_menu_eles: - two_link_ele = two_menu_ele - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - # three_menu_eles = two_menu_ele.eles('xpath=ul/li') - # for three_menu_ele in three_menu_eles: - # three_link_ele = three_menu_ele.ele('@tag()=a') - # three_url = three_link_ele.attr('href') - # three_name = three_link_ele.text.replace('/', '-') - # category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - self.tab.get(f"{category_url}") - goods_urls = [] - - while True: - try: - self.tab.scroll.to_bottom() - self.tab.ele('text=Load More').click() - except: - break - - goods_eles = self.tab.eles('xpath=//*[@id="__next"]/div[9]/div/div[2]/div[2]/div') - for goods_ele in goods_eles: - try: - goods_link_ele = goods_ele.ele('@tag()=a') - except Exception as e: - continue - goods_urls.append(goods_link_ele.attr('href')) - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - - image_eles = tab.eles('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[1]/div/div[2]/div/div[1]/div') - for image_ele in image_eles: - image_link_ele = image_ele.ele('xpath=div/span/img') - image_urls.append(image_link_ele.attr('src').replace('_150x150', '_1450x1450')) - - return image_urls - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - brand = '' - # try: - # brand = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1/div[1]', timeout=10).text - # except: - # pass - # if brand == '': - # title = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1').text - # else: - title = tab.ele('@tag()=h1').text - - desc = formats.clean_html(tab.ele('#productDescription').html) - - price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[1]').text.replace('$', '')) - old_price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[2]/span[1]').text.replace('$', '')) - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - m_data = [] - attr_items = [] - try: - tab.ele('text=Select Flavor').click() - m_data.append('Flavor') - except: - pass - try: - tab.ele('text=Select Size').click() - m_data.append('Size') - except: - pass - try: - tab.ele('text=Select Quantity').click() - m_data.append('Quantity') - except: - pass - - if 'Flavor' in m_data: - tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[3]/div/div').click() - color_eles = tab.eles('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[3]/div/div[2]/div') - color_xpaths = [] - for color_ele in color_eles: - color_xpaths.append(color_ele.xpath) - - for color_xpath in color_xpaths: - while True: - tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[3]/div/div').click() - try: - color_ele = tab.ele(f"xpath={color_xpath}") - color_name = color_ele.text - break - except: - tab.get(url) - color_ele.click() - tab.wait(3) - color_images = get_image_urls() - if 'Size' in m_data: - try: - size_eles = tab.eles(f"xpath={tab.ele('text=Select Size').xpath.replace('/span[1]', '/div/div')}") - except: - size_name = 'Default' - if 'Quantity' in m_data: - quantity_eles = tab.eles(f"xpath={tab.ele('text=Select Quantity').xpath.replace('/span[1]', '/div/div')}") - for quantity_index, quantity_ele in enumerate(quantity_eles): - try: - quantity_ele = tab.ele(f"xpath={tab.ele('text=Select Quantity').xpath.replace('/span[1]', f'/div/div[{quantity_index+1}]')}") - quantity_name = quantity_ele.text - except: - continue - quantity_ele.click() - tab.wait(2) - price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[1]').text.replace('$', '')) - old_price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[2]/span[1]').text.replace('$', '')) - attr_items.append({ - 'url': tab.url, - 'items': [color_name, size_name, quantity_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - else: - price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[1]').text.replace('$', '')) - old_price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[2]/span[1]').text.replace('$', '')) - attr_items.append({ - 'url': tab.url, - 'items': [color_name, size_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - size_xpaths = [] - for size_ele in size_eles: - try: - size_xpaths.append(size_ele.xpath) - except: - continue - - for size_xpath in size_xpaths: - try: - size_ele = tab.ele(f"xpath={size_xpath}") - size_name = size_ele.text - except: - continue - size_ele.click() - tab.wait(3) - color_images = get_image_urls() - if 'Quantity' in m_data: - quantity_eles = tab.eles(f"xpath={tab.ele('text=Select Quantity').xpath.replace('/span[1]', '/div/div')}") - for quantity_index, quantity_ele in enumerate(quantity_eles): - try: - quantity_ele = tab.ele(f"xpath={tab.ele('text=Select Quantity').xpath.replace('/span[1]', f'/div/div[{quantity_index+1}]')}") - quantity_name = quantity_ele.text - except: - continue - quantity_ele.click() - tab.wait(2) - price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[1]').text.replace('$', '')) - old_price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[2]/span[1]').text.replace('$', '')) - attr_items.append({ - 'url': tab.url, - 'items': [color_name, size_name, quantity_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - else: - price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[1]').text.replace('$', '')) - old_price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[2]/span[1]').text.replace('$', '')) - attr_items.append({ - 'url': tab.url, - 'items': [color_name, size_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - else: - price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[1]').text.replace('$', '')) - old_price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[2]/span[1]').text.replace('$', '')) - attr_items.append({ - 'url': tab.url, - 'items': [color_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - else: - color_images = [] - if 'Size' in m_data: - size_eles = tab.eles(f"xpath={tab.ele('text=Select Size').xpath.replace('/span[1]', '/div/div')}") - size_xpaths = [] - for size_ele in size_eles: - try: - size_xpaths.append(size_ele.xpath) - except: - continue - - for size_xpath in size_xpaths: - try: - size_ele = tab.ele(f"xpath={size_xpath}") - size_name = size_ele.text - except: - continue - size_ele.click() - tab.wait(2) - color_images = get_image_urls() - if 'Quantity' in m_data: - quantity_eles = tab.eles(f"xpath={tab.ele('text=Select Quantity').xpath.replace('/span[1]', '/div/div')}") - for quantity_index, quantity_ele in enumerate(quantity_eles): - try: - quantity_ele = tab.ele(f"xpath={tab.ele('text=Select Quantity').xpath.replace('/span[1]', f'/div/div[{quantity_index+1}]')}") - quantity_name = quantity_ele.text - except: - continue - quantity_ele.click() - tab.wait(2) - price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[1]').text.replace('$', '')) - old_price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[2]/span[1]').text.replace('$', '')) - attr_items.append({ - 'url': tab.url, - 'items': [size_name, quantity_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - else: - if 'Quantity' in m_data: - quantity_eles = tab.eles(f"xpath={tab.ele('text=Select Quantity').xpath.replace('/span[1]', '/div/div')}") - for quantity_index, quantity_ele in enumerate(quantity_eles): - try: - quantity_ele = tab.ele(f"xpath={tab.ele('text=Select Quantity').xpath.replace('/span[1]', f'/div/div[{quantity_index+1}]')}") - quantity_name = quantity_ele.text - except: - continue - quantity_ele.click() - tab.wait(2) - price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[1]').text.replace('$', '')) - old_price = float(tab.ele('xpath=//*[@id="__next"]/div[8]/div[1]/div/div[2]/div[2]/div/div[1]/div/span/span[2]/span[1]').text.replace('$', '')) - attr_items.append({ - 'url': tab.url, - 'items': [quantity_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - - if len(attr_items) == 0: - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - else: - goods_info.attr = 'M' - goods_info.attr_items = m_data - for attr_item in attr_items: - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - url=attr_item['url'], - attr_items=attr_item['items'], - price=attr_item['price'], - old_price=attr_item['old_price'], - images=attr_item['images'], - )) - for image_url in attr_item['images']: - if image_url not in main_images: - main_images.append(image_url) - goods_info.images = main_images - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info diff --git a/lib/module/bricomarche.py b/lib/module/bricomarche.py deleted file mode 100644 index 97c616d..0000000 --- a/lib/module/bricomarche.py +++ /dev/null @@ -1,201 +0,0 @@ -from core import spiders, types -from utils import formats, messages -from DrissionPage.common import Keys - -class SpiderModule(spiders.Spiders): - project_name = "bricomarche" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 5, - worker_num = 1, - switch_clash = False, - reflush_browser = False - ) - self.tab.get('https://www.bricomarche.pl/') - # input('wait:') - - def get_category_urls(self) -> list[str]: - category_urls = [] - - self.tab.get('https://www.bricomarche.pl/') - one_menu_eles = self.tab.eles('xpath=//*[@id="root"]/main/div[5]/div[3]/nav/div') - for one_menu_ele in one_menu_eles: - one_link_ele = one_menu_ele.ele('@tag()=a') - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - two_menu_eles = one_menu_ele.eles('xpath=div/div[1]/div') - for two_menu_ele in two_menu_eles: - two_link_ele = two_menu_ele.ele('@tag()=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - three_menu_eles = two_menu_ele.eles('xpath=ul/li') - for three_menu_ele in three_menu_eles: - three_link_ele = three_menu_ele.ele('@tag()=a') - three_url = three_link_ele.attr('href') - three_name = three_link_ele.text.replace('/', '-') - category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - page = 1 - limit = 100 - self.tab.get(f"{category_url}?page={page}&limit={limit}") - if self.tab.ele('@tag()=h2').text == '执行安全验证': - self.tab.wait(10) - self.tab.actions.type((Keys.TAB, Keys.SPACE)) - goods_urls = [] - - while True: - try: - self.tab.scroll.to_bottom() - goods_eles = self.tab.eles('xpath=//*[@id="spark"]/div[2]/div/section/div/div/main/div[2]/section/div') - for goods_ele in goods_eles: - goods_link_ele = goods_ele.ele('@tag()=a') - goods_urls.append(goods_link_ele.attr('href')) - if len(goods_eles) == 0: - break - except: - break - page += 1 - self.tab.get(f"{category_url}?page={page}&limit={limit}") - if self.tab.ele('@tag()=h2').text == '执行安全验证': - self.tab.wait(10) - self.tab.actions.type((Keys.TAB, Keys.SPACE)) - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - - image_eles = tab.eles('xpath=//*[@id="spark"]/div[2]/div/main/div/div[2]/section[1]/div/div[1]/div/div/div/div/div') - for image_ele in image_eles: - image_link_ele = image_ele.ele('xpath=button/div/img') - image_urls.append(image_link_ele.attr('src').replace('gallery_100_91', 'gallery')) - - return image_urls - - tab = self.browser.new_tab(url) - while True: - try: - if tab.ele('@tag()=h2').text == '执行安全验证': - tab.wait(10) - tab.actions.type((Keys.TAB, Keys.SPACE)) - tab.wait(5) - else: - break - except: - break - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - brand = '' - # try: - # brand = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1/div[1]', timeout=10).text - # except: - # pass - - title = tab.ele('@tag()=h1', timeout=10).text - - desc = "" - try: - desc = formats.clean_html(tab.ele('.attributes').html) - except: - pass - - # try: - price_ele = tab.ele('.main-price') - price = float(f"{price_ele.ele('.whole').text}{price_ele.ele('.cents').text.replace(' zł', '')}") - # except: - # price = 0.0 - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - m_data = [] - attr_items = [] - # color_urls = [url] - # color_eles = tab.eles('xpath=//*[@id="contentContainer"]/form/div[2]/div[2]/div/ul/li') - # for color_ele in color_eles[1:]: - # color_link_ele = color_ele.ele('xpath=a') - # color_urls.append(color_link_ele.attr('href')) - # if len(color_urls) > 1: - # m_data = ["Color"] - - # if len(color_urls) > 1: - # for color_url in color_urls: - # color_images = main_images - # if color_url != url: - # tab.get(color_url) - # if brand == '': - # title = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1').text - # else: - # title = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1/div[2]').text - # color_images = get_image_urls() - - # price = float(f"{tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/section[2]/div[1]/div[2]/span[1]').text}.{tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/section[2]/div[1]/div[2]/span[3]').text}") - # old_price = price - - # try: - # item_name = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[2]/div/ul/li[1]/div[2]/p').text - # except: - # continue - # attr_items.append({ - # 'url': color_url, - # 'items': [item_name], - # 'price': price, - # 'old_price': old_price, - # 'images': color_images - # }) - - if len(attr_items) == 0: - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - else: - goods_info.attr = 'M' - goods_info.attr_items = m_data - for attr_item in attr_items: - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - url=attr_item['url'], - attr_items=attr_item['items'], - price=attr_item['price'], - old_price=attr_item['old_price'], - images=attr_item['images'], - )) - for image_url in attr_item['images']: - if image_url not in main_images: - main_images.append(image_url) - goods_info.images = main_images - # goods_info.p_urls = color_urls - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info diff --git a/lib/module/condom69.py b/lib/module/condom69.py deleted file mode 100644 index 51a6893..0000000 --- a/lib/module/condom69.py +++ /dev/null @@ -1,136 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "condom69" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 30, - worker_num = 5, - switch_clash = False, - reflush_browser = False - ) - self.tab.get('https://www.condom69.net/') - # input('wait:') - - def get_category_urls(self) -> list[str]: - category_urls = [] - - one_menu_eles = self.tab.eles('xpath=//*[@id="nav-one"]/li') - for one_menu_ele in one_menu_eles[:-1]: - one_link_ele = one_menu_ele.ele('xpath=a') - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - two_menu_eles = one_menu_ele.eles('xpath=div/ul/li', timeout=1) - for two_index, two_menu_ele in enumerate(two_menu_eles): - two_link_ele = two_menu_ele.ele('xpath=div/a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-').replace(',', ',').replace('#', ' ') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - # try: - # three_menu_eles = self.tab.ele(f'xpath=//*[@id="__next"]/div[1]/header/div/div[2]/nav/div[{two_index+1}]/div/div[1]').eles('@tag()=li') - # except: - # continue - # for three_menu_ele in three_menu_eles: - # three_link_ele = three_menu_ele.ele('@tag()=a') - # three_url = three_link_ele.attr('href') - # three_name = three_link_ele.text.replace('/', '-') - # category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - page = 1 - self.tab.get(f"{category_url}&pg={page}") - - #####获取页数#### - - ################# - - goods_urls = [] - url_index = {} - while True: - self.tab.scroll.to_bottom() - goods_eles = self.tab.eles('.divProdItemImg2Inner') - page_urls = [] - for goods_ele in goods_eles: - goods_url = f"{goods_ele.ele('xpath=a').attr('href')}" - if goods_url not in url_index: - page_urls.append(goods_url) - url_index[goods_url] = None - if len(page_urls) > 0: - goods_urls += page_urls - else: - break - page += 1 - self.tab.get(f"{category_url}&pg={page}") - - messages.sendInfo(f"{len(goods_urls)} 个") - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - image_eles = tab.eles('xpath=/html/body/form/div[3]/div[2]/div/div[2]/div/div/div[2]/div[2]/div[3]/div/div[2]/div/div/div[1]/div[1]/div[2]/div') - - for image_ele in image_eles: - image_url = image_ele.ele('xpath=div/div/a/img').attr('src') - image_urls.append(image_url) - return image_urls - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - h1_ele = tab.ele('xpath=/html/body/form/div[3]/div[2]/div/div[2]/div/div/div[2]/div[2]/div[3]/div/div[2]/div/div/div[1]/div[2]/div/div[1]') - brand = '' - try: - brand = tab.ele('xpath=/html/body/form/div[3]/div[2]/div/div[2]/div/div/div[2]/div[2]/div[3]/div/div[2]/div/div/div[1]/div[2]/div/div[2]/div[1]/table/tbody/tr/td[3]/a').text - except: - pass - title = h1_ele.text - - desc = "" - try: - desc = formats.clean_html(tab.ele('.ctl00_cphContent_ucUsrIndProduct_pnlIndProdDesc').html) - except: - pass - - price = tab.ele('xpath=/html/body/form/div[3]/div[2]/div/div[2]/div/div/div[2]/div[2]/div[3]/div/div[2]/div/div/div[1]/div[2]/div/div[2]/div[3]/div[1]/div[2]/span').text.replace(',', '') - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info diff --git a/lib/module/dk_one.py b/lib/module/dk_one.py deleted file mode 100644 index e037a4f..0000000 --- a/lib/module/dk_one.py +++ /dev/null @@ -1,210 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "dk_one" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 30, - worker_num = 1, - switch_clash = False, - reflush_browser = False - ) - - def get_category_urls(self) -> list[str]: - category_urls = [] - - self.tab.get('https://www.dk_one.com/') - one_menu_eles = self.tab.eles('xpath=/html/body/div[5]/header/div[2]/div[2]/div/div[1]/div[1]/ul/li') - for one_menu_ele in one_menu_eles: - one_link_ele = one_menu_ele.ele('@tag()=a') - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - if one_name == '라이프': - continue - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - two_menu_eles = one_menu_ele.eles('xpath=div/div/div[1]/ul/li') - for two_menu_ele in two_menu_eles: - two_link_ele = two_menu_ele.ele('@tag()=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - if two_name == '메인': - continue - category_urls.append(f"{two_url}#{one_name}/{two_name}") - two_menu_eles = one_menu_ele.eles('xpath=div/div/div[2]/ul/li') - for two_menu_ele in two_menu_eles: - two_link_ele = two_menu_ele.ele('@tag()=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - if two_name == '메인': - continue - category_urls.append(f"{two_url}#{one_name}/Top Brand/{two_name}") - - # three_menu_eles = two_menu_ele.eles('xpath=ul/li') - # for three_menu_ele in three_menu_eles: - # three_link_ele = three_menu_ele.ele('@tag()=a') - # three_url = three_link_ele.attr('href') - # three_name = three_link_ele.text.replace('/', '-') - # category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - self.tab.get(category_url) - goods_urls = [] - goods_eles = self.tab.eles('xpath=//*[@id="prodList"]/div') - for goods_ele in goods_eles: - goods_link_ele = goods_ele.ele('.prod-link') - goods_urls.append(goods_link_ele.attr('href')) - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(tab): - image_urls = [] - image_eles = tab.ele('#prod-img').eles('@tag()=img') - for image_ele in image_eles: - image_urls.append(image_ele.attr('src')) - return image_urls - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - brand = '' - # try: - # brand = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1/div[1]', timeout=10).text - # except: - # pass - # if brand == '': - # title = tab.ele('xpath=//*[@id="contentContainer"]/form/div[2]/div[1]/h1').text - # else: - title = tab.ele('.page-title').text - - try: - desc = formats.clean_html(tab.ele('@@class=tab-content@@id=tabContent0202').html) - except: - desc = '' - - price = float(tab.ele('.price-group').ele('.val').text.replace(',', '')) - try: - old_price = float(tab.ele('.price-group origin').text.replace(',', '')) - except: - old_price = price - - main_images = get_image_urls(tab) - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - images=main_images - ) - - m_data = [] - color_data = {} - color_eles = [] - # 颜色 - tab.ele('.opt-color') - m_data.append('컬러') - color_eles = tab.ele('.color-list-wrap').eles('.prod-color-rdo') - - m_data.append('사이즈') - - for color_ele in color_eles: - color_input_onclick = color_ele.ele('@tag()=input').attr('onclick') - have_url = False - if 'location.href=' in color_input_onclick: - color_url = 'https://dk-on.com' + formats.re_search(color_input_onclick, r"location\.href\s*=\s*'([^']*)'") - color_name = color_url.split('/')[-1] - have_url = True - elif 'fnColorClicked' in color_input_onclick: - color_url = goods_info.url - color_name = color_ele.ele('@tag()=input').attr('value') - color_ele.click() - else: - color_url = goods_info.url - color_name = goods_info.title.split(' / ')[-1] - - color_data[color_name] = {'url': color_url, 'have_url': have_url, 'ele': color_ele} - goods_info.p_urls.append(color_url) - - real_color_data = {} - - - for color_name, color_item in color_data.items(): - color_tab = tab - if color_item['have_url']: - color_tab = self.browser.new_tab() - - size_data = [] - if color_item['have_url']: - color_tab.get(color_item['url']) - else: - color_item['ele'].click() - color_tab.wait(1) - color_item['price'] = str(color_tab.ele('.price-group').ele('.val').text.replace(',', '')) - try: - color_item['old_price'] = str(color_tab.ele('.price-group origin').text.replace(',', '')) - except: - color_item['old_price'] = color_item['price'] - - # 颜色对应商品图 - color_item['images'] = get_image_urls(tab = color_tab) - - # 颜色对应尺码 - radio_eles = color_tab.ele('.prod-size-list').eles('.prod-size') - for radio_ele in radio_eles: - value = radio_ele.ele('@tag()=label').text - if value == None: - continue - size_data.append(value) - color_item['size'] = size_data - - real_color_data[color_tab.ele('.page-title').text.split(' / ')[-1]] = color_item - color_data = real_color_data - - goods_info.attr = 'M' - goods_info.title = goods_info.title.split(' / ')[0] - goods_info.attr_items = m_data - for color_name, color_item in color_data.items(): - for color_image in color_item['images']: - if color_image in goods_info.images: - continue - goods_info.images.append(color_image) - - # if color_data: - item_data = [] - for color_name, color_item in color_data.items(): - for size in color_item['size']: - item_data.append([color_name, size]) - for attribute_items in item_data: - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - attr_items=attribute_items, - price=color_data[attribute_items[0]]['price'], - old_price=color_data[attribute_items[0]]['price'], - images=color_data[attribute_items[0]]['images'], - )) - - except Exception as e: - try: - tab.close() - color_tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - color_tab.close() - except: - pass - return goods_info diff --git a/lib/module/friskybusiness.py b/lib/module/friskybusiness.py deleted file mode 100644 index 9a1575c..0000000 --- a/lib/module/friskybusiness.py +++ /dev/null @@ -1,141 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "friskybusiness" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 30, - worker_num = 5, - switch_clash = False, - reflush_browser = False - ) - self.tab.get('https://friskybusiness.sg/') - # input('wait:') - - def get_category_urls(self) -> list[str]: - category_urls = [] - - one_menu_eles = self.tab.eles('xpath=/html/body/header/height-observer/x-header/nav[2]/ul/li') - for one_index, one_menu_ele in enumerate(one_menu_eles[:-1]): - - one_link_ele = one_menu_ele.ele('@tag()=summary') - one_url = one_link_ele.attr('data-follow-link') - one_name = one_link_ele.text.replace('/', '-') - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - if one_index == 0 or one_index == 6: - two_menu_eles = one_menu_ele.eles('xpath=mega-menu-disclosure/details/div/div/a') - else: - two_menu_eles = one_menu_ele.eles('xpath=mega-menu-disclosure/details/div/ul/li', timeout=1) - for two_index, two_menu_ele in enumerate(two_menu_eles): - if one_index == 0 or one_index == 6: - two_link_ele = two_menu_ele - else: - two_link_ele = two_menu_ele.ele('@tag()=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-').replace(',', ',').replace('#', ' ') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - try: - three_menu_eles = two_menu_ele.eles(f'xpath=div/ul/li') - except: - continue - for three_menu_ele in three_menu_eles: - three_link_ele = three_menu_ele.ele('@tag()=a') - three_url = three_link_ele.attr('href') - three_name = three_link_ele.text.replace('/', '-').replace(',', ',').replace('#', ' ') - category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - page = 1 - self.tab.get(f"{category_url}?page={page}") - goods_urls = [] - - #####获取页数#### - - ################# - - goods_urls = [] - while True: - self.tab.scroll.to_bottom() - try: - goods_eles = self.tab.eles('#:snize-product-', timeout=5) - for goods_ele in goods_eles: - goods_url = f"{goods_ele.ele('@tag()=a').attr('href')}" - goods_urls.append(goods_url) - if len(goods_eles) == 0: - break - except: - break - page += 1 - self.tab.get(f"{category_url}?page={page}") - - messages.sendInfo(f"{len(goods_urls)} 个") - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - image_eles = tab.eles('xpath=/html/body/main/section[1]/div/div/product-rerender/div/product-gallery/safe-sticky/product-gallery-navigation/button') - - for image_ele in image_eles[-1:]: - image_url = image_ele.ele('xpath=img').attr('src') - image_urls.append(image_url) - return image_urls - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - h1_ele = tab.ele('@tag()=h1') - brand = '' - title = h1_ele.text - - desc = "" - try: - desc = formats.clean_html(tab.ele('.liquid').html) - except: - pass - - price_list = tab.ele('.price-list price-list--product') - price = price_list.ele('@tag()=sale-price').ele('.money').text.replace('$', '').replace(',', '') - try: - old_price = price_list.ele('@tag()=compare-at-price').ele('.money').text.replace('$', '').replace(',', '') - except: - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info diff --git a/lib/module/peek_cloppenburg.py b/lib/module/peek_cloppenburg.py deleted file mode 100644 index ca21863..0000000 --- a/lib/module/peek_cloppenburg.py +++ /dev/null @@ -1,217 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "peek-cloppenburg" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 30, - worker_num = 5, - switch_clash = False, - reflush_browser = False - ) - - def get_category_urls(self) -> list[str]: - category_urls = [] - - self.tab.get('https://www.peek-cloppenburg.at/') - one_menu_eles = self.tab.ele('@data-testid=header-links').eles('@tag()=a') - for one_menu_ele in one_menu_eles: - one_link_ele = one_menu_ele - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - one_link_ele.click() - self.tab.wait(3) - - two_menu_eles = self.tab.eles('xpath=//*[@id="__next"]/div[1]/header/div[2]/div[2]/nav/a', timeout=1) - for two_index, two_menu_ele in enumerate(two_menu_eles): - two_link_ele = two_menu_ele - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - try: - three_menu_eles = self.tab.ele(f'xpath=//*[@id="__next"]/div[1]/header/div[2]/div[2]/nav/div[{two_index+1}]/div/div[1]').eles('@tag()=li') - except: - continue - for three_menu_ele in three_menu_eles: - three_link_ele = three_menu_ele.ele('@tag()=a') - three_url = three_link_ele.attr('href') - three_name = three_link_ele.text.replace('/', '-') - category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - self.tab.get(f"{category_url}?page=1") - goods_urls = [] - - max_page = 1 - #####获取页数#### - try: - max_page = int(self.tab.eles('@data-testid=pagination-item')[-1].text) - except: - pass - ################# - - goods_urls = [] - if max_page > 1: - for page in range(1, max_page+1): - if page > 1: - self.tab.get(f"{category_url}?page={page}&userId=123456") - - goods_eles = self.tab.eles('xpath=//*[@id="__next"]/div[2]/div/section/div/div[2]/div[5]/div/section[1]/section/div/div') - for goods_ele in goods_eles: - goods_url = f"{goods_ele.ele('@tag()=a').attr('href')}" - goods_urls.append(goods_url) - messages.sendInfo(f"{page}/{max_page}") - else: - goods_eles = self.tab.eles('xpath=//*[@id="__next"]/div[2]/div/section/div/div[2]/div[5]/div/section[1]/section/div/div') - for goods_ele in goods_eles: - goods_url = f"{goods_ele.ele('@tag()=a').attr('href')}" - goods_urls.append(goods_url) - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - image_eles = tab.ele('#photoswipe-gallery').eles('@tag()=a') - - for image_ele in image_eles: - image_url = image_ele.attr('href') - image_urls.append(image_url) - return image_urls - - def get_size_eles(): - try: - eles = tab.ele('.option-picker mt-2 ').eles('@tag()=li') - except: - pass - try: - eles = tab.ele('.option-picker mt-2 long-label ').eles('@tag()=li') - except: - pass - try: - eles = tab.ele('.option-picker mt-2 out-of-stock').eles('@tag()=li') - except: - pass - try: - eles = tab.ele('.option-picker mt-2 long-label out-of-stock').eles('@tag()=li') - except: - pass - return eles - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - h1_eles = tab.ele('@tag()=h1', timeout=10).eles('@tag()=span') - brand = '' - try: - brand = h1_eles[0].text - title = h1_eles[1].text - except: - title = tab.ele('@tag()=h1').text - - desc = "" - try: - desc = formats.clean_html(f"{tab.ele('#accordion-panel-material-care').html}{tab.ele('#accordion-panel-details').html}") - except: - pass - - price = tab.ele('.:text-pdp-price-primary-xs font-bold').text.split(' ')[0].replace(',', '.') - try: - old_price = tab.ele('.line-through').text.split(' ')[0].replace(',', '.') - except: - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - m_data = [] - attr_items = [] - color_urls = [] - try: - color_eles = tab.ele('.pt-6 xl:pt-8 -mr-6 md:mr-0').eles('@tag()=li') - m_data.append('Farbe') - for color_ele in color_eles: - color_url = color_ele.ele('@tag()=a').attr('href') - color_urls.append(color_url) - except: - pass - m_data.append('Größe') - - if len(color_urls) > 0: - for color_url in color_urls: - color_images = main_images - if color_url != url: - tab.get(color_url) - color_images = get_image_urls() - - price = tab.ele('.:text-pdp-price-primary-xs font-bold').text.split(' ')[0].replace(',', '') - try: - old_price = tab.ele('.line-through').text.split(' ')[0].replace(',', '') - except: - old_price = price - - color_name = tab.ele('.text-cp-md font-bold').ele('xpath=text()[3]') - - size_eles = get_size_eles() - for size_ele in size_eles: - size_name = size_ele.ele('.text-cp-md truncate').text - - attr_items.append({ - 'url': color_url, - 'items': [color_name, size_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - - if len(attr_items) == 0: - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - else: - goods_info.attr = 'M' - goods_info.attr_items = m_data - for attr_item in attr_items: - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - url=attr_item['url'], - attr_items=attr_item['items'], - price=attr_item['price'], - old_price=attr_item['old_price'], - images=attr_item['images'], - )) - for image_url in attr_item['images']: - if image_url not in main_images: - main_images.append(image_url) - goods_info.images = main_images - goods_info.p_urls = color_urls - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info diff --git a/lib/module/peek_cloppenburg_nl.py b/lib/module/peek_cloppenburg_nl.py deleted file mode 100644 index 6be9f3b..0000000 --- a/lib/module/peek_cloppenburg_nl.py +++ /dev/null @@ -1,213 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "peek-cloppenburg-nl" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 30, - worker_num = 5, - switch_clash = False, - reflush_browser = False - ) - - def get_category_urls(self) -> list[str]: - category_urls = [] - - self.tab.get('https://www.peek-cloppenburg.nl/') - one_menu_eles = self.tab.ele('@data-testid=header-links').eles('@tag()=a') - for one_menu_ele in one_menu_eles: - one_link_ele = one_menu_ele - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - one_link_ele.click() - self.tab.wait(3) - - two_menu_eles = self.tab.eles('xpath=//*[@id="__next"]/div[1]/header/div/div[2]/nav/a', timeout=1) - for two_index, two_menu_ele in enumerate(two_menu_eles): - two_link_ele = two_menu_ele - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - try: - three_menu_eles = self.tab.ele(f'xpath=//*[@id="__next"]/div[1]/header/div/div[2]/nav/div[{two_index+1}]/div/div[1]').eles('@tag()=li') - except: - continue - for three_menu_ele in three_menu_eles: - three_link_ele = three_menu_ele.ele('@tag()=a') - three_url = three_link_ele.attr('href') - three_name = three_link_ele.text.replace('/', '-') - category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - self.tab.get(f"{category_url}?page=1") - goods_urls = [] - - max_page = 1 - #####获取页数#### - try: - max_page = int(self.tab.eles('@data-testid=pagination-item')[-1].text) - except: - pass - ################# - - goods_urls = [] - if max_page > 1: - for page in range(1, max_page+1): - if page > 1: - self.tab.get(f"{category_url}?page={page}&userId=123456") - - goods_eles = self.tab.eles('xpath=//*[@id="__next"]/div[2]/div/section/div/div[2]/div[5]/div/section[1]/section/div/div') - for goods_ele in goods_eles: - goods_url = f"{goods_ele.ele('@tag()=a').attr('href')}" - goods_urls.append(goods_url) - messages.sendInfo(f"{page}/{max_page}") - else: - goods_eles = self.tab.eles('xpath=//*[@id="__next"]/div[2]/div/section/div/div[2]/div[5]/div/section[1]/section/div/div') - for goods_ele in goods_eles: - goods_url = f"{goods_ele.ele('@tag()=a').attr('href')}" - goods_urls.append(goods_url) - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - image_eles = tab.ele('#photoswipe-gallery').eles('@tag()=a') - - for image_ele in image_eles: - image_url = image_ele.attr('href') - image_urls.append(image_url) - return image_urls - - def get_size_eles(): - try: - eles = tab.ele('.option-picker mt-2 ').eles('@tag()=li') - except: - pass - try: - eles = tab.ele('.option-picker mt-2 long-label ').eles('@tag()=li') - except: - pass - try: - eles = tab.ele('.option-picker mt-2 out-of-stock').eles('@tag()=li') - except: - pass - try: - eles = tab.ele('.option-picker mt-2 long-label out-of-stock').eles('@tag()=li') - except: - pass - return eles - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - h1_eles = tab.ele('@tag()=h1').eles('@tag()=span') - brand = h1_eles[0].text - title = h1_eles[1].text - - desc = "" - try: - desc = formats.clean_html(f"{tab.ele('#accordion-panel-material-care').html}{tab.ele('#accordion-panel-details').html}") - except: - pass - - price = tab.ele('.:text-pdp-price-primary-xs font-bold').text.split(' ')[1].replace(',', '.') - try: - old_price = tab.ele('.line-through').text.split(' ')[1].replace(',', '.') - except: - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - m_data = [] - attr_items = [] - color_urls = [] - try: - color_eles = tab.ele('.pt-6 xl:pt-8 -mr-6 md:mr-0').eles('@tag()=li') - m_data.append('Kleur') - for color_ele in color_eles: - color_url = color_ele.ele('@tag()=a').attr('href') - color_urls.append(color_url) - except: - pass - m_data.append('Maat') - - if len(color_urls) > 0: - for color_url in color_urls: - color_images = main_images - if color_url != url: - tab.get(color_url) - color_images = get_image_urls() - - price = tab.ele('.:text-pdp-price-primary-xs font-bold').text.split(' ')[1].replace(',', '.') - try: - old_price = tab.ele('.line-through').text.split(' ')[1].replace(',', '.') - except: - old_price = price - - color_name = tab.ele('.text-cp-md font-bold').ele('xpath=text()[3]') - - size_eles = get_size_eles() - for size_ele in size_eles: - size_name = size_ele.ele('.text-cp-md truncate').text - - attr_items.append({ - 'url': color_url, - 'items': [color_name, size_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - - if len(attr_items) == 0: - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - else: - goods_info.attr = 'M' - goods_info.attr_items = m_data - for attr_item in attr_items: - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - url=attr_item['url'], - attr_items=attr_item['items'], - price=attr_item['price'], - old_price=attr_item['old_price'], - images=attr_item['images'], - )) - for image_url in attr_item['images']: - if image_url not in main_images: - main_images.append(image_url) - goods_info.images = main_images - goods_info.p_urls = color_urls - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info diff --git a/lib/module/ssfshop.py b/lib/module/ssfshop.py deleted file mode 100644 index 7dd4674..0000000 --- a/lib/module/ssfshop.py +++ /dev/null @@ -1,371 +0,0 @@ -from core import spiders, types -from utils import formats, messages, files -import requests - -class SpiderModule(spiders.Spiders): - project_name = "ssfshop" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 300, - worker_num = 24, - switch_clash = False, - reflush_browser = False - ) - - def get_category_urls(self) -> list[str]: - category_urls = [] - - self.tab.get('https://www.ssfshop.com/') - one_menu_eles = self.tab.eles('xpath=/html/body/div[5]/header/div[2]/div[2]/div/div[1]/div[1]/ul/li') - for one_menu_ele in one_menu_eles: - one_link_ele = one_menu_ele.ele('@tag()=a') - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - if one_name == '라이프': - continue - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - two_menu_eles = one_menu_ele.eles('xpath=div/div/div[1]/ul/li') - for two_menu_ele in two_menu_eles: - two_link_ele = two_menu_ele.ele('@tag()=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - if two_name == '메인': - continue - category_urls.append(f"{two_url}#{one_name}/{two_name}") - two_menu_eles = one_menu_ele.eles('xpath=div/div/div[2]/ul/li') - for two_menu_ele in two_menu_eles: - two_link_ele = two_menu_ele.ele('@tag()=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - if two_name == '메인': - continue - category_urls.append(f"{two_url}#{one_name}/Top Brand/{two_name}") - - # three_menu_eles = two_menu_ele.eles('xpath=ul/li') - # for three_menu_ele in three_menu_eles: - # three_link_ele = three_menu_ele.ele('@tag()=a') - # three_url = three_link_ele.attr('href') - # three_name = three_link_ele.text.replace('/', '-') - # category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - page = 1 - self.tab.get(f"{category_url}¤tPage={page}&sortColumn=SALE_QTY_SEQ&serviceType=DSP&ctgrySectCd=GNRL_CTGRY&fitPsbYn=N") - goods_urls = [] - - url_index = {} - while True: - self.tab.scroll.to_bottom() - page_urls = [] - goods_eles = self.tab.eles('.god-item') - for goods_ele in goods_eles: - goods_link_ele = goods_ele.ele('xpath=a') - if goods_link_ele.attr('href') in url_index: - continue - page_urls.append(goods_link_ele.attr('href')) - url_index[goods_link_ele.attr('href')] = None - - if len(page_urls) == 0: - break - if len(goods_urls) > 5000: - break - goods_urls += page_urls - page += 1 - self.tab.get(f"{category_url}¤tPage={page}&sortColumn=SALE_QTY_SEQ&serviceType=DSP&ctgrySectCd=GNRL_CTGRY&fitPsbYn=N") - self.tab.wait(1) - - return goods_urls - - def get_goods_info(self, url: str) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - - for _ in range(10): - image_eles = tab.eles('xpath=//*[@id="godImgThumb"]/div') - if len(image_eles) > 0: - break - tab.wait(3) - for image_ele in image_eles: - image_link_ele = image_ele - image_urls.append('https://img.ssfshop.com'+image_link_ele.attr('data')) - - return image_urls - - def get_options(godNo, optValCd1, optValCd2 = ''): - headers = { - 'Accept': 'application/json, text/javascript, */*; q=0.01', - 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', - 'Connection': 'keep-alive', - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - 'Origin': 'https://www.ssfshop.com', - 'Referer': url, - 'Sec-Fetch-Dest': 'empty', - 'Sec-Fetch-Mode': 'cors', - 'Sec-Fetch-Site': 'same-origin', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0', - 'X-CSRF-TOKEN': 'e8e4bcd2-b976-4ca3-89b0-c85de0d1f3b0', - 'X-Requested-With': 'XMLHttpRequest', - 'sec-ch-ua': '"Chromium";v="146", "Not-A.Brand";v="24", "Microsoft Edge";v="146"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - # 'Cookie': 'PCID=17748347492661999807244; UTID=17748347492661999807244; MAI="eyJsb2dpbiI6Ik4ifQ=="; WMONID=mUUUMLseCyQ; AWSALBAPP-1=_remove_; AWSALBAPP-2=_remove_; AWSALBAPP-3=_remove_; visid_incap_2173964=lpNXES71Q5iAc3f2rzl/jTzUyWkAAAAAQUIPAAAAAABeBQZ8XijRe/SDlNUYlcCm; nlbi_2173964_3216183=TbQ1Ku6HAX5AN79F2g4AdQAAAADFBJVdMHKyRlRjq5BE8+sZ; storedUrl=Y; visid_incap_2794548=/x/uA+w/Rna/+lXitrmX20DUyWkAAAAAQUIPAAAAAACOgO5Lt68U4l70FJ35r3uf; incap_ses_725_2173964=A1WxV+agRSxFFqDq6bcPCtPnyWkAAAAAl1pNcoghbBUv0Idr250rQA==; visid_incap_2898463=WYviBGzFSwWHcJFJUGirBdXnyWkAAAAAQUIPAAAAAAAtfVuBlsqIe97ZjwN6QI2j; nlbi_2898463=wXQSYet0xyoFwAnd4MbCSgAAAAArzXmJlyqxxSh3+i0S9GbO; incap_ses_725_2898463=s8pzSCxlllS0GaDq6bcPCtXnyWkAAAAAu3cfqwOGa86YepyhOT6TvQ==; nth_pcid=3d5ffbba-60dd-a49a-6747-a542beef7538-1774839765504; incap_ses_725_2794548=D/rjK2Wq+zSjGqDq6bcPCtXnyWkAAAAAwfdIptRC0JfZMv8gf0dFHw==; incap_ses_724_2173964=dLR3AfGiVBRg7b2bbSoMCuEsymkAAAAAo4viBM5iG3asWiau6QX32w==; incap_ses_724_2898463=/V2oJwzj6BLV8L2bbSoMCuMsymkAAAAA9Ybn1njwVQ3r7KT6QLCZcg==; incap_ses_724_2794548=3i9aHRkHkTdh872bbSoMCugsymkAAAAAt9AH6HTki4ssrvCcPmSpIA==; AWSALBTG=AIb2slX0AEp+Mv3KJalsspDk7579UU9Jv2/3kjqEGNWjsIrDM+27+/1Ke7bKfPJDQPkvjZ2Sxz50ZoGgs7wax+6xPQZc22NzAPVhfCwSibc44xWGCNEUT9ixCDWhVrmeHJTF4AGiXACsmVs+73qXWgynz4bNZxFvwGcomdcZ09QX; AWSALB=1Lc2nZgyDqlHzKH2Ht9zUCbVzO3nmyjbvR6L8TbjmEzgIJXLWPHd2TKRrA4NweRQ4J3aqEC0O7/FVTTgdHmYYm6M1K3NeLkZbyrFTXyTGk7GFDh5nYLYl/aBRLKe; AWSALBCORS=1Lc2nZgyDqlHzKH2Ht9zUCbVzO3nmyjbvR6L8TbjmEzgIJXLWPHd2TKRrA4NweRQ4J3aqEC0O7/FVTTgdHmYYm6M1K3NeLkZbyrFTXyTGk7GFDh5nYLYl/aBRLKe; AWSALBAPP-0=AAAAAAAAAACeq+TZG7CFWkFz6UEyoFzfgzCso6p2one/fqTkDd1D8aJwmBMDcXt1z/4SFXLjp7cnG/VXtUeFI5VsG2vzUNb7CeolT4ZG4OzG2MYZTDISyFXF0Ftu3Y5EnlA+ClLy5QvoVKs=; nlbi_2173964_2029297=AebNbzFaqQMN0dyi2g4AdQAAAADw44LnFE5aKd0nWF3BiMTo; STID=1774941024138741600844420260331161024; INFLOW_SN=99993; N_INFLOW_SN=Y; PC_JSESSIONID=054FCD4B9E7ABB3B015CF732C022A41B; incap_ses_138_2173964=rIZHCDf5DCYIKM99lkbqAV9zy2kAAAAAhshd7O+yiHEnrcRAybEDaw==; incap_ses_138_2898463=zRn2E3KmY3qUMM99lkbqAWBzy2kAAAAAT0zfogyh0Cs4exDxqH0C5w==; nlbi_2794548=gojpVZcccHOhC/svvoS1vwAAAAB8htUpn549dG0/xu4xckFq; incap_ses_138_2794548=A1yKCZEQdFLyMc99lkbqAWBzy2kAAAAAcNViNS39K56YSoYGpK3p0A==; _TODAYALLLIST="[{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GM0026011527285\\",\\"regDt\\":\\"1774840170633\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GQ3A26021060165\\",\\"regDt\\":\\"1774920131600\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GM0025122296270\\",\\"regDt\\":\\"1774920840210\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GQJ924040149659\\",\\"regDt\\":\\"1774921134062\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GR4H25042395931\\",\\"regDt\\":\\"1774921515277\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GQZG26012945089\\",\\"regDt\\":\\"1774921868451\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GQZG26012945090\\",\\"regDt\\":\\"1774921870125\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GQZG26012945092\\",\\"regDt\\":\\"1774921872189\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GRRI26030602949\\",\\"regDt\\":\\"1774941024251\\"},{\\"todayGodSectCd\\":\\"GOD\\",\\"godNo\\":\\"GRRI26030602950\\",\\"regDt\\":1774941046056}]"; godClickInfo=GQY026032636412||GM0026011527285||GQ3A26021060165||GM0025122296270||GR4H25042395931||GR4H25042395931||GQJ924040149659||GR4H25042395931||GR4H25042395931||GQZG26012945092||GQZG26012945089||GQZG26012945090||GQZG26012945092||GQZG26012945089||GQZG26012945090||GQZG26012945092||GRRI26030602949||GRRI26030602950', - } - - data = { - 'optValCd1': optValCd1, - 'optValCd2': optValCd2, - 'optValCd3': '', - 'godNo': godNo, - } - - response = requests.post('https://www.ssfshop.com/public/goods/selectGodDetailOpt', headers=headers, data=data, proxies={'http': 'http://127.0.0.1:7890','https': 'http://127.0.0.1:7890'}) - json_data = response.json() - - options = {} - if 'opt' not in json_data: - return options - - for option in json_data['opt']: - for i in range(1, 6): - key = f"optValNm{i}" - if option[key]: - options[option[key]] = {} - break - return options - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - brand = url.split('/')[3] - godNo = url.split('/')[4] - - title = tab.ele('#goodDtlTitle').text - - desc = "" - try: - desc = tab.ele('#godsTabView').html - except: - pass - - price = float(tab.ele('xpath=//*[@id="content"]/section/div[2]/div[2]/div[3]/span').ele('.price').text.replace(',', '')) - try: - old_price = float(tab.ele('xpath=//*[@id="content"]/section/div[2]/div[2]/div[3]/span/span[1]/del').text.replace(',', '')) - except: - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - m_data = [] - attr_items = [] - color_urls = [] - try: - tab.ele('.gods-option').ele('text=색상').click() - color_eles = tab.eles('xpath=//*[@id="content"]/section/div[2]/div[2]/div[6]/div[1]/div/span/label') - for color_ele in color_eles: - color_url = color_ele.attr('onclick') - if color_url: - color_url = color_url.split("'")[1] - else: - color_url = url - if 'https://' not in color_url: - color_url = 'https://www.ssfshop.com'+color_url - color_urls.append(color_url) - except: - pass - - if len(color_urls) > 1: - m_data = ["색상"] - - try: - option_eles = tab.ele('#prdInfoOptionArea').eles('#:optSelectPartmalDiv') - except: - option_eles = [] - for option_ele in option_eles: - m_data.append(option_ele.ele('@tag()=input').attr('opt-nm')) - m_data = m_data[:3] - - option_data = {} - if len(option_eles) > 0: - try: - option_eles[0].click() - except: - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - try: - tab.close() - except: - pass - return goods_info - tab.wait(0.5) - option1_eles = option_eles[0].eles('@tag()=li') - for option1_ele in option1_eles: - option_data[option1_ele.text] = get_options(godNo, option1_ele.text) - for option2_name, items in option_data[option1_ele.text].items(): - option_data[option1_ele.text][option2_name] = get_options(godNo, option1_ele.text, option2_name) - - if len(color_urls) > 1: - for color_url in color_urls: - color_images = main_images - if color_url != url: - tab.get(color_url) - title = tab.ele('#goodDtlTitle').text - color_images = get_image_urls() - - godNo = color_url.split('/')[4] - try: - option_eles = tab.ele('#prdInfoOptionArea', timeout=5).eles('.select lg unapplied') - except: - option_eles = [] - option_data = {} - if len(option_eles) > 0: - option1_eles = option_eles[0].eles('xpath=div/ul/li') - for option1_ele in option1_eles: - option_data[option1_ele.text] = get_options(godNo, option1_ele.text) - for option2_name, items in option_data[option1_ele.text].items(): - option_data[option1_ele.text][option2_name] = get_options(godNo, option1_ele.text, option2_name) - - try: - color_name = title.split('-')[1] - except: - color_name = tab.ele('.buy-txts').text - - price = float(tab.ele('xpath=//*[@id="content"]/section/div[2]/div[2]/div[3]/span').ele('.price').text.replace(',', '')) - try: - old_price = float(tab.ele('xpath=//*[@id="content"]/section/div[2]/div[2]/div[3]/span/span[1]/del').text.replace(',', '')) - except: - old_price = price - - if len(option_data) > 0: - for option1_name, items1 in option_data.items(): - if len(items1) > 0: - for option2_name, items2 in items1.items(): - attr_items.append({ - 'url': color_url, - 'items': [color_name, option1_name, option2_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - else: - attr_items.append({ - 'url': color_url, - 'items': [color_name, option1_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - else: - attr_items.append({ - 'url': color_url, - 'items': [color_name], - 'price': price, - 'old_price': old_price, - 'images': color_images - }) - else: - for option1_name, items1 in option_data.items(): - if len(items1) > 0: - for option2_name, items2 in items1.items(): - if len(items2) > 0: - for option3_name, items3 in items2.items(): - attr_items.append({ - 'url': url, - 'items': [option1_name, option2_name, option3_name], - 'price': price, - 'old_price': old_price, - 'images': [] - }) - else: - attr_items.append({ - 'url': url, - 'items': [option1_name, option2_name], - 'price': price, - 'old_price': old_price, - 'images': [] - }) - else: - attr_items.append({ - 'url': url, - 'items': [option1_name], - 'price': price, - 'old_price': old_price, - 'images': [] - }) - - if len(attr_items) == 0: - try: - tab.ele('.gods-option').ele('text=사이즈').click() - size_eles = tab.eles('xpath=/html/body/div[5]/main/section/div[2]/div[2]/div[6]/div[1]/div/ul/li') - goods_info.attr = 'M' - goods_info.attr_items = ['사이즈'] - goods_info.images = main_images - for size_ele in size_eles: - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - attr_items=[size_ele.text], - price=price, - old_price=old_price, - images=[], - )) - except: - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - else: - goods_info.attr = 'M' - goods_info.attr_items = m_data - for attr_item in attr_items: - if len(attr_item['items']) != len(m_data): - attr_item['items'] += m_data[len(attr_item['items']):] - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - url=attr_item['url'], - attr_items=attr_item['items'], - price=attr_item['price'], - old_price=attr_item['old_price'], - images=attr_item['images'], - )) - for image_url in attr_item['images']: - if image_url not in main_images: - main_images.append(image_url) - goods_info.images = main_images - goods_info.p_urls = color_urls - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info - - def get_home(self): - self.tab.get('https://www.ssfshop.com/main') - li_eles = self.tab.ele('xpath=/html/body/div[5]/main/div[2]/section[2]/div/div[1]').eles('@tag()=li') - categorys = [] - for li_ele in li_eles: - a_ele = li_ele.ele('@tag()=a') - categorys.append(f"{a_ele.attr('href')}#{a_ele.text}") - files.save_list(f"{self.__data_path__}/categorys(home).txt", categorys) diff --git a/lib/module/taketoys.py b/lib/module/taketoys.py deleted file mode 100644 index 286744e..0000000 --- a/lib/module/taketoys.py +++ /dev/null @@ -1,131 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "taketoys" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 30, - worker_num = 5, - switch_clash = False, - reflush_browser = False - ) - self.tab.get('https://taketoys.sg/') - # input('wait:') - - def get_category_urls(self) -> list[str]: - category_urls = [] - - one_menu_eles = self.tab.eles('xpath=/html/body/header/div[2]/div/nav/ul/li') - for one_menu_ele in one_menu_eles[1:-1]: - one_link_ele = one_menu_ele.ele('xpath=a') - one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - two_menu_eles = one_menu_ele.eles('xpath=ul/li', timeout=1) - for two_index, two_menu_ele in enumerate(two_menu_eles): - two_link_ele = two_menu_ele.ele('xpath=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-').replace(',', ',').replace('#', ' ') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - # try: - # three_menu_eles = self.tab.ele(f'xpath=//*[@id="__next"]/div[1]/header/div/div[2]/nav/div[{two_index+1}]/div/div[1]').eles('@tag()=li') - # except: - # continue - # for three_menu_ele in three_menu_eles: - # three_link_ele = three_menu_ele.ele('@tag()=a') - # three_url = three_link_ele.attr('href') - # three_name = three_link_ele.text.replace('/', '-') - # category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - self.tab.get(f"{category_url}?page=1") - goods_urls = [] - - #####获取页数#### - - ################# - - goods_urls = [] - while True: - self.tab.scroll.to_bottom() - try: - self.tab.ele('text=Show more', timeout=5).click() - self.tab.wait(1) - except: - break - - goods_eles = self.tab.eles('.col-xs-6 col-sm-4 col-lg-3 item-wrapper') - for goods_ele in goods_eles: - goods_url = f"{goods_ele.ele('@tag()=a').attr('href')}" - goods_urls.append(goods_url) - messages.sendInfo(f"{len(goods_urls)} 个") - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - image_eles = tab.eles('xpath=/html/body/main/div[2]/div[2]/div[2]/div[2]/div/div/div[3]/div[2]/div/div') - - for image_ele in image_eles: - image_url = image_ele.ele('xpath=img').attr('src') - image_urls.append(image_url) - return image_urls - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - h1_ele = tab.ele('@tag()=h1') - brand = '' - try: - brand = h1_ele.ele('@tag()=strong').text - except: - pass - title = h1_ele.ele('@tag()=span').text - - desc = "" - try: - desc = formats.clean_html(tab.ele('#product-info-tab').html) - except: - pass - - price = tab.ele('.price').attr('title').replace('SGD', '').replace(',', '') - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - goods_info.attr = 'S' - goods_info.attr_items = [] - goods_info.images = main_images - goods_info.p_lists = [] - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info diff --git a/lib/module/tfashion.py b/lib/module/tfashion.py deleted file mode 100644 index 31e668c..0000000 --- a/lib/module/tfashion.py +++ /dev/null @@ -1,140 +0,0 @@ -from core import spiders, types -from utils import formats, messages - -class SpiderModule(spiders.Spiders): - project_name = "t-fashion" - - def __init__(self): - super().__init__( - self.project_name, - bitch = 300, - worker_num = 24, - switch_clash = False, - reflush_browser = False - ) - - def get_category_urls(self) -> list[str]: - category_urls = [] - - self.tab.get('https://www.t-fashion.jp/') - one_menu_eles = self.tab.ele('.m-aside-menu-body').eles('.js-collest-li') - for one_menu_ele in one_menu_eles: - one_link_ele = one_menu_ele.ele('@tag()=a') - # one_url = one_link_ele.attr('href') - one_name = one_link_ele.text.replace('/', '-') - # category_urls.append(f"{one_url}#{one_name}") - messages.sendInfo(one_name) - - two_menu_eles = one_menu_ele.eles('xpath=div/ul/li') - for two_menu_ele in two_menu_eles[1:]: - two_link_ele = two_menu_ele.ele('@tag()=a') - two_url = two_link_ele.attr('href') - two_name = two_link_ele.text.replace('/', '-') - category_urls.append(f"{two_url}#{one_name}/{two_name}") - - # three_menu_eles = two_menu_ele.eles('xpath=ul/li') - # for three_menu_ele in three_menu_eles: - # three_link_ele = three_menu_ele.ele('@tag()=a') - # three_url = three_link_ele.attr('href') - # three_name = three_link_ele.text.replace('/', '-') - # category_urls.append(f"{three_url}#{one_name}/{two_name}/{three_name}") - - return category_urls - - def get_goods_urls(self, category_url: str) -> list[str]: - page = 1 - self.tab.get(f"{category_url}?page={page}") - goods_urls = [] - - while True: - try: - goods_eles = self.tab.eles('xpath=/html/body/div[1]/div[3]/div/section[1]/div/div[1]/div[1]/div[3]/ol/li') - for goods_ele in goods_eles: - goods_link_ele = goods_ele.ele('xpath=a') - goods_urls.append(goods_link_ele.attr('href')) - if len(goods_eles) == 0: - break - except: - break - page += 1 - self.tab.get(f"{category_url}?page={page}") - - return goods_urls - - def get_goods_info(self, url) -> types.GoodsInfo: - def get_image_urls(): - image_urls = [] - - image_eles = tab.eles('xpath=//*[@id="item-gallery-parent"]/li') - for image_ele in image_eles: - image_link_ele = image_ele.ele('xpath=div/img') - image_urls.append(image_link_ele.attr('src')) - - return image_urls - - tab = self.browser.new_tab(url) - tab.set.window.max() - spu = formats.url_to_spu(url) - - try: - brand = '' - try: - brand = tab.ele('xpath=//*[@id="current-tgoods-section"]/div/div[2]/div/div[1]/a[2]', timeout=10).text - except: - pass - - title = tab.ele('@tag()=h1').text - - desc = "" - try: - desc = formats.clean_html(tab.ele('xpath=//*[@id="slide-down-contents-parent"]')) - except: - pass - - try: - price = float(tab.ele('.is-fz28-36f is-fw-b ').text.replace(',', '').replace('¥', '').replace('(税込)', '')) - except: - price = float(tab.ele('.is-fz28-36f is-fw-b is-color-notice').text.replace(',', '').replace('¥', '').replace('(税込)', '')) - old_price = price - - main_images = get_image_urls() - - goods_info = types.GoodsInfo( - title=title, - desc=desc, - brand=brand, - url=url, - spu=spu, - price=price, - old_price=old_price, - ) - - m_data = [] - attr_items = [] - goods_info.attr = 'M' - goods_info.attr_items = ['Color', 'Size'] - goods_info.images = main_images - color_eles = tab.eles('xpath=//*[@id="sku-list-box"]/div') - for color_ele in color_eles: - color_image = color_ele.ele('xpath=div/a').attr('href') - color_name = color_ele.ele('xpath=div/a/span').text - size_eles = color_ele.eles('xpath=ol/li') - for size_ele in size_eles: - size_name = size_ele.ele('xpath=div[1]/text()') - goods_info.p_lists.append(types.GoodsInfo.GoodsInfoP( - attr_items=[color_name, size_name], - price=price, - old_price=old_price, - images=[color_image] - )) - except Exception as e: - try: - tab.close() - except: - pass - raise Exception(e) - try: - tab.close() - except: - pass - return goods_info