Contents

抓包分析cookie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SUV=009541197BAEB0865AE4275C40671974; 
CXID=85CFAE0BE2B060BC90434EEB68C2503F;
SUID=86B0AE7B3665860A5AE4319C000790BC;
IPLOC=CN1408;
wuid=AAHOprp8IQAAAAqLE2MNMAgAGwY=;
ad=DpJwbyllll2ziRptlllllVHIR1klllllWffZPkllllwlllllxTBHqs@@@@@@@@@@;
ABTEST=0|1534215316|v17;
browerV=3;
osV=1;
sst0=116;
taspeed=taspeedexist;
pgv_pvi=8960340992;
pgv_si=s680434688;
sct=7;
PHPSESSID=k8tr4ct0qsk44j29iu4efc4pl2;
SUIR=E7070CD2BBB9C8E0EC821D21BC275570;
SNUID=D0373AE38C89FED06563BEFC8DC232EF;
ld=1lllllllll2bt6vBlllllVHhmf1lllllbrWEgllllxYlllllRklll5@@@@@@@@@@;
LSTMV=969%2C85;
LCLKINT=48607

经过测试,发现其中有几个参数很重要,SUID、SNUID以及SUV。

SUID具体的含义可以自行百度,这里只讲述它生成的过程。当我们访问sogou搜索首页的时候,set-cookies中便会生成一个SUID参数的内容,除非重启浏览器,不然短时间内SUID并不会改变。SUID的值应该是sogou服务端随便分配的,只有当重新开启一个session时它的值才会更新。

SNUID是sogou反爬虫的重点,sogou也是对同一个SNUID访问次数做了限制,而超过限制后,会跳转到验证码页面,只有输入验证码重新验证以后,SNUID才会更新,访问才能继续进行。那么SNUID是如何生成的呢?经过测试,应该是由javascript生成的,当然前提是要有SUID,SUID是生成SNUID的基础。

SUV参数内容是由javascript生成的,测试并没有发现其对于反爬虫有何影响,故本文不做详细介绍。

被屏蔽现象:
当同一个SNUID访问次数受限后,继续访问sogou会跳转到一个验证码页面。

URL地址:

1
http://www.sogou.com/antispider/?from=%2fweb%3Fquery%3d152512wqe%26ie%3dutf8%26_ast%3d1488957312%26_asf%3dnull%26w%3d01029901%26p%3d40040100%26dp%3d1%26cid%3d%26cid%3d%26sut%3d578%26sst0%3d1488957299160%26lkt%3d3%2C1488957298718%2C1488957298893

自动化生成SNUID

通过访问验证码页面获取
当访问验证码页面,并填写验证码完成验证后,会重新生成一个新的SNUID,而此请求可以重复发送(不需要再次输入验证码),每次发送都会生成一个新的SNUID。
通过模拟浏览器访问,执行javascript
可以利用phantomjs去爬取sogou页面,也能获取SNUID值。

