页面解析之结构化数据

结构化的数据是最好处理,一般都是类似JSON格式的字符串,直接解析JSON数据,提取JSON的关键字段即可。

JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式;适用于进行数据交互的场景,比如网站前台与后台之间的数据交互

Python 2.7中自带了JSON模块,直接import json就可以使用了。

Json模块提供了四个功能:dumps、dump、loads、load,用于字符串 和 python数据类型间进行转换

Python操作json的标准api库参考

在线JSON格式化代码

1. json.loads()

实现:json字符串 转化 python的类型,返回一个python的类型

从json到python的类型转化对照如下:

页面解析之结构化数据 - 图1

  1. import json
  2. a="[1,2,3,4]"
  3. b='{"k1":1,"k2":2}'#当字符串为字典时{}外面必须是''单引号{}里面必须是""双引号
  4. print json.loads(a)
  5. [1, 2, 3, 4]
  6. print json.loads(b)
  7. {'k2': 2, 'k1': 1}

案例

  1. import urllib2
  2. import json
  3. response = urllib2.urlopen(r'http://api.douban.com/v2/book/isbn/9787218087351')
  4. hjson = json.loads(response.read())
  5. print hjson.keys()
  6. print hjson['rating']
  7. print hjson['images']['large']
  8. print hjson['summary']

2. json.dumps()

实现python类型转化为json字符串,返回一个str对象

从python原始类型向json类型的转化对照如下:

页面解析之结构化数据 - 图2

  1. import json
  2. a = [1,2,3,4]
  3. b ={"k1":1,"k2":2}
  4. c = (1,2,3,4)
  5. json.dumps(a)
  6. '[1, 2, 3, 4]'
  7. json.dumps(b)
  8. '{"k2": 2, "k1": 1}'
  9. json.dumps(c)
  10. '[1, 2, 3, 4]'

json.dumps 中的ensure_ascii 参数引起的中文编码问题

如果Python Dict字典含有中文,json.dumps 序列化时对中文默认使用的ascii编码

  1. import chardet
  2. import json
  3. b = {"name":"中国"}
  4. json.dumps(b)
  5. '{"name": "\\u4e2d\\u56fd"}'
  6. print json.dumps(b)
  7. {"name": "\u4e2d\u56fd"}
  8. chardet.detect(json.dumps(b))
  9. {'confidence': 1.0, 'encoding': 'ascii'}

'中国' 中的ascii 字符码,而不是真正的中文。

想输出真正的中文需要指定ensure_ascii=False

  1. json.dumps(b,ensure_ascii=False)
  2. '{"name": "\xe6\x88\x91"}'
  3. print json.dumps(b,ensure_ascii=False)
  4. {"name": "我"}
  5. chardet.detect(json.dumps(b,ensure_ascii=False))
  6. {'confidence': 0.7525, 'encoding': 'utf-8'}

3. json.dump()

把Python类型 以 字符串的形式 写到文件中

  1. import json
  2. a = [1,2,3,4]
  3. json.dump(a,open("digital.json","w"))
  4. b = {"name":"我"}
  5. json.dump(b,open("name.json","w"),ensure_ascii=False)
  6. json.dump(b,open("name2.json","w"),ensure_ascii=True)

4. json.load()

读取 文件中json形式的字符串元素 转化成python类型

  1. # -*- coding: utf-8 -*-
  2. import json
  3. number = json.load(open("digital.json"))
  4. print number
  5. b = json.load(open("name.json"))
  6. print b
  7. b.keys()
  8. print b['name']

实战项目

获取 lagou 城市表信息

  1. import urllib2
  2. import json
  3. import chardet
  4. url ='http://www.lagou.com/lbs/getAllCitySearchLabels.json?'
  5. request =urllib2.Request(url)
  6. response = urllib2.urlopen(request)
  7. print response.code
  8. resHtml = response.read()
  9. jsonobj = json.loads(resHtml)
  10. print type(jsonobj)
  11. print jsonobj
  12. citylist =[]
  13. allcitys = jsonobj['content']['data']['allCitySearchLabels']
  14. print allcitys.keys()
  15. for key in allcitys:
  16. print type(allcitys[key])
  17. for item in allcitys[key]:
  18. name =item['name'].encode('utf-8')
  19. print name,type(name)
  20. citylist.append(name)
  21. fp = open('city.json','w')
  22. content = json.dumps(citylist,ensure_ascii=False)
  23. print content
  24. fp.write(content)
  25. fp.close()

输出:

页面解析之结构化数据 - 图3

JSONPath

JSON 信息抽取类库,从JSON文档中抽取指定信息的工具

JSONPath与Xpath区别

JsonPath 对于 JSON 来说,相当于 XPATH 对于XML。

下载地址:

https://pypi.python.org/pypi/jsonpath/

安装方法:

下载jsonpath,解压之后执行'python setup.py install'

参考文档

XPathJSONPathResult
/store/book/author $.store.book[].author the authors of all books in the store
//author $..author all authors
/store/ $.store. all things in store, which are some books and a red bicycle.
/store//price $.store..price the price of everything in the store.
//book[3] $..book[2] the third book
//book[last()] $..book[(@.length-1)]$..book[-1:] the last book in order.
//book[position()<3] $..book[0,1]$..book[:2] the first two books
//book[isbn] $..book[?(@.isbn)] filter all books with isbn number
//book[price<10] $..book[?(@.price<10)] filter all books cheapier than 10
// $..* all Elements in XML document. All members of JSON structure.

案例

还是以 http://www.lagou.com/lbs/getAllCitySearchLabels.json 为例,获取所有城市

  1. import jsonpath
  2. import urllib2
  3. import chardet
  4. url ='http://www.lagou.com/lbs/getAllCitySearchLabels.json'
  5. request =urllib2.Request(url)
  6. response = urllib2.urlopen(request)
  7. print response.code
  8. resHtml = response.read()
  9. ##detect charset
  10. print chardet.detect(resHtml)
  11. jsonobj = json.loads(resHtml)
  12. citylist = jsonpath.jsonpath(jsonobj,'$..name')
  13. print citylist
  14. print type(citylist)
  15. fp = open('city.json','w')
  16. content = json.dumps(citylist,ensure_ascii=False)
  17. print content
  18. fp.write(content.encode('utf-8'))
  19. fp.close()

XML

xmltodict模块让使用XML感觉跟操作JSON一样

Python操作XML的第三方库参考:

https://github.com/martinblech/xmltodict

模块安装:

  1. pip install xmltodict
  1. import xmltodict
  2. bookdict = xmltodict.parse("""
  3. <bookstore>
  4. <book>
  5. <title lang="eng">Harry Potter</title>
  6. <price>29.99</price>
  7. </book>
  8. <book>
  9. <title lang="eng">Learning XML</title>
  10. <price>39.95</price>
  11. </book>
  12. </bookstore>
  13. """)
  14. print bookdict.keys()
  15. [u'bookstore']
  16. print json.dumps(bookdict,indent=4)

输出结果:

  1. {
  2. "bookstore": {
  3. "book": [
  4. {
  5. "title": {
  6. "@lang": "eng",
  7. "#text": "Harry Potter"
  8. },
  9. "price": "29.99"
  10. },
  11. {
  12. "title": {
  13. "@lang": "eng",
  14. "#text": "Learning XML"
  15. },
  16. "price": "39.95"
  17. }
  18. ]
  19. }
  20. }

数据提取总结

  • HTML、XML
  1. XPath
  2. CSS选择器
  3. 正则表达式
  • JSON
  1. JSONPath
  2. 转化成Python类型进行操作(json类)
  • XML
  1. 转化成Python类型(xmltodict
  2. XPath
  3. CSS选择器
  4. 正则表达式
  • 其他(js、文本、电话号码、邮箱地址)
  1. 正则表达式