★我要吧★

 找回密码
 注册[Register]
帖子
qq空间相册密码查看为什么登陆后需要激活无法注册?

[分享] QQ空间爬取教程

[复制链接]
发表于 2024-5-15 02:00:52 | 显示全部楼层 |阅读模式
selenium模拟登录( X0 D$ V+ ?8 v" K0 W
QQ空间的反爬做的相对较好,而且由于好友权限的原因,我们要先登录后再进行说说等信息的获取, `* S$ }, \( }( R. }* a. u
3 W, r  J0 u; U: s
selenium是获取登录cookies的一大利器,非常方便$ o: I4 T' K; }- b5 o8 A4 _; j1 _

, _: U7 g9 ?* H. J- f) V- ^  N
7 A1 ~. ~1 c6 I* ~* \
2 a8 V* R" w3 J( S在空间的登陆界面可以观察到,登录的窗口与背景窗口是分开的,所以我们需要先切换框架
( m8 l' P: S- L$ f3 j  R: L- X& ^2 K7 j# o; j: J% t# f8 {
切换窗口后定位到账号密码登录元素的位置后点击4 e' Q; g4 K" F. b1 j( x9 b

1 @" @, y/ O" |
( @7 p( I( r- }5 R: f3 N& u
) P. i" z7 Q1 U. v6 H" {使用send_keys函数把账号和密码写入对应位置后定位登录元素后点击,这里使用自带的get_cookies函数获取到cookies,但是这个cookies需要过滤一下,具体操作看以下代码
/ K; Z# g4 Z! m0 A( z
+ P' a/ q$ R5 @" j1 L8 k+ x代码为类的部分节选,完整代码在最后,未声明的变量皆为类的成员变量
& O" X! w+ O5 r3 s9 c: ]2 s& G
1 Z7 O- B( E( m( t% s8 E0 \: P. xde login_func(self,z):
8 X3 o& D* X: O0 @) W browser = webdriver.Chrome()
  _! V! N# E6 u- K* |8 i browser.maximize_window()4 v% w  Q. U5 F% x: L9 P8 h& ]
browser.get(self.login_url)
# r! E% J7 J3 f/ `! |8 R# f time.sleep(1.2)' z" H& {, [/ x+ q+ H4 }
browser.switch_to.frame('login_frame')
3 l; ~, f' E4 t( o4 }& h browser.find_element_by_id('switcher_plogin').click()2 t8 F0 y" B: Y8 E/ `( H. g( M
time.sleep(1)
( N0 ?# z8 `7 M; Z browser.find_element_by_id('u').send_keys(self.number)" F. f# X+ i0 M$ H
browser.find_element_by_id('p').send_keys(self.password)
5 ~9 U, w' F/ f1 a time.sleep(1)
. E) p$ P: i) d( g9 _4 l+ I5 E browser.find_element_by_id('login_button').click()
) j6 u1 I3 a1 b. J. M time.sleep(1)& v2 M  c: a8 K1 T6 `: a2 m$ Y
cookies_list = browser.get_cookies()
3 b- y" ?' l) ?# ~( j  i. c- a
$ f5 }# G; L# f4 C for cookie in cookies_list:
) m, W* c( ]7 z. \. c: U1 K if 'name' in cookie and 'value' in cookie:! }) Z% n, A+ C
self.cookies[cookie['name']] = cookie['value']& ^& Z6 o( g& J
# print(self.cookies), u2 i6 v5 _0 X& f! _% k! \% l1 w
with open('cookie_dict_{}.txt'.format(z),'w') as f: # 这里是为了一次性多刷几次cookies建立一个cookies池,便于加快爬虫速度,后面再提
9 Q& F* p1 i: R; O7 s2 }- Y% j json.dump(self.cookies,f)
! J: F/ [) J& r* f6 ^4 b# browser.close()
) E/ y3 J; F) e) l; G- L0 c. q
1# E  |. }# V" h( B. K  K( U% T
2$ J6 h# r' h) I  ^  I8 A- y
3
" E+ v1 E2 ?( p/ t4
/ d! ], N% Z1 M, L7 K  z8 S5
* n; o( g" J- }+ u- V6
( u8 X7 B4 X+ w3 T  N/ R7
3 h/ ?: w2 [# |88 [" d& U, Y; r$ S$ Q
9
: R8 n. W# b4 _. U10) U  |" Y( e: c( @+ m3 J1 K
11
/ p( S& M) R1 j) |12: M2 }, h$ g8 T4 b
13
- R( r* F1 L2 B, R  [! ?
" i4 `5 D, K  k6 f2 U14 153 A" a: r0 y# p. ^
( X, C: l% n: I/ V2 G" v1 T
16 17" A8 ^6 K; _. v5 `& {
18; \/ k5 v( z  [  z9 K! k
19
6 X: F7 }, \* [8 ?20& u3 H1 r' j7 W7 O
21$ @2 B  f  d5 y( X
22
3 e. _  U3 ^( Z  e" D2 M" c说说内容获取3 H% ~3 f3 o7 B$ I
在打开开发者工具后,在众多XHR对象中发现emotion_cgi......里面的msglist即是说说的内容: J; V6 L3 j4 f' V

0 t8 A& S) \) O& x$ q1 S
5 v/ \* b4 V* }7 ]" i7 w/ S7 P$ ~( _/ L" A" S' Y" S' V

8 l. X$ l) X' D5 O! }) k) L: N( [! Y# K3 m3 y6 c
这里的msglist是个列表,里面有0-20条不等的说说,可能跟空间发的说说的形式问题相关,至多不超过20条/ b; H: c( O, A' F) Q: [7 E! p
- r: v7 L" S5 c3 y. c* \
稍微猜测一下这里的参数的含义,一眼明了的我就不说了,我不清楚的也没有肆意揣度
+ H) }2 U& g" |) C
$ x6 H1 N" x( A, Bcmtnum 转发数
7 Y% s. [- l7 C
5 {' @9 x3 B% T2 U& Ncommentlist 评论列表,里面是每条说说4 V* U5 i) Y* v% `1 l# l. U' y

) ?& W& m* w1 r$ \的内容conlist 内容的一个列表,里面有两个参数,一个是内容一个不知道有啥作用,取内容的话直接取下面的内容也是一样的( A6 P' W9 K6 n1 j4 n
, [/ d$ t- S8 r5 C3 A/ F
created_time 说说发表的时间戳7 A/ [; r7 w+ P

* u* D6 l6 b7 F1 _6 F* _2 B8 Q. MisEditable 是否编辑过
, B+ r7 ^; q. f0 ?  H9 {6 _6 O. g) ^/ f7 }- C: V
lbs 位置信息
: P  _3 s4 y# f* c, r# z6 a" O$ Q6 j9 c- F+ P
name 你给的备注,没备注就是昵称
4 h& I! {9 C9 R
4 U0 _, H. ~! I# P/ lpic 如果发的说说有图片则在这个键下面,但是如果没有图片则没有这个键4 |" ^1 K0 r6 `7 U2 r$ ]- ]
) `# X- I$ A5 [- p  W* H/ {
pictotal 图片数量,没有图片则没有这个键
/ e  E& r% d! s  [( c# x5 y& j' X5 K" ?# I
rt_sum 猜测是转发数量5 B; d3 E: a3 z  H: a' M! Z
: q+ B5 M( a8 N( i5 A
source_appid 说说来自的app标识9 l  q6 z; ~" p! X- W6 ]9 r/ e: ~7 G

, Y5 V7 V4 n5 V, p! v9 P8 usource_name 说说来自的设备名称5 y! I, B/ B0 ]* A4 ^

5 L3 n" x/ u2 Q9 Tsource_url 说说来自的网址: i/ `. u/ h  r9 l# |1 _
$ w1 z' z! V# A
tid这个是每个说说独一无二的标识,可能是根据某些变量使用特定的算法得出的,直接使用即可" N1 m8 ]3 C4 ~* W# O5 c1 g
' n5 L& v5 Y+ L  w* u  q% F
uin 该说说的作者QQ
, O; |) W# F  I2 n
3 U& s5 `' [, {  B+ W当然如果是转发的说说,这里还会多别的一些键值,我这里未对转发说说进行处理,只是单纯地取出该QQ转发时发送的内容,有兴趣的朋友可以加以改进
7 x7 l: ^9 m  ~  M$ |, b0 a6 i9 s  G/ {
- C! x( u4 j( i6 T& f. z( |下面我们看一下这个内容的获取网址构成* ?  Z, x9 |8 K5 F

4 _9 r8 r+ p! l. g- S! E: Q# R在Headers选项中可以看网址的构成参数7 r: }% [4 ?! b9 p. [
0 w  ]! q5 y! D  }, s
经过尝试发现,uin后面对应目标QQ号,sort可能对应排序方式,我采取的默认值0,pos这是个关键参数,其改变决定了返回数据的范围,num是返回的说说数量,我选用的是默认值,不知道增大会有什么变化,读者可以尝试
" E; C/ M1 P$ G# o& t7 f) `0 S' t3 J$ Z; c" Z
最后一个关键参数是g_tk,这是个加密参数,有了这个才能正确登录: Q( f8 L( D8 \$ m$ E. l) H

* m! [5 |* t  i3 N! D- e
* L# R. v9 c: V. R) j) e& d4 N! ^3 p2 @, \/ V5 P
破解g_tk7 x* L% u/ Z; ~/ ]5 n* w6 Z
网上的搜索发现是js,破解的方法见下图2 Z0 V$ ]+ t1 A5 A
9 k7 `- {! `9 c. b" _& e7 V5 ?0 h9 S
随意点开一个人的空间,进行如下操作- m& s, h/ A5 L1 S7 M# c

$ ^% n  p6 O( N5 q% x8 V( T0 D; R

; [% O4 ^- p% ^6 t3 C搜索g_tk=后面的关键词
' h3 t  {3 o+ v3 k2 s
8 q  Z" H0 J9 Y3 ?" @0 |/ Y0 L1 j4 q  L( W
# c! z) h& r8 O
找到对应的函数,这里的函数读一下之后将其转成对应的python语言即可
0 s$ F9 J) N" O5 S# `7 d9 x% s; P2 d4 G
def get_g_tk(self):8 S$ C9 q3 t2 i
p_skey = self.cookies['p_skey']: Q$ \8 U+ _' v, ~3 ]
t = 5381
) r7 \% k5 G/ C" C) @ for i in p_skey:' h* N- ~" F5 I
t += (t<<5) + ord(i)
7 T; k: `0 f2 Y: V" M; }" R4 l, p return t & 2147483647
8 `% b/ S" _6 p4 V' y1: g/ C7 J& ]8 ~$ B+ R: x$ g
2
( B6 ^, b1 T6 M3 N1 C- Q, C3
3 s) ~5 g- w- h* s! T* R4
" n3 D! p  N9 g9 }, m/ R; z- q5
9 [3 D* @& J2 a' U. |# [. Q9 k6& f, `0 z5 V- Z. [
说说的评论获取; R" C) A5 b0 b7 o- Y' [
这里没什么好说的,数据返回是跟说说一起的,在commentlist的键里面,里面的键值对和外面的类似,这里就不赘述了,值得一提的是,外面的cmtnum返回的评论数是指单独的回复数量,也就是跟楼的评论数量不被统计,跟楼的评论在每条父评论的里面,对应键list_3- Z" H* j; A/ m% ~
! e) Q6 P4 E- P
- e5 _3 J: m' ^( e4 Y9 D6 `

; Z) u' ?7 N0 u9 E( u# S' |说说的点赞人获取& h, D0 X  d/ V, \
8 U8 x; R9 Z! R. B
8 P: L0 P- ^: X6 [. @0 g
框内可以点击,点击后
; R0 N- ]4 O* U9 }) ?  O  c
0 w% e: l# `/ n: x8 L& e8 m1 b( I  L, U% P% w# w( \* ~
出现
. [6 q7 \) _+ h9 h( ?! V同时右边出现一个" P4 W2 r* N, q' G* x

/ [7 }( b/ {# p; |2 {2 j# U$ a5 x

+ V  ~4 n- Q5 T6 U: k1 s) \这里对应的内容为/ `/ J; d  S( |( D! Q5 T% O; B
; F' k1 s+ X% ^. t
is_dolike 我是否点赞了- z* k' }; i# B5 `' ~% ~; {5 W( ~( [
* f: l  O* A' o! V
like_uin_info 点赞这条说说的朋友的信息(除我以外
4 C' {, s1 L8 V6 M3 c$ _( a
9 c& N. g. x% }. W# u# Qtotal_number 总共的点赞数量' M" _* y$ q& r9 `& A

: {7 y( n8 S* i$ a' W: H每位点赞好友里面还有一些信息,我这里就没有赘述,那些键值都看得懂' I( m) l! K: h, y) _
3 s9 c* b' v' d  j4 A1 C
url参数构成4 F( y, D: Q- J5 b$ d/ e8 v
那么还需要知道的就是url的构成,老方法,先看headers/ ~& l! k5 p: M& k/ C1 Q. G4 n( C

. m7 S6 @% h# U. ?& d) {) B: h( }! R6 V) V

' ]/ n) A* S" k% |" o  S那tid在哪里呢
2 s' n7 p7 k4 C% _7 u
7 n! G7 r2 z0 Q; K之前的msglist里每条说说底下对应都存在一条tid,这里就是它的用武之地了!! a) Q+ _% K! O4 A8 w

% j' w- ~" K$ Z) l4 u, g# ]好友列表获取" d9 F0 E0 y" N4 o% b. a
我在网上看到过很多个版本
& x; V/ e0 I( D, l+ m
3 N& ]( }- y  t我自己也都尝试了一下,以下的版本获取到的好友信息与QQ好友是最一致的2 s' m8 W: l# A+ |0 J4 e( J! R; \
1 _' i! }: z+ e1 p
进入自己的空间后在设置中点权限设置: z+ s  `+ f* |. T1 v# ~

' i: r0 R$ p+ P: I/ n9 S( n
3 [& M& c$ T6 A8 v
! Q/ M; E  ?& Z  j( }1 B: V: _" B- S1 B! ~

0 R2 k& K! S3 J: n找到对应的项,friendlist里面即是,但是只有50条,如果你点开了xxx个QQ好友并向下滚动后查看url构成% F9 w/ @7 q  S' Y+ p9 Y
. {9 n3 F! f; u+ b/ i8 A. g; [
就会发现4 A5 r% @: ~, d$ @
$ ?( u0 z2 o) G& d6 s

2 p4 ]; t4 ]3 b8 w9 |, n+ W- a3 }$ |
offset偏移量用来查看更多的好友
! C6 C7 N& X* Y. v
+ e: ^9 c' P8 b4 e/ Y# K,如果是最后一页,返回的字典中的键end的值为1% B. E- y8 B, b" ~' _! r. ?- |" `
2 @& i8 k9 y1 y. n4 W1 j" L
数据库的存储" h: s5 z: X( O; o
由于对数据库的使用不是十分熟练,这里单纯只是为了存一下,有很多弊端,例如图片的存储# L) M2 Z# ^( `/ c* E, ^7 n

6 o( o  W, Q0 I) P4 u而且用的很丑陋,这段代码可以忽略1 f( J+ _" \# Z6 B; _% Z/ R
( G' C+ G, ^! o- o6 L* l0 ^
def check_exist(self,uid):, [" o! P1 O( i. W: P7 s
cursor = self.conn.cursor(). x+ s/ U3 D0 a* T$ A7 e1 y
cursor.execute(“show databases”)( T0 c4 U6 H8 x' S  N7 Q: v; ]4 g
content = [i[0] for i in cursor.fetchall()]
7 V% [3 J' Q# j+ Y; d if uid not in content:8 d- U/ q6 e. M" N2 `# z
cursor.execute('create database '{}';'.format(uid))
7 ^2 |, U( @$ |0 p; q: v+ ] cursor.execute('use '{}';'.format(uid))) E; ^; T+ ^- M1 z
msg = '''  b* w0 y+ W3 U% u
创建表 msg
& h0 j7 Y: e& ]4 \- B2 u$ D1 \$ ]& l& Y% v! Z
id text,) x; e" u; `+ Y4 }
name char(100),
3 O7 J: R0 r1 w: r% [& X$ l content TEXT,
2 A4 R9 {* E$ G3 I9 l7 Z, [ createtime timestamp,
' j, o! V  d9 m! V- V) ~! R: S; g tid char(32),
  R# |+ _$ Q6 `, N2 x! t0 @" r location char(32),
5 T; k$ [4 F/ k# }( @5 f posx int(20),! f1 K0 p* b, }3 @% J% o3 z
posy int(20),
; `3 }8 F$ A! G6 n+ O7 V4 P6 g& D- A# g comment_num int(11),
8 o1 d5 i8 E# K like_num int(11),5 D4 I/ s- l3 l- u, x
pic_url TEXT,# e: T$ }6 G( V) G4 ]! B
pic_num int,- C! D+ u9 i9 x3 a% i
source_appidchar(32),
3 m! ?8 ?8 p! e( ` source_name char(32),
# t: X' X4 t! N, H1 d is_tran char,, c# ^. j( `8 l! ?( h
trans_num char(32),
# k! L' b: D0 J7 m5 {$ R' J* I& h trans_content TEXT, B# E! |5 }3 ]- Z6 K: t4 R: n" ?
);
, P. E1 A& A; e+ I '''
1 ~' |- ~) B' y5 { cursor.execute(msg)
/ G. h( c% [4 d! I* y, I* q2 P cmt = '''
% ~3 J8 y" B- v8 x create table comment
% |6 n- [3 N' i/ u/ D1 i$ Z, ~! `- l# F: o% j9 F
tid char(32)," e$ j4 |) A) g. r, _" L9 W0 s
id text,
1 w5 Q3 W7 z9 v' q3 E' p6 t name char(100),/ |- I( ?0 T! w9 l0 r& q1 A4 t. j7 {
content TEXT,, T' x% ^% D+ C: E0 u1 N2 I; t
createtime timestamp,
( K! s3 Y: H; n3 z% L0 v2 i reply TEXT# y2 @1 l6 c' e1 J: h: d/ R
1 l1 u, `" |+ [" A8 Y$ W
'''8 L% g5 I; S) b$ y3 ?9 l! i
cursor.execute(cmt)! ?, j, Z. o2 b7 Y9 w
like_table='''
- r1 ?, E& x4 U2 C* M create table like_table& ~& V; ~" A( |: T

0 o! c% @1 ?0 d3 O9 K tid char(32),2 ~2 u' r2 v! X, D' k, }. z4 j
id text,
+ s% L& u' G  Q6 d3 L; s7 T- G; j name char(100),
, l5 x) ~3 s4 B; q5 k# p1 C3 i) L addr char(32),
! U& _5 C+ Z- O. {# v constellation char(32)、0 R) i& M3 n5 ?5 B3 C5 K
gender char(4)、/ v. \! B- P) {2 z
if_qq_friend int(1)、
: K+ V9 [, @5 ?1 }9 Oif_special_care int(1)、
6 Y3 I$ n& i- g3 Z. X6 Yis_special_vip int(1)、
4 K: C+ Y) h+ wportrait TEXT
- b+ `. g9 S9 Q
' e7 S1 e' N. v  p '''/ T2 Z) m' W7 [6 d' Z1 {' C, z3 y' I2 v
cursor.execute(like_table)3 d* R1 V. B8 i  q
self.conn.commit()+ x' k: I& G8 \  z
return 1
# ~& D2 @, J- n( f1 X9 J else:
: @, W, t2 W, @2 q return 0" a8 l0 y( i! ]$ N. M8 q
1 H" p& u' D5 H: h" M1 L& N
————————————————
; y9 O% u. N4 H
发表于 2024-10-9 11:21:01 来自手机 | 显示全部楼层
大佬可以帮我看下嘛,有偿
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

QQ|手机版|小黑屋|☆我要吧☆ ( 豫ICP备13016831号-1 )

GMT+8, 2025-4-11 01:36 , Processed in 0.403672 second(s), 19 queries .

Powered by abc369 X3.4

© 2001-2023 abc369.

快速回复 返回顶部 返回列表