获取SNUID代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import requests
import json
import time
import random
'''
方法(一)通过phantomjs访问sogou搜索结果页面,获取SNUID的值
'''
def phantomjs_getsnuid():
from selenium import webdriver
d=webdriver.PhantomJS('D:\python27\Scripts\phantomjs.exe',service_args=['--load-images=no','--disk-cache=yes'])
try:
d.get("https://www.sogou.com/web?query=")
Snuid=d.get_cookies()[5]["value"]
except:
Snuid=""
d.quit()
return Snuid
'''
方法(二)通过访问特定url,获取body里面的id
'''
def Method_one():
url="http://www.sogou.com/antispider/detect.php?sn=E9DA81B7290B940A0000000058BFAB0&wdqz22=12&4c3kbr=12&ymqk4p=37&qhw71j=42&mfo5i5=7&3rqpqk=14&6p4tvk=27&eiac26=29&iozwml=44&urfya2=38&1bkeul=41&jugazb=31&qihm0q=8&lplrbr=10&wo65sp=11&2pev4x=23&4eyk88=16&q27tij=27&65l75p=40&fb3gwq=27&azt9t4=45&yeyqjo=47&kpyzva=31&haeihs=7&lw0u7o=33&tu49bk=42&f9c5r5=12&gooklm=11&_=1488956271683"
headers={"Cookie":
"ABTEST=0|1488956269|v17;\
IPLOC=CN3301;\
SUID=E9DA81B7290B940A0000000058BFAB6D;\
PHPSESSID=rfrcqafv5v74hbgpt98ah20vf3;\
SUIR=1488956269"
}
try:
f=requests.get(url,headers=headers).content
f=json.loads(f)
Snuid=f["id"]
except:
Snuid=""
return Snuid
'''
方法(三)访问特定url,获取header里面的内容
'''
def Method_two():
url="https://www.sogou.com/web?query=333&_asf=www.sogou.com&_ast=1488955851&w=01019900&p=40040100&ie=utf8&from=index-nologin"
headers={"Cookie":
"ABTEST=0|1488956269|v17;\
IPLOC=CN3301;\
SUID=E9DA81B7290B940A0000000058BFAB6D;\
PHPSESSID=rfrcqafv5v74hbgpt98ah20vf3;\
SUIR=1488956269"
}
f=requests.head(url,headers=headers).headers
print f
'''
方法(四)通过访问需要输入验证码解封的页面,可以获取SNUID
'''
def Method_three():
'''
http://www.sogou.com/antispider/util/seccode.php?tc=1488958062 验证码地址
'''
'''
http://www.sogou.com/antispider/?from=%2fweb%3Fquery%3d152512wqe%26ie%3dutf8%26_ast%3d1488957312%26_asf%3dnull%26w%3d01029901%26p%3d40040100%26dp%3d1%26cid%3d%26cid%3d%26sut%3d578%26sst0%3d1488957299160%26lkt%3d3%2C1488957298718%2C1488957298893
访问这个url,然后填写验证码,发送以后就是以下的包内容,可以获取SNUID。
'''
import socket
import re
res=r"id\"\: \"([^\"]*)\""
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.sogou.com',80))
s.send('''
POST http://www.sogou.com/antispider/thank.php HTTP/1.1
Host: www.sogou.com
Content-Length: 223
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: CXID=65B8AE6BEE1CE37D4C63855D92AF339C; SUV=006B71D7B781DAE95800816584135075; IPLOC=CN3301; pgv_pvi=3190912000; GOTO=Af12315; ABTEST=8|1488945458|v17; PHPSESSID=f78qomvob1fq1robqkduu7v7p3; SUIR=D0E3BB8E393F794B2B1B02733A162729; SNUID=B182D8EF595C126A7D67E4E359B12C38; sct=2; sst0=958; ld=AXrrGZllll2Ysfa1lllllVA@rLolllllHc4zfyllllYllllljllll5@@@@@@@@@@; browerV=3; osV=1; LSTMV=673%2C447; LCLKINT=6022; ad=6FwTnyllll2g@popQlSGTVA@7VCYx98tLueNukllll9llllljpJ62s@@@@@@@@@@; SUID=EADA81B7516C860A57B28911000DA424; successCount=1|Wed, 08 Mar 2017 07:51:18 GMT; seccodeErrorCount=1|Wed, 08 Mar 2017 07:51:45 GMT
c=6exp2e&r=%252Fweb%253Fquery%253Djs%2B%25E6%25A0%25BC%25E5%25BC%258F%25E5%258C%2596%2526ie%253Dutf8%2526_ast%253D1488957312%2526_asf%253Dnull%2526w%253D01029901%2526p%253D40040100%2526dp%253D1%2526cid%253D%2526cid%253D&v=5
''')
buf=s.recv(1024)
p=re.compile(res)
L=p.findall(buf)
if len(L)>0:
Snuid=L[0]
else:
Snuid=""
return Snuid
def getsnuid(q):
while 1:
if q.qsize()<10:
Snuid=random.choice([Method_one(),Method_three(),phantomjs_getsnuid()])
if Snuid!="":
q.put(Snuid)
print Snuid
time.sleep(0.5)
if __name__=="__main__":
import Queue
q=Queue.Queue()
getsnuid(q)

思路就是事先预制一些snuid放到队列,用的时候拿来用即可

ip问题自行解决一下
还有python3和python2的socket编码方式需要注意。3.0读取的是bytes-like的,但参数要求是chart-like的。2.0是str的

参考 https://thief.one/2017/03/19/爬取搜索引擎之搜狗/

Contents