★我要吧★

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

[分享] QQ空间爬取教程

[复制链接]
发表于 2024-5-15 02:00:52 | 显示全部楼层 |阅读模式
selenium模拟登录
. z; C7 o" d( z# b% SQQ空间的反爬做的相对较好,而且由于好友权限的原因,我们要先登录后再进行说说等信息的获取
' n1 ?% r& l7 M' F7 Y% _# W  t, J$ v
selenium是获取登录cookies的一大利器,非常方便8 ~2 T- C8 k* u+ Q. _" q: x

, _; Q  M7 O. Z3 w( j* ~' S! o
9 x4 b" o) A2 A! a3 B& ]1 ?9 h0 @7 P( m7 I- b
在空间的登陆界面可以观察到,登录的窗口与背景窗口是分开的,所以我们需要先切换框架
) Y9 {. m. ^+ c4 o7 b8 a$ j
  N0 h4 v* |  u8 t7 s切换窗口后定位到账号密码登录元素的位置后点击7 k% u* u0 S4 F7 P' W

3 Y; n/ H  Y3 G' H& s
+ C9 e/ E  f- s" b4 z/ O- v7 I8 v0 r3 C  D
使用send_keys函数把账号和密码写入对应位置后定位登录元素后点击,这里使用自带的get_cookies函数获取到cookies,但是这个cookies需要过滤一下,具体操作看以下代码# B/ A6 C& P/ q/ Z
% ^% X$ c( w- b3 z! z
代码为类的部分节选,完整代码在最后,未声明的变量皆为类的成员变量+ _3 O+ b9 {# B9 a" n
7 c! y; }0 r$ l9 D
de login_func(self,z):
! ], T0 E$ i& d% N browser = webdriver.Chrome()
2 h; J# \( q) U& C browser.maximize_window()
  F- q' B$ }. T( J& R; Y- Z browser.get(self.login_url)
% o2 w, @+ y' Z- |" H  C) I9 g time.sleep(1.2)  z3 v: r0 l( U) S' Y( z* F4 P
browser.switch_to.frame('login_frame'). V) }3 P- }9 y2 H& C# H! f. S
browser.find_element_by_id('switcher_plogin').click()
" Z# s: [9 I# \! h time.sleep(1)
% A) [' Q; \0 }$ D. N& S* E; ` browser.find_element_by_id('u').send_keys(self.number)
) J) Q0 a" }% C3 z, j browser.find_element_by_id('p').send_keys(self.password)* k# r  ~4 f) l
time.sleep(1); q- F# ~+ S* D; o  i# \& f
browser.find_element_by_id('login_button').click()% ~) S! ?7 Q$ z
time.sleep(1)4 e, b# p: A2 \0 s. e! `5 r
cookies_list = browser.get_cookies()9 v+ o& `; u, v# E# x/ W) H* ~9 J2 h
  Z" T: N# v4 H
for cookie in cookies_list:
. G9 {9 U$ ]* k3 U if 'name' in cookie and 'value' in cookie:- ~* j0 c0 C, M# W" O
self.cookies[cookie['name']] = cookie['value']
( B) I) N0 P6 f7 }4 [ # print(self.cookies)
0 I0 |7 D1 e2 E# C( l* y5 s with open('cookie_dict_{}.txt'.format(z),'w') as f: # 这里是为了一次性多刷几次cookies建立一个cookies池,便于加快爬虫速度,后面再提
$ C; h$ x# y7 ~5 C# l  W0 l- {5 r json.dump(self.cookies,f)1 n3 Y' t+ S, ~
# browser.close(). u4 b% Z4 l1 \( v  h. `/ B
6 l& V# o0 w2 ~# `( P
1
1 U: w! `6 c1 H% R# P9 j8 ^( v2
7 r! {4 U* g' X0 l* G) S3
0 o% F' d  p6 I' c5 u4, u% \# h) h! ~0 n
5
3 n, }6 O4 w$ t: T2 A65 ]& T8 I4 `# j! L9 R& O6 A. k
7
2 X- R* \- p$ o* s8
$ Q! v; h2 U  i  S1 D! w) _% \& q# s5 I9  F0 B% I; f0 F& ^  u5 [
10+ u, ]% c2 ~0 `  |  o# s* V
11% n$ ^' j- v  K5 t0 q0 v- [. m  {& ?$ l
12' C# {- q+ K: W: D' n& P$ ~# o
13- g3 V: B, U  W; _- k( j

! ^, R" E, U$ [, j* G3 b14 15
0 h) o/ f4 L( N0 H" ]3 |8 \: K& k2 |
16 17
$ I; P, Z% N: N( z0 W+ Y18, f- N, @/ A, |5 J- _- z3 H2 T: O
19
4 R- A2 E" E' [6 P4 _20+ p" o7 D9 o- Q, T. d" H
21
" Y2 }! ]5 Z6 T0 o2 B22
: v8 h/ e7 `, R3 ~$ _! {说说内容获取
5 K. g* \( Z: W) j在打开开发者工具后,在众多XHR对象中发现emotion_cgi......里面的msglist即是说说的内容
3 B$ D) z% p8 R8 o1 f, h# k- ~! T% M

