- 第三部分 : 数据提取
- 知识点一 : 结构数据与非结构数据
- 知识点二 : 初级_10_正则模拟爬取某蜓FM排行榜数据
- 知识点三 : 非结构数据的提取
- 1.正则表达式
- 2.Xpath语法
- 知识点四 : 初级_11_正则模拟爬取某氪新闻列表数据
- 知识点五 : 初级_12_Xpath模拟爬取某瓣电影影评
- 知识点六 : jsonpath模块
- 知识点七 : 初级_13_jsonpath模块获取json格式中数据
结构化数据 : json,xml等,方式是直接转python类型
非结构化数据 : html,方式是用正则表达式,xpath,bs4提取
注释1 : json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False
注释2 : 一般情况下Network里面的Preview和Response的结果似乎一模一样,但在preview中控制台会把发过来的json数据自动转为js对象格式
注释3 : r.text和r.content.decode()的区别在于text按照自己的方式进行解码,而content.decode()默认按照utf8进行解码,所以最好用content.decode()
注释4 : json格式转字典格式后,用json_dict.get(“name”)进行提取,而不用json_dict[“name”],因为前者没有对应的值返回None而后者会报错.
"""
help1: requests模块中,r.json()为Requests中内置的JSON解码器.其中只有response返回为json格式时,用r.json()打印出响应的内容,如果response返回不为json格式,使用r.json()会报错.
报错内容:ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
"""
import requests
# 1.获取网页url,,伪装浏览器版本
url = "https://webapi.qtfm.cn/api/mobile/rank/hotSaleWeekly"
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1"
}
# 2.发起请求,获得响应
r = requests.get(url=url, headers=headers)
# 3.分析内容
print(r.status_code)
print(r.json())
print(type(r.json()))
# 4.提取数据
json_dict = r.json()
ranking_list = json_dict.get("rankinglist")
for temp in ranking_list:
print(temp.get("title"), "播放量"+temp.get("playCount"), temp.get("desc"), temp.get("imgUrl"))
正则表达式即用事先定义好的一些特定字符,及这些特定字符的组合,组成一个规则字符串,这个规则字符串用来表达对字符串的一种过滤逻辑.
Xpath使用路径表达式来选取文档中的节点或节点集.
注释1 : 插件Xpath helper 只能在电脑端模式下才能使用
注释2 : Xpath起始下标为1,最后一个下标为last(),倒数第二个为last()-1
"""
help1: 在源代码中搜索,看看是否是嵌套在 HTML中的,如果在就用正则匹配出来
help2:
问题:SyntaxError: Non-UTF-8 code starting with 'xe5' in file G:爬虫路线学习[2022_04_28]第二部分_requests[2022_04_30]初级_1.10_正则模拟爬取36氪新闻列表数据.py on line 7, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
解决:py文件内第一行注释该文档的编码格式# coding:utf-8
help3: .*?加()只提取文本(.*?)
help4: 取下标:item_list.index(temp)
help5: [^"]表示除了"都取
help6: 分别取第一个,第二个内容: temp[0] temp[1]
help7:
问题:TypeError: a bytes-like object is required, not 'str'
方案:删除"wb"中的b
help8: 'w+' 是文本写入'wb'是字节写入
help9:
问题:UnicodeEncodeError: 'gbk' codec can't encode character 'u2022' in position 11: illegal multibyte sequence
方案:去设置里面讲解码全部改为utf-8
"""
# coding:utf-8
import re
import requests
# 1.获取网页url,伪装浏览器版本
url = "https://m.36kr.com/"
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1"
}
# 2.发送请求,获取数据
r = requests.get(url=url, headers=headers)
# 3.分析内容
html = r.content.decode()
item_list = re.findall(r'(.*?).*?', html)
# 4.提取数据
print("提取到的新闻个数:", len(item_list))
for temp in item_list:
print(f"{item_list.index(temp)+1}.新闻标题:《{temp[1]}》t链接:https://36kr.com{temp[0]}")
"""
help1: pycharm中用lxml模块实现Xpath表达式,需要用到Xpath表达式的数据先用etree.HTML()接收
help2: 去处获取到的数据中奇奇怪怪的东西用.replace("xxx", "")
"""
import time
import requests
from lxml import etree
num = 0
for i in range(3):
num += 20
# 1.获取网页url,伪装浏览器版本
url = f"https://movie.douban.com/subject/1292052/reviews?start={num}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36"
}
# 2.发起请求获得响应
r = requests.get(url=url, headers=headers)
# 3.调用etree模块,用XPath表达式分析数据
html = etree.HTML(r.content.decode())
comment_list = html.xpath('//*[@]/text()[1]')
# 4.提取数据
print(f"提取到的评论条数为:{len(comment_list)}")
for comment in comment_list:
print(comment.replace(" ", "").replace("(", "").replace(" ", ""))
print(f"第{i+1}页影评爬取完成,共{len(comment_list)}条数据")
print("-"*100)
time.sleep(3)
jsonPath是一种可以快速解析json数据的方式,jsonpath对应json来说,相当于Xpath对于XML,JsonPath用来解析多层嵌套的json数据.
import json
import jsonpath
info = {
"error_code": 0,
"stu_info": [
{
"id": 2059,
"name": "小白",
"sex": "男",
"age": 28,
"addr": "重庆市沙坪坝区大学城xxx",
"grade": "天蝎座",
"phone": "151119xxxxx",
"goid": 10896,
"info": {
"card": "1234567",
"bank_name": "中国银行"
}
},
{
"id": 2067,
"name": "小黑",
"sex": "男",
"age": 26,
"addr": "重庆市沙坪坝区大学城xxx",
"grade": "处女座",
"phone": "152231xxxxx",
"goid": 10896,
}
]
}
# $表示最外层的{} .表示子节点
res1 = jsonpath.jsonpath(info, "$.stu_info[0].name")
print(''.join(res1)) # 将列表转为字符串
# ..表示模糊匹配 整个语句能从嵌套n层中获取到所有学生的姓名信息
res2 = jsonpath.jsonpath(info, "$.stu_info..name")
print(','.join(res2))



