爬虫项目中涉及Json数据的处理

作者: guoery | 来源:发表于2017-04-05 11:28 被阅读1908次

    在执行爬虫项目的过程中,有时返回的不是一个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 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

    :ptyhondict转成str

    json.loads:str转成pythondict类型

    有了以上的基础知识后,对于人人贷的数据可以直接采用如下方式处理:

    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格式数据,那么可能需要额外处理一下。比如京东商品的评论数据,

    https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv52063&productId=3133859&score=0&sortType=5&page=1&pageSize=10&isShadowSku=0

    这是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)

    :http://bluewhale.cc/2016-12-11/use-python-crawl-and-analysis-data-renrendai-urllib-html.html#ixzz4dKuFHIgb

    2 http://blog.csdn.net/yan_xing_an/article/details/46892105

    相关文章

      网友评论

      本文标题:爬虫项目中涉及Json数据的处理

      本文链接:https://www.haomeiwen.com/subject/pemtattx.html