/ r- q2 b- ~6 G8 o/ Q& }' ]' q  Q7 q6 |8 Z
& s' g3 e/ }$ o% W8 R/ u8 h

  ^. d3 r/ N$ E2 l这里的msglist是个列表,里面有0-20条不等的说说,可能跟空间发的说说的形式问题相关,至多不超过20条
" J/ B; Z: V" |  N( E4 B# s* t0 k- o6 o) j
稍微猜测一下这里的参数的含义,一眼明了的我就不说了,我不清楚的也没有肆意揣度
$ Y! B* y; b3 ?) {: c
9 P/ u3 `/ \" x1 {$ R4 Dcmtnum 转发数) p' e5 E" c3 N  ]% r. \! n8 G

" ^$ }  k: t1 a4 z8 a% \commentlist 评论列表,里面是每条说说
8 @) I: O3 D0 [& J" L2 Z. y. L) ?. N" t/ k2 f7 T* @# X2 a4 M' H
的内容conlist 内容的一个列表,里面有两个参数,一个是内容一个不知道有啥作用,取内容的话直接取下面的内容也是一样的1 L4 f# Y. E1 c5 c

0 A  ]: ]7 p' P# @# Acreated_time 说说发表的时间戳+ [: w- L6 W! h% Y1 f

( d: ]; W& t: KisEditable 是否编辑过. g6 a; _+ {1 B* M7 J- k1 K% ?

& \! O+ X7 n; Z: {+ rlbs 位置信息
; D+ X0 q& t( E2 W: [4 I; C) R) N! h; I
name 你给的备注,没备注就是昵称
. C& `5 v' H( H
4 P' ?' K- c  Z9 B# ^6 u+ Gpic 如果发的说说有图片则在这个键下面,但是如果没有图片则没有这个键4 B9 ~* \  T- D% ?+ ~
+ ?( m; e* z) n3 N# q
pictotal 图片数量,没有图片则没有这个键# A+ a; M5 Q3 t' g- [
8 g) j0 X( i' B5 Q/ Q/ o- ~( U8 ]
rt_sum 猜测是转发数量: z! h, {* c3 L- O
- n$ g# F& V, i
source_appid 说说来自的app标识8 J  v$ {8 K' F) l! a4 }& E
5 k. n- O# Q( L8 l% ~# V: {" U
source_name 说说来自的设备名称
" J! k9 i+ r5 H
, M* f7 I5 N! r7 ], {2 lsource_url 说说来自的网址7 ~2 W/ r4 s8 A2 b0 Z( r
/ d) O$ O, E$ u& w6 T: @
tid这个是每个说说独一无二的标识,可能是根据某些变量使用特定的算法得出的,直接使用即可: }  g1 `5 E( F4 R$ {
  F: b# ^2 k4 J2 A; L4 ~, b
uin 该说说的作者QQ8 F- R& E0 E4 s* K9 {6 c

. k5 Z) q- K0 N当然如果是转发的说说,这里还会多别的一些键值,我这里未对转发说说进行处理,只是单纯地取出该QQ转发时发送的内容,有兴趣的朋友可以加以改进: l' ~7 y; ?0 O

, v( i  P- s  j% m' r) Z" O* d# M下面我们看一下这个内容的获取网址构成
, u/ j4 ]! m! @8 R- b4 j5 ^" ^% K, }* t( G+ x3 h
在Headers选项中可以看网址的构成参数
2 J0 K% ~9 Z4 K7 N
1 F# V" |2 T9 F( ]经过尝试发现,uin后面对应目标QQ号,sort可能对应排序方式,我采取的默认值0,pos这是个关键参数,其改变决定了返回数据的范围,num是返回的说说数量,我选用的是默认值,不知道增大会有什么变化,读者可以尝试
9 o0 X& J6 J. b+ J* w( G$ P$ _" A' `, @
最后一个关键参数是g_tk,这是个加密参数,有了这个才能正确登录4 N9 H! q, ]8 J: |  E

" K/ n+ s+ k- z7 h5 @8 h. L+ _0 T/ x0 F4 R) M

5 D! w8 d* Z; N  j. ?$ o破解g_tk
# o( B( Y) x* g1 C2 t2 i# h网上的搜索发现是js,破解的方法见下图9 N: G6 ~5 c2 z. v, y
7 F! c9 }% R3 {; l! U
随意点开一个人的空间,进行如下操作
0 z2 X9 V8 Z5 {9 ?* `
+ f3 Y* l+ v/ n! h3 O6 L) f( O4 u- `+ U  e' y% l1 w

  D+ n% M& P. [2 _搜索g_tk=后面的关键词7 \. r9 f0 y. X

2 O1 ?* J4 F& _. n: b' O2 v
0 v) V1 j, T! `/ w+ g6 [) \! k/ y" y2 e! t6 K$ o
找到对应的函数,这里的函数读一下之后将其转成对应的python语言即可$ F6 K2 P) P# J  X
3 V7 N; m6 @$ o! A
def get_g_tk(self):
" J8 @  l: a; g; A% @ p_skey = self.cookies['p_skey']5 S2 G( F1 E! t. w, _$ m
t = 5381  `" c  P( K6 X  d* R, w7 }
for i in p_skey:$ Y; h. s( x% O& b3 E" m
t += (t<<5) + ord(i)% O6 s+ j( @2 n! Z: S, U( h% _2 ?
return t & 2147483647, S' @' y; r+ }' h3 w' w
1) ]) Z$ G* R: F2 i. S1 }- p8 B$ d7 Y4 ^
2( t% ?3 t& q6 Y% r1 z0 h
3$ d4 U; k5 Z5 C9 p- k2 Q
42 ~3 F& \2 t0 B1 j) S9 P; w
5
2 g/ w- T" m/ V. `2 o( |1 \1 @7 \+ s6
: m' t% P9 g7 W  U4 B4 c  k说说的评论获取5 F" s) ^" S6 N. v8 p
这里没什么好说的,数据返回是跟说说一起的,在commentlist的键里面,里面的键值对和外面的类似,这里就不赘述了,值得一提的是,外面的cmtnum返回的评论数是指单独的回复数量,也就是跟楼的评论数量不被统计,跟楼的评论在每条父评论的里面,对应键list_3
$ [( [6 w/ H- h. o9 B" y3 ]( u3 W" c% _% j: E5 G' b
  N. |4 S0 S8 O+ s, R/ k% v, |; x5 V

" ^" h2 K; e0 g+ ]说说的点赞人获取. X/ F5 R! D* C8 z0 P0 E

* G& g/ ~. `4 U. U+ w6 [* u5 z- K  T& Z& m% C4 M
框内可以点击,点击后
2 D4 q) E; X: _# ^2 U4 f. L! a8 Z& n1 B+ T1 \4 R) O

+ r( r( r* O$ q, \+ p4 {  n出现. ^+ b2 v8 u( ~- d
同时右边出现一个! `% I0 m7 G4 j  [' s$ W4 W

" |* J! _9 J0 |; B0 L$ c) y/ o# \& S+ V9 ]! M. z
8 h( i$ Z% }' }  K6 D
这里对应的内容为% ~3 u' U; K* M8 C8 t. \) m

/ q8 B) k- m/ c) E6 pis_dolike 我是否点赞了
! D3 z4 t, i* O6 d  H2 L3 q0 G
+ Z$ ?3 j! E1 g0 h# {like_uin_info 点赞这条说说的朋友的信息(除我以外
6 n9 x, j2 x( \; \$ D7 `; i
4 w4 @7 {9 M5 D' M, Y' ^total_number 总共的点赞数量6 u( g& s2 |1 N4 K$ x! P) v

/ e7 l/ K$ R8 c" e. @6 T每位点赞好友里面还有一些信息,我这里就没有赘述,那些键值都看得懂7 }. v- ^2 F; j

6 A1 F3 z& s4 u5 K, n6 X$ Y7 ?url参数构成4 f- ]+ m- ]. F3 Y
那么还需要知道的就是url的构成,老方法,先看headers
6 x' I2 j" e( \
7 @* m3 e4 ~8 g/ Z: K" ^* G5 M# E  F$ r! s
3 ]1 W7 n! f. r: Y
那tid在哪里呢3 W% ]% P; k7 t& F

- B+ s% F. I4 u# H8 N, H之前的msglist里每条说说底下对应都存在一条tid,这里就是它的用武之地了!
! S8 }, |# T# c6 ?0 F1 r5 f6 A( I0 |7 ^  k0 r" U- C* u" V9 v  s6 \
好友列表获取
% L/ R! L3 t! `9 m我在网上看到过很多个版本
, n+ x$ V8 Q+ Q' m+ t
4 l, g; |; p* E. V/ T我自己也都尝试了一下,以下的版本获取到的好友信息与QQ好友是最一致的8 L; m5 Q3 \2 Q. F* _8 [' |" ?0 x* c
' N# {: \0 u( s/ e
进入自己的空间后在设置中点权限设置
( ~- r+ j, [0 \% r! O7 N$ d9 c+ r4 g! e: E9 j. S+ ^
+ R3 K7 Q  |( w$ A/ e* m/ R" D

. N" Z. r1 R5 A( c3 K* v$ x# n& F& r" Q
( G  n+ D/ B( ^! P, T
找到对应的项,friendlist里面即是,但是只有50条,如果你点开了xxx个QQ好友并向下滚动后查看url构成
% L5 e; k% o( j, g% F* F* m
4 K0 E. Z7 p: [" V4 C% J- J# e# u4 p$ d就会发现
. i, |8 Y- C1 }) G! W; x" O5 D0 w  b% _" y9 k/ e. e8 w
0 ]$ k' r5 {8 H- x0 r2 z' J( S
8 j2 J( |, q% W0 H) ~8 G
offset偏移量用来查看更多的好友
+ v( I8 V7 j. v' J+ r
' K8 k$ ^+ l; u,如果是最后一页,返回的字典中的键end的值为1
% C2 l) A- s. h: V  B0 G  f
3 ^$ Z( x% }* s8 ?数据库的存储
) u4 Q) f* E$ L: z, k7 I由于对数据库的使用不是十分熟练,这里单纯只是为了存一下,有很多弊端,例如图片的存储
+ U9 E' X4 c; }5 `& R$ j: ]% D
1 W0 }0 C' y9 ~而且用的很丑陋,这段代码可以忽略
6 o$ @9 M, h/ l) [5 I8 h/ v1 e( E: {0 A, Y
def check_exist(self,uid):- A  s1 D+ B& R6 @& E
cursor = self.conn.cursor()4 Q7 K' o2 G% E. ]8 B( r0 S# I4 |
cursor.execute(“show databases”)
  ^; [9 h; L. C* A* U; H8 X7 \ content = [i[0] for i in cursor.fetchall()]5 j8 a( B9 D8 Y/ J2 w' i; ^
if uid not in content:
- j, t+ ^5 t2 ^9 P: Q cursor.execute('create database '{}';'.format(uid))1 U4 ^% s0 m+ L' d3 w. u, K
cursor.execute('use '{}';'.format(uid))" R% e3 p! c2 I: s7 x2 @+ M
msg = '''
( r- p! e4 `4 w% C- a) A 创建表 msg$ [# ]: K$ J! [
7 j5 p+ w% k3 G% @4 X
id text,
% t' W4 \* Z# ^) x' k# \- R name char(100),+ \" L# C& [1 u% e. X3 K) ~
content TEXT,$ [" I/ |0 S2 I1 l( w
createtime timestamp,
1 e' h) I; n$ g, V. ^ tid char(32),- e0 B( ^! @8 V$ n3 t2 }8 @
location char(32),9 h% }1 x( ]' x5 i" C, j+ Q9 X3 u
posx int(20),3 @+ }- j) F: t5 I; }( B9 e2 k( U3 y
posy int(20),
. A1 m# W* ]! |$ R2 t! x" ?" d comment_num int(11),% b% {9 U4 J8 G& \9 H) D) P
like_num int(11),& T5 E5 V- {; C3 @) ]- U# X
pic_url TEXT,1 P7 a! ?/ K- Q5 n, C* W5 ]* @
pic_num int,% E. |* \3 F0 g, ^0 {# H( H
source_appidchar(32),1 d6 a0 B3 N& J& H
source_name char(32),5 ]8 @) u5 {6 J9 n  {
is_tran char,+ I% V1 Q3 f% L2 {! r
trans_num char(32),
1 p" Y; `( S+ x% C5 W& U; D trans_content TEXT# _  [8 Z) s- k
);) K2 h7 y" o' S6 l+ L9 T$ |
'''
) H; L4 f# Z) _( z cursor.execute(msg)
3 f' V0 {  D$ s0 [) E cmt = '''
# A8 _. h$ i, [1 I create table comment
: S' t5 d. k: L/ y
) e. x/ x& `8 f) c) l tid char(32),
4 c) v- v) f5 H, H5 D: | id text,
: h9 ~: s: y! {5 h7 A, S name char(100),
7 L& H8 c/ P2 ?/ k content TEXT,! [* `. x% |+ |1 e
createtime timestamp,
; M* C' p1 c( u9 b reply TEXT
/ L; }# l4 e! }5 Z; Y. b# Z
7 s$ l8 O4 z: c  @# j '''
4 g# U$ [& Z6 e1 X cursor.execute(cmt), G: `0 f6 Q/ L; H0 v( ?
like_table='''
7 |$ v" c6 p0 G# Q$ l( v0 W0 |: | create table like_table
1 b1 f7 o; K% J. U
) o! p- v8 x5 d' c tid char(32),
7 l! s* f6 N. V8 Q id text,
, C" R4 v8 F+ {7 }' M name char(100),% z: ?& C2 n& \* o: _
addr char(32),) @. H: {& s2 `5 X0 C# {, N
constellation char(32)、% m/ s9 x. \' `0 @( V+ O
gender char(4)、9 f7 {+ E( B+ I# [, z
if_qq_friend int(1)、1 u+ }* T, q& P) o& s# G* B* }
if_special_care int(1)、, K, j; t" S2 z- s, d
is_special_vip int(1)、" l0 t- h* W; `1 s; w+ \3 h
portrait TEXT
6 |2 F( S" Q1 b7 f" E
. A! R  e/ H1 Q2 F0 D '''
8 W4 |. n) j- S% M cursor.execute(like_table)
4 O# S/ o- ]) G' F3 _ self.conn.commit()
5 d1 ?# G9 J/ e: l. G. l return 1
) P! v9 D; t* c- I else:' m) _1 C2 X6 h
return 0
0 n* Q* S0 y- `  ~! \: x. n( ^/ N4 G  T2 m5 M$ ~
————————————————
& w3 s. `3 u5 n1 r3 l$ @+ f  t1 P9 u
发表于 2024-10-9 11:21:01 来自手机 | 显示全部楼层
大佬可以帮我看下嘛,有偿
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-20 00:21 , Processed in 0.113759 second(s), 18 queries .

Powered by abc369 X3.4

© 2001-2023 abc369.

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