在执行爬虫项目的过程中,有时返回的不是一个html页面而是json格式数据,此时对数据的解析非常重要。
比如京东的评论数据、淘宝的评论数据、人人贷的数据(https://www.we.com/lend/loanList!json.action?pageIndex=3)。
(一).Json格式数据的爬取
采用Python爬取数据可以采用Scrapy或者采用urllib,requests等两种方法,显然在这里采用第二种方式更为简单。
步骤如下:
1、由于有分页的情况,因此首先构造带分页的url地址。
urlbase ="https://www.we.com/lend/loanList!json.action?pageIndex="
urlList = []
#拼接要爬取的地址
for i in range(1,52):
url= urlbase +str(i)+"&_=1489560949549"urlList.append( url )
#循环抓取列表页信息
2、采用request对以上的url进行爬取
import requests
content=requests.get(url,headers=headers).content
在爬取的过程中,考虑到需要模拟真实的用户,因此需要添加cookie或者header参数。
(二).对爬取的json格式数据的解析
至此,数据已经爬取下来,存放在contend里面,但是如何提出里面的关键数据非常重要。
为了能在浏览器中方便的浏览Json格式的数据,建议在chrome中添加一个扩展程序JSONView,使得其Json格式的数据能够结构化的显示。比如人人贷的数据显示如下。
对于这个数据的解析有两种方式
1、采用正则表达式解析
比如我们要获取“amount”的内容,可以采用以下方式获取:
importre
##使用正则提取amount字段amount = re.findall(r'"amount":(.*?),', content)
其中content是爬取下来内容。
2、基于json格式进行获取
实际上json的数据格式与python的dict是有极大的类似之处。在python的importjson这个包里面提供了两个经典的预处理方法:
import json
dict_ = {1:2, 3:4,"55":"66"}
# test json.dumps
print type(dict_), dict_
json_str =json.dumps(dict_)
print "json.dumps(dict) return:"
print type(json_str), json_str
# test json.loads
print "\njson.loads(str) return"
dict_2 =json.loads(json_str)
print type(dict_2), dict_2
输出为:
程序结果:
{'55': '66', 1: 2, 3: 4}
json.dump(dict) return:
{"55": "66", "1": 2,"3": 4}
json.loads(str) return
{u'55': u'66', u'1': 2, u'3': 4}
从上面的样例可以看出两个经典的方法dumps和loads的作用分别为:
json.dumps
:将ptyhon的dict转成str
json.loads:将str转成python的dict类型
有了以上的基础知识后,对于人人贷的数据可以直接采用如下方式处理:
for url in urlList:
//获取内容
content=requests.get(url,headers=headers).content
//采用json.loads方法将str转换为dict类型
con=json.loads(content)#获取都到评论列表,因为之前还有很多的其他东西,这些是不需要的
//直接采用python中dict的数据获取方法,取得loans列表,然后直接取得各个数据。
commentList= con["data"]["loans"]
for item in commentList:
loanId= item['loanId']
title= item['title']
amount= item['amount']
interest= item['interest']
months= item['months']
备注:
采用第二种方式的时候要注意,返回的数据是不是标准的json格式的数据,如果不是标准的json格式数据,那么可能需要额外处理一下。比如京东商品的评论数据,
这是Apple iPhone 7 Plus (A1661) 128G亮黑色移动联通电信4G手机的评论数据。
直接打开上面的链接后就会发现在jsonview下面并不是正规的json格式数据显示,那么对于这种数据类型,可以采用正则表达式的方式来获取,当然也还是可以采用json转换为dict方式来处理。
仔细分析爬下来的数据:
原始页面:
我们要爬取的是用户评论数据,而爬取下来的content并不是标准的json格式数据,怎么办,如上图给出的提示,爬取下来的contend是把数据放到fetchJSON_comment98vv52063()里面了,而括号里面的数据则是标准的json格式数据。
因此对于此类的数据,首先要正则表达是提出括号里面的数据,然后再用loads方法转换为python的dict类型数据进行处理就可以了。
源码如下:
#爬取
for url in urlList:
cont=requests.get(url,headers=headers,cookies=cookie).content
#这点非常重要,这里的正则表达式是取以数字或者字母开头,后面紧跟()中的内容 rex=re.compile(r'\w+[(]{1}(.*)[)]{1}')
content=rex.findall(cont)[0]#取出括号中的东西,这是一个标准的json格式数据
con=json.loads(content,"gbk")
#获取都到评论列表,因为之前还有很多的其他东西,这些是不需要的
commentList= con['comments']
for item in commentList:
id= item['id']
content= item['content'].strip()
referenceName= item['referenceName']
productColor= item['productColor']
一个技巧:可以先尝试提出()内的数据到一些在线的json解析网站(http://www.bejson.com/)去看看json数据的排列格式,这样就更加清楚该怎么提取数据了。
(三)参考文献:
1、使用python抓取并分析数据—人人贷(urllib)
2 http://blog.csdn.net/yan_xing_an/article/details/46892105