7·数据解析

1.概念

什么是数据解析,数据解析可以干什么

概念就是讲一组数据中的局部数据进行提取 
数据清洗是去除
作用:就是用来实现聚焦爬虫

数据解析的通用原理

数据解析的通用原理
html展示的数据可以存储在哪里?
	标签之中
	属性中

2.提取数据的步骤

标签定位
取文本或者取属性

3.使用正则

需求:爬取的网站

1.对图片数据进行爬取

(.*?)取括号里面的值
.*?
.*? 表示匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
#如:
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab和ab。

2.re.m取多行数据

re.S 单行模式(可以看成将所有的字符串放在一行内匹配包括换行符\n)
re.M 多行模式(可以识别换行符 进行取值)

使用re.fechall 使用re.s re.m
字符串拼接拼接路径
#imgPath = dirName+\'/\'+imgName

示例

正则实现的数据解析

方法1(requests)

#方法1:使用requests模块
import requests
headers = {
    \'User-Agent\':\'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36\'
}
url = \'http://duanziwang.com/usr/uploads/2019/02/3334500855.jpg\'
pic_data = requests.get(url=url,headers=headers).content #content返回的是二进制类型的响应数据
with open(\'1.jpg\',\'wb\') as fp:
    fp.write(pic_data)

方法2(urllib)

使用urllib

urllib.request.urlretrieve(url=src,filename=imgPath) 
#url 指定图片路径地址 filename 图片路径地址

爬取单个页面

#需求的实现:爬取了一页的数据
url = \'http://duanziwang.com/category/%E6%90%9E%E7%AC%91%E5%9B%BE/\'
page_text = requests.get(url,headers=headers).text #页面源码数据

#新建一个文件夹
dirName = \'imgLibs\'
if not os.path.exists(dirName):
    os.mkdir(dirName)

#数据解析:每一张图片的地址
ex = \'<article.*?<img src="(.*?)" alt=.*?</article>\'
img_src_list = re.findall(ex,page_text,re.S) #爬虫中使用findall函数必须要使用re.S

for src in img_src_list:
    imgName = src.split(\'/\')[-1]
    imgPath = dirName+\'/\'+imgName
    urllib.request.urlretrieve(url=src,filename=imgPath)
    print(imgName,\'下载成功!!!\')

爬取所有页面

import os
import re
import requests
import urllib
#进行全站数据的爬取:爬取所有页码的图片数据
#需求的实现

#制定一个通用的url模板,不可以被改变
url = \'http://duanziwang.com/category/搞笑图/%d/\'

for page in range(1,4):
    new_url = format(url%page)
    page_text = requests.get(new_url,headers=headers).text #页面源码数据

    #新建一个文件夹
    dirName = \'imgLibs\'
    if not os.path.exists(dirName):
        os.mkdir(dirName)

    #数据解析:每一张图片的地址
    ex = \'<article.*?<img src="(.*?)" alt=.*?</article>\'
    img_src_list = re.findall(ex,page_text,re.S) 
    #爬虫中使用findall函数必须要使用re.S

    for src in img_src_list:
        imgName = src.split(\'/\')[-1]#进行
        imgPath = dirName+\'/\'+imgName#根据路径取存放爬取的内容
        urllib.request.urlretrieve(url=src,filename=imgPath)
        print(imgName,\'下载成功!!!\')

4.bs4

返回值是对应的html页面(标签)

1.环境的安装:
- pip install bs4
- pip install lxml
2.解析原理
- 实例化一个BeautifulSoup的一个对象,把即将被解析的页面源码内容加载到该对象中
- 调用BeautifulSoup对象中相关的方法和属性进行标签定位和本文数据的提取
3.实例化方式

BeautifulSoup对象的实例化的方式:

本地
BeautifulSoup(fp,\'lxml\'):将本地的文件内容加载到该对象中进行数据解析
网络
BeautifulSoup(page_text,\'lxml\'):将互联网上请求到的数据加载到该对象中进行数据解析
fp文件描述符 open函数的返回值
soup当前页面的对象活到当前页面的所有标签
find属性定位 也可以进行tagname的取值
关键字_=属性值 例如class 类声明 需要加下划线
不是关键字=属性值

取文本

string :只可以将标签中直系的文本取出
text:可以将标签中所有内容取出

取属性

tag[\'attrName\']

一些常用参数

from bs4 import BeautifulSoup
fp = open(\'./test.html\',\'r\',encoding=\'utf-8\')
soup = BeautifulSoup(fp,\'lxml\')
soup.p
soup.find(\'div\',class_=\'tang\')
soup.find(\'a\',id=\'feng\')
soup.find_all(\'div\',class_=\'tang\')
soup.select(\'#feng\')
soup.select(\'.tang > ul > li\')
soup.select(\'.tang li\')
tag = soup.title
tag.text
li_list = soup.select(\'.tang > ul > li\')
li_list[6].text
div_tag = soup.find(\'div\',class_=\'tang\')
div_tag.text
a_tag = soup.select(\'#feng\')[0]
a_tag[\'href\']

示例

from bs4 import BeautifulSoup
#爬取到首页的页面数据
main_url = \'http://www.shicimingju.com/book/sanguoyanyi.html\'
page_text = requests.get(main_url,headers=headers).text

fp = open(\'./sanguo.txt\',\'a\',encoding=\'utf-8\')

#解析章节名称+详情页的url
soup = BeautifulSoup(page_text,\'lxml\')
a_list = soup.select(\'.book-mulu > ul > li > a\')
for a in a_list:
    title = a.string#章节标题
    detail_url = \'http://www.shicimingju.com\'+a[\'href\']
    
    #爬取详情页的页面源码内容
    detail_page_text = requests.get(url=detail_url,headers=headers).text
    #解析章节内容
    detail_soup = BeautifulSoup(detail_page_text,\'lxml\')
    
    
    div_tag = detail_soup.find(\'div\',class_="chapter_content")
    
    
    content = div_tag.text #章节内容
    
    
    fp.write(title+\':\'+content+\'\n\')
    print(title,\'下载成功!!!\')
fp.close()

5.xpath(面试重点)

为什么xpath从0开始索引 cpu更好寻址
打印出来的实例化对象
返回的都是列表复数对象
#在xpath表达式中一定不可以出现tbody标签!!

5.1(扩展)补充参数

我们将在下面的例子中使用这个 XML 文档。

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>
5.1.1选取节点

XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。

下面列出了最有用的路径表达式:
表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。
实例

在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性。
5.1.2谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

实例

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符 描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。
实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式 结果
/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title[@*] 选取所有带有属性的 title 元素。
5.1.3选取若干路径 管道符

通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式 结果
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
//title | //price 选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

5.2xpath入门

1.环境的安装:
pip install lxml
2.解析原理
实例化一个etree的对象,将解析的数据加载到该对象中
需要调用etree对象中的xpath方法结合着不同的xpath表达式进行标签定位和文本数据的提取

3.etree对象的实例化
etree.parse(\'filePath\'):将本都数据加载到etree中
etree.HTML(page_text):将互联网上的数据加载到该对象中
4.其他
html中所有的标签都是遵从了树状的结构,便于我们实现高效的节点的遍历或者查找(定位)
etree遵从了树状存储结构
xpath方法的返回值一定是复数(列表)
5.参数
#1.标签定位
    最左侧的/:xpath表达式式一定要从根标签开始进行定位
    非最左侧的/:表示一个层级
    最左侧的//:从任意位置进行标签定位(常用)
    非最左侧//:表示多个层级
    //tagName:定位到所有的tagName标签
    属性定位://tagName[@attrName="value"]#定位对应属性为"value"属性值
    索引定位://tagName[index],index索引是从1开始
#2.模糊匹配:
//div[contains(@class, "ng")]
//div[starts-with(@class, "ta")]
#3.取文本
/text():取直系的文本内容。列表只有一个元素
//text():所有的文本内容。列表会有多个列表元素
#4.取属性
/@attrName
#5.逻辑运算:
    #找到href属性值为空且class属性值为du的a标签
    //a[@href="" and @class="du"]
from lxml import etree
tree = etree.parse(\'./test.html\')
# 创建etree对象进行制定数据解析# 解析本地文件

"""进行本地文件的创建"""
tree.xpath(\'/html/head/meta\')
tree.xpath(\'/html//meta\')
tree.xpath(\'//meta\')
tree.xpath(\'//div\')
tree.xpath(\'//div[@class="tang"]\')
tree.xpath(\'//li[1]\')
tree.xpath(\'//a[@id="feng"]/text()\')[0]
tree.xpath(\'//div[2]//text()\')
tree.xpath(\'//a[@id="feng"]/@href\')

// 是相对定位 进行占位

6.实例化对象
url = \'路径\'
page_text = requests.get(url=url,headers=headers).text#取出text信息
#数据解析
tree = etree.HTML(page_text)
6.1.使用本地
etree.parse(\'filePath\'):将本都数据加载到etree中
6.2.使用网络
etree.HTML(page_text):将互联网上的数据加载到该对象中
7.全局解析
7.1知识点
tree.xpath(\'//a[@id="feng"]/text()\')[0]
tree.xpath(\'//div[2]//text()\')
tree.xpath(\'//a[@id="feng"]/@href\')

7.2示例使用
li_list = tree.xpath(\'//div[@class="box-bd"]/ul/li\')
8.局部解析 ./ 当前标签
8.1知识点
./表示当前标签
./a[2]表示当前标签下面索引为2的标签
./@href 当前标签的属性
8.2示例使用
url = \'https://www.huya.com/g/lol\'
page_text = requests.get(url=url,headers=headers).text
#数据解析
tree = etree.HTML(page_text)
li_list = tree.xpath(\'//div[@class="box-bd"]/ul/li\')
for li in li_list:
    #实现局部解析:将局部标签下指定的内容进行解析
    #局部解析xpath表达式中的最左侧的./表示的就是xpath方法调用者对应的标签
    title = li.xpath(\'./a[2]/text()\')[0]
    hot = li.xpath(\'./span/span[2]/i[2]/text()\')[0]
    detail_url = li.xpath(\'./a[1]/@href\')[0]
    print(title,hot,detail_url)
9.管道符
9.1知识点
|管道符 选取若干路径
1.可以同时允许
2.可以管道符左右都允许 
用于提高xpath兼容性,提升查询效率 
9.2示例
from lxml import etree
headers = {
    \'User-Agent\':\'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36\'
}
url = \'https://www.aqistudy.cn/historydata/\'
page_text = requests.get(url,headers=headers).text

tree = etree.HTML(page_text)
# hot_cities = tree.xpath(\'//div[@class="bottom"]/ul/li/a/text()\')
all_cities = 
tree.xpath(\'//div[@class="bottom"]/ul/div[2]/li/a/text() | //div[@class="bottom"]/ul/li/a/text()\')
all_cities

5.3xpath示例

需求:爬取解析虎牙中直播的房间名称,热度,详情页的url

from lxml import etree
headers = {
    \'User-Agent\':\'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36\'
}
url = \'https://www.huya.com/g/lol\'
page_text = requests.get(url=url,headers=headers).text
#数据解析
tree = etree.HTML(page_text)
li_list = tree.xpath(\'//div[@class="box-bd"]/ul/li\')
for li in li_list:
    #实现局部解析:将局部标签下指定的内容进行解析
    #局部解析xpath表达式中的最左侧的./表示的就是xpath方法调用者对应的标签
    title = li.xpath(\'./a[2]/text()\')[0]
    hot = li.xpath(\'./span/span[2]/i[2]/text()\')[0]
    detail_url = li.xpath(\'./a[1]/@href\')[0]
    print(title,hot,detail_url)

音频输入

百度AI的使用

1.注册百度AI账号
下载
如果已安装pip,执行pip install baidu-aip即可。
如果已安装setuptools,执行python setup.py install即可。

from aip import AipSpeech

""" 你的 APPID AK SK """
APP_ID = \'你的 App ID\'
API_KEY = \'你的 Api Key\'
SECRET_KEY = \'你的 Secret Key\'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

result  = client.synthesis(\'你好百度\', \'zh\', 1, {
    \'vol\': 5,
})

# 识别正确返回语音二进制 错误则返回dict 参照下面错误码
if not isinstance(result, dict):#result 音频文件
    with open(\'auido.mp3\', \'wb\') as f:
        f.write(result)

html存储音频

<audio controls>
  <source src="horse.ogg" type="audio/ogg">
  <source src="horse.mp3" type="audio/mpeg">
</audio>

视频的爬取

动态加载

1.如果没有加载此视频将是一个图片

2.根据js发送请求此视频变为一个视频

3.使用re正则进行匹配选取 准确定位到指定的属性


常用数据解析的分析

bs4的标签定位:返回值一定是定位到的标签

bs4参数

标签定位:返回值一定是定位到的标签
soup.tagName:定位到第一个出现的tagName标签.返回的是单数
属性定位:soup.find(\'tagName\',attrName=\'value\'),返回的是单数
find_all(\'tagName\',attrName=\'value\')返回的是复数(列表)
选择器定位:select(\'选择器\'),返回的也是一个列表
层级选择器:
大于号:表示一个层级
空格:标识多个层级
取文本
string:只可以将标签中直系的文本取出
text:可以将标签中所有的内容取出
取属性
tag[\'attrName\']
from bs4 import BeautifulSoup
fp = open(\'./test.html\',\'r\',encoding=\'utf-8\')
soup = BeautifulSoup(fp,\'lxml\')
soup.p
soup.find(\'div\',class_=\'tang\')
soup.find(\'a\',id=\'feng\')
soup.find_all(\'div\',class_=\'tang\')
soup.select(\'#feng\')
soup.select(\'.tang > ul > li\')
soup.select(\'.tang li\')
tag = soup.title
tag.text
li_list = soup.select(\'.tang > ul > li\')
li_list[6].text
div_tag = soup.find(\'div\',class_=\'tang\')
div_tag.text
a_tag = soup.select(\'#feng\')[0]
a_tag[\'href\']

xpath返回值一定是列表(复数)的实例化对象

#1.标签定位
    最左侧的/:xpath表达式式一定要从根标签开始进行定位
    非最左侧的/:表示一个层级
    最左侧的//:从任意位置进行标签定位(常用)
    非最左侧//:表示多个层级
    //tagName:定位到所有的tagName标签
    属性定位://tagName[@attrName="value"]#定位对应属性为"value"属性值
    索引定位://tagName[index],index索引是从1开始
#2.模糊匹配:
//div[contains(@class, "ng")]
//div[starts-with(@class, "ta")]
#3.取文本
/text():取直系的文本内容。列表只有一个元素
//text():所有的文本内容。列表会有多个列表元素
#4.取属性
/@attrName
#5.逻辑运算:
    #找到href属性值为空且class属性值为du的a标签
    //a[@href="" and @class="du"]
from lxml import etree
tree = etree.parse(\'./test.html\')本地
tree.xpath(\'/html/head/meta\')
tree.xpath(\'/html//meta\')
tree.xpath(\'//meta\')
tree.xpath(\'//div\')
tree.xpath(\'//div[@class="tang"]\')
tree.xpath(\'//li[1]\')
tree.xpath(\'//a[@id="feng"]/text()\')[0]
tree.xpath(\'//div[2]//text()\')
tree.xpath(\'//a[@id="feng"]/@href\')
re xpath bs4
模块安装 内置 第三方 第三方
语法 正则 路径匹配 面向对象
使用级别 困难 较困难 简单
性能(处理速度) 最高 适中 最低

9.编码问题总结

1.修改响应头

import requests
url = \'https://www.sogou.com/web?query=人民币\'
response = requests.get(url)
#修改响应数据的编码格式
response.encoding = \'utf-8\'#进行编码转义
page_text = response.text
with open(\'./人民币.html\',\'w\',encoding=\'utf-8\') as fp:
    fp.write(page_text)

2.修改单个数据

 img_name.encode(\'iso-8859-1\').decode(\'gbk\')

使用xpath

#url模板
url = \'http://pic.netbian.com/4kmeinv/index_%d.html\'
for page in range(1,11):
    new_url = format(url%page) #只可以表示非第一页的页码连接
    if page == 1:
        new_url = \'http://pic.netbian.com/4kmeinv/\'
    page_text = requests.get(new_url,headers=headers).text
    tree = etree.HTML(page_text)
    li_list = tree.xpath(\'//*[@id="main"]/div[3]/ul/li\')
    for li in li_list:
        img_name = li.xpath(\'./a/img/@alt\')[0]+\'.jpg\'
        img_name = img_name.encode(\'iso-8859-1\').decode(\'gbk\')
        img_src = \'http://pic.netbian.com\'+li.xpath(\'./a/img/@src\')[0]
        print(img_name,img_src)

牛巴巴查看视频

版权声明:本文为strawberry-1原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/strawberry-1/articles/12008586.html