您的位置:首页 > 编程语言 > Python开发

python爬虫-京东登录

2016-06-24 10:40 441 查看
在写爬虫的时候,解决登陆问题往往是比较麻烦的事情。这里介绍一下京东网站的登陆方法。

登陆到京东的首页,我们看到最上方有一个登陆链接,点进去之后是这样: https://passport.jd.com/new/login.aspx
为了方便我们观察传递的参数规律,我们先用自己的账号密码模拟登陆一次,然后使用抓包工具查看。这里使用的是firefox+firebug ,firebug在这篇文章中有讲到。

点击登陆之后我们经过仔细的查看,找到了登陆的这条POST信息:



这里我们可以看到,POST数据的目标地址为: http://passport.jd.com/uc/loginService ,POST参数中需要我们我们自己填写的为:loginname,loginpwd,nloginpwd,其中后面两个是一样的,都是用户的密码。另外三个machineCpu,machineDisk,machineNet都为空。那么还有两个怎么办呢?一个是第一行的无规律的字符,另外一个是uuid,这两个都是根据每次登陆随机生成的内容,要怎么才能找到呢?

我们回到最开始的登陆页面 https://passport.jd.com/new/login.aspx ,查看源代码。直接搜索uuid,能够找到后面的值:



可以直接用BeautifulSoup或者正则表达式提取出来:

uuid = loginSoup.find_all("form")[0].find_all("input")[0]['value']

那么另外一个参数怎么办呢?由于这个参数的Key和Value都是变化的,我们可以先把登陆页面源代码保存下来,然后登陆一次,查看包中的Key的值,再通过这个值在刚刚保存的代码中去搜索,从而知道它的位置:



我们同样能够把它取出来:

clr = loginSoup.find_all("span","clr")[0]
clrName = clr.find_next_siblings("input")[0]['name']
clrValue = clr.find_next_siblings("input")[0]['value']

有了这两个参数,我们就可以尝试着进行登陆了:

import urllib
import urllib2
import cookielib
import re
import socket
from bs4 import BeautifulSoup

def Navigate(url,data={}): #定义连接函数,有超时重连功能
tryTimes = 0
while True:
if (tryTimes>20):
print "多次尝试仍无法链接网络,程序终止"
break
try:
if (data=={}):
req = urllib2.Request(url)
else:
req = urllib2.Request(url,urllib.urlencode(data))
req = urllib2.urlopen(req).read()
tryTimes = tryTimes +1
except socket.error:
print "连接失败,尝试重新连接"
else:
break
return req

try:
cookie = cookielib.CookieJar()
cookieProc = urllib2.HTTPCookieProcessor(cookie)
except:
raise
else:
opener = urllib2.build_opener(cookieProc)
opener.addheaders = [('User-Agent','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11')]
urllib2.install_opener(opener)

url = "https://passport.jd.com/uc/login"
login = func.Navigate(url)
loginSoup = BeautifulSoup(login)
#查找登陆参数中的uuid
uuid = loginSoup.find_all("form")[0].find_all("input")[0]['value']
#print uuid

#查找登陆参数中的随机值,class为clr
clr = loginSoup.find_all("span","clr")[0] clrName = clr.find_next_siblings("input")[0]['name'] clrValue = clr.find_next_siblings("input")[0]['value']
#print clrName,clrValue

url = "http://passport.jd.com/uc/loginService"
#print url

postData = {
'loginname':self.user,
'nloginpwd':self.password,
'loginpwd':self.password,
# 'machineNet':'',
# 'machineCpu':'',
# 'machineDisk':'', str(clrName):str(clrValue),
'uuid':uuid,
'authcode':''
}
passport = Navigate(url,postData)
print passportSoup

运行程序,程序返回:{“success”:”http://www.jd.com”} ,则说明登陆成功。

但还不是这么顺利,因为京东在几次登陆之后就会加上讨厌的验证码,普通登陆的情况下验证码authcode只要为空即可,但如果接口返回的是“请输入验证码”的汉字编码的话,则说明该用户需要验证码才能登陆了。

目前验证码处理仍然是一个比较困难的问题。ocr技术也并不是那么成熟。不过好在京东的验证码图片并不太复杂,不像那种人去看都看不明白的反人类图片。要解决这一问题可以有两种方法:

如果仅仅是个人使用,一般的实验测试等,可以将验证码图片下载下来,通过人工查看并手动输入的方法来完成,这里附上代码处理:

#下载验证码图片:
checkPicUrl = loginSoup.find_all("div","item-ifo")[2].find_all("img")[0]['src2']
req = func.Navigate(checkPicUrl)
checkPic = open("checkPic.jpg","w")
checkPic.write(req)
checkPic.close()
#调用Linux系统的eog(图像查看器)来打开图片文件

os.system('eog checkPic.jpg')
checkCode = raw_input("请输入弹出图片中的验证码:")
postData['authcode'] = str(checkCode)

把这段代码放到最后的登陆代码之前即可,这里需要系统有图形界面和图片查看器,并通过程序内置调用Linux的命令来打开验证码图片。

2.没有图形界面,大规模调用的情况。

这种情况如果自己没有验证码识别的系统,可以求助于网上很多第三方接口,厂商名字这里就不介绍了以免有广告之嫌。不过效果还是不错的,价格一般是根据验证码的复杂程度区别。像京东的4字符这种一般是1分钱一条。

自此,京东网站登陆完毕。接下来就可以任意的抓取想要的信息啦。

欢迎转载,请注明出处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: