我们以网易社招页面来做演示:
使用BeautifuSoup4解析器,将招聘网页上的职位名称、职位类别、招聘人数、工作地点、发布时间,以及每个职位详情的点击链接存储出来。
import json import requests from bs4 import BeautifulSoup class WangYiSpider(object): def __init__(self): self.base_url = "https://hr.163.com/position/list.do?positionName=¤tPage=" self.page = 1 # 初始化一个字典列表,保存职位信息 self.item_list = [] self.headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"} def send_request(self, full_url): response = requests.get(full_url, headers=self.headers) return response def parse_response(self, response): html = response.content.decode("utf-8") soup = BeautifulSoup(html, "lxml") node_list = soup.find_all("tr", attrs={"id":""}) node_list.pop(0) for node in node_list: item = {} # 遍历css选择器列表 for name in node.select("td a"): # 从a标签获取职位内容, 保存到字典中 item["position_name"] = name.get_text() # 部门 item["bumen"] = node.find_all("td")[1].get_text() print(item["bumen"]) # 职位 item["position"] = node.find_all("td")[2].get_text() # 工作类型 item["work_type"] = node.find_all("td")[3].get_text() # 工作地点 item["work_place"] = node.find_all("td")[4].get_text() # 招聘人数 item["counts"] = node.find_all("td")[5].get_text() # 发布时间 item["time"] = node.find_all("td")[6].get_text() # 链接详情 item["link"] = node.find_all("td")[0].a.get("href") # 每次循环获取一个职位信息,并保存在同一个列表中 self.item_list.append(item) def save_data(self): """ 实现数据存储 """ # 写入了Unicode字符串的json数据 # 将Python的列表 转为 Json字符串 json_str = json.dumps(self.item_list) # 写入json字符串数据到文件中 with open("wangyi.json", "w") as f: f.write(json_str) # 写入utf-8字符串的json数据(Python2 需要通过sys模块修改解释器编码即可) # json_str = json.dumps(self.item_list, ensure_ascii=False) # # 写入json字符串数据到文件中 # with open("wangyi.json", "w") as f: # f.write(json_str) def main(self): while True: q = input("q退出") if q == "q" or self.page == 125: break full_url = self.base_url + str(self.page) response = self.send_request(full_url=full_url) self.parse_response(response) self.save_data() self.page += 1 if __name__ == '__main__': spider = WangYiSpider() spider.main() 练习: 根据url:https://www.xinpianchang.com/channel/index/type-/sort-like/duration_type-0/resolution_type-/page-2 抓取新片场列表页的数据: 用户名,作者信息,保存片场名, 视频来源,观看次数,点赞数。并将数据保存在json文件中 # xin_pian_chang_bs4.py[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oSMBuCQe-1572484834755)(assets/1567060774891.png)]
——————————————————————————————————————————
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。
JSON和XML的比较可谓不相上下。
Python 2.7中自带了JSON模块,直接import json就可以使用了。
官方文档:http://docs.python.org/library/json.html
Json在线解析网站:http://www.json.cn/#
json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构
对象:对象在js中表示为{ }括起来的内容,数据结构为 { key:value, key:value, ... }的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象这几种。数组:数组在js中是中括号[ ]括起来的内容,数据结构为 ["Python", "javascript", "C++", ...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。import json
json模块提供了四个功能:dumps、dump、loads、load,用于字符串 和 python数据类型间进行转换。
把Json格式字符串解码转换成Python对象 从json到python的类型转化对照如下:
# json_loads.py import json strList = '[1, 2, 3, 4]' strDict = '{"city": "北京", "name": "小明"}' json.loads(strList) # [1, 2, 3, 4] json.loads(strDict) # json数据自动按Unicode存储 # {u'city': u'\u5317\u4eac', u'name': u'\u5c0f\u660e'}实现python类型转化为json字符串,返回一个str对象 把一个Python对象编码转换成Json字符串
从python原始类型向json类型的转化对照如下:
# json_dumps.py import json import chardet listStr = [1, 2, 3, 4] tupleStr = (1, 2, 3, 4) dictStr = {"city": "北京", "name": "小明"} json.dumps(listStr) # '[1, 2, 3, 4]' json.dumps(tupleStr) # '[1, 2, 3, 4]' # 注意:json.dumps() 处理中文时默认使用的ascii编码,会导致中文无法正常显示 print(json.dumps(dictStr) ) # {"city": "\u5317\u4eac", "name": "\u5c0f\u660e"} # 记住:处理中文时,添加参数 ensure_ascii=False 来禁用ascii编码 print(json.dumps(dictStr, ensure_ascii=False) ) # {"city": "北京", "name": "小明"}将Python内置类型序列化为json对象后写入文件
# json_dump.py import json listStr = [{"city": "北京"}, {"name": "大刘"}] json.dump(listStr, open("listStr.json","w"), ensure_ascii=False) dictStr = {"city": "北京", "name": "大刘"} json.dump(dictStr, open("dictStr.json","w"), ensure_ascii=False)读取文件中json形式的字符串元素 转化成python类型
# json_load.py import json strList = json.load(open("listStr.json")) print(strList) # [{"city": "\u5317\u4eac", "name": "\u5c0f\u660e"}] strDict = json.load(open("dictStr.json")) print(strDict)JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Python, PHP 和 Java。
JsonPath 对于 JSON 来说,相当于 XPath 对于 XML。
安装方法:pip install jsonpath
官方文档:http://goessner.net/articles/JsonPath
Json结构清晰,可读性高,复杂度低,非常容易匹配,下表中对应了XPath的用法。
XPathJSONPath描述/$根节点.@现行节点/.or[]取子节点..n/a取父节点,Jsonpath未支持//..就是不管位置,选择所有符合条件的条件**匹配所有元素节点@n/a根据属性访问,Json不支持,因为Json是个Key-value递归结构,不需要属性访问。[][]迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等)|[,]支持迭代器中做多选。[]?()支持过滤操作.n/a()支持表达式计算单的迭代操作,如数组下标,根据内容选值等)|[,]支持迭代器中做多选。[]?()支持过滤操作.n/a()支持表达式计算()n/a分组,JsonPath不支持