python 调用百度识图识取本地图片
最近看到一个 github 项目, https://github.com/andelf/fuck12306,使用百度识图来识取 12306 的分割图片.
其中,调用百度识图的时候出现了错误.
对该方法好奇,研究了一下.
先自己手动完成百度识图的整个过程,#5 为向百度上传图片,#10 为一个不知道的响应过程,#14 为一个关于注册的 js 响应,#16 同样为一个 json.通过观察可知,识图的相关响应只发生在 #5 和#10 以及#16 三步.
利用 Fiddler 观察 #5 的请求信息,是一个 post 形式的请求,除了一般的 headers 以外,还有一个文件传输
(具体内容不止图中这点)
这是一个 multipart/form-data 请求,能够用 python 的 requests 进行模拟.具体方法参照:
http://blog.csdn.net/j_akill/article/details/43560293 和 https://www.cnblogs.com/titan5750/p/6879114.html
返回的 response 中的内容如下所示
然后观察 #10,#10 的网页中已经有了 guessword
该 guessword 应该就是结果了.那么只要获得 #10 的网址就可以获得识图的结果,也就不需要查看#16 了.查看#10 的 request_url,
该网址可以用到 #5 中返回的 querySign 和 queryImageUrl,推测 fm,uptype,result 应该是不变的字符串,只剩下最后一个 vs 未知.查找所有 js 文件,在 http://imgn0.bdstatic.com/image/mobile/n/static/pcdutu/static/pkg/pcdutu_*****.js 中找到
观察后可知 fm,uptype,result 的确为不变的字符串(不同情况下可能不同),而 vs 取值来自变量 u,将该 js 反编译,以后
u 为 window.bd,这个 window 有可能是 JavaScript 层级中的顶层对象 Window,代表一个浏览器窗口或一个框架.那么这个 window 应该第一次打开百度识图网页的时候就确定了,打开 image.baidu.com/?fr=shitu 的网页,查看源代码,果然里面有一个 window,且该 window 有一个 vsid.
将这个 vsid 保存下来结合 #5 中获得的数据,就可以构造#10 的网页,进而获得#10 网页中的 guessword.
代码如下:# -*-coding:utf-8-*-
importrequests
importos
importjson
importre
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) ApplewebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
}
source='http://image.baidu.com'
#得到vs
vs_url=source+'/?fr=shitu'
vs_page=requests.get(vs_url,headers=headers).text
vs_id=re.findall('window.vsid = "(.*?)"',vs_page)[0]
url='/pcdutu/a_upload?fr=html5&target=pcSearchImage&needJson=true'
filepath=os.getcwd()
pic=u"test1.jpg"
files={'file':(pic,open(filepath+'\\'+pic,'rb'),'image/jpeg'),'pos':(None,'upload'),
'uptype':(None,'upload_pc'),'fm':(None,'home')}
r=requests.post(source+url,headers=headers,files=files)
tmp=r.text
tmp_json=json.loads(tmp)
queryImageUrl=tmp_json['url']
querySign=tmp_json['querySign']
simid=tmp_json['simid']
url2=source+'/pcdutu?queryImageUrl='+queryImageUrl+'&querySign='+querySign+'fm=index&uptype=upload_pc&result=result_camera&vs='+vs_id
r2=requests.get(url2,headers=headers).text
gussword=re.findall("'guessWord': '(.*?)'",r2)[0]
printgussword
来源: http://blog.csdn.net/m0_37596686/article/details/78982618