python爬虫数据解析的三种方式
1.正则表达式
单字符:
. : 除换行以外所有字符
[] :[aoe] [a-w] 匹配集合中任意一个字符
\d : 数字 [0-9]
\D : 非数字
\w : 数字、字母、下划线、中文
\W : 非\w
\s : 所有的空白字符,包括空格、制表符、换页符等等. 等价于 [ \f\n\r\t\v]
\S : 非空白
数量修饰:
* :任意多次 >=0
+ : 至少一次 >=1
? : 可有可无 0次或者1次
{m} : 固定m次 hello{3}
{m,} : 至少m次
{m,n} :m-n次
边界:
$ : 以某某结尾
^ : 以某某开头
分组:
(ab)
贪婪模式: a.b尽可能重复多次,第一个a与最后一个b之间的元素全部被提取出来(包括a与b)
非贪婪(懒惰)模式 :a.?b 遇到一次停一次,ab之间不含任何元素,同样会被提取出来(包括a与b)
非贪婪(懒惰)模式 :a(.*?)b遇到一次停一次,只保留括号中的内容,ab之间不含任何元素,则提取''
re.I : 忽略大小写
re.M : 多行匹配
re.S : 单行匹配(爬虫中使用的都是单行匹配)
re.sub(正则表达式,替换内容,字符串)
2.bs4
-如何实例化BeautifulSoup对象:
-from bs4 import BeautifulSoup
-对象的实例化:
-1.将本地的html文档中的数据加载到该对象中
fp = open('./test.html', 'r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml')
-2.将互联网上获取的页面源码加载到该对象中
page_text = response.text
soup = BeautifulSoup(page_text,'lxml')
-提供的用于数据解析的方法和属性:
-soup.tagName: 返回的是文档中第一次出现的tagName对应的标签
-soup.find():
-find('tagName'):等同于soup.tagName
-属性定位:
-soup.find('div',class_/id/attr='song'):返回class/id/attr为song的div标签
-soup.find_all('tagName'):返回符合要求的所有标签(是一个列表)
-select:
-select('某种选择器(id,class,标签...选择器)'),返回的是一个列表
-层级选择器:
-soup.select('.tang > ul > li > a')[0]: >表示的是一个层级(返回该列表下的第一个元素)
-soup.select('.tang > ul a'):空格表示多个层级
-获取文本之间的标签数据:两个属性(text,string)一个方法(get_text() )
-soup.a.text/string/get_text()
-text/get_text() : 可以获取某一个标签中所有的文本内容
-string: 只可以获取该标签下面直系的文本内容
-获取标签中的属性值:
-soup.a.attrs['href']或soup.a['href'] 获取a的href属性
-soup.a.attrs:获取a所有的属性和属性值,返回一个字典
3.xpath(最常用且最便捷高效的一种解析方式)
-xpath解析原理:
-1.实例化一个etree对象,将需要被解析的页面源码数据加载到该对象中。
-2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获
-环境安装
-pip install lxml
-如何实例化一个etree对象: from lxlm import etree
-1.将本地的html文档中的源码加载到etree对象中
etree.parse(fileName)
-2.将互联网上获取的源码数据加载到该对象中
etree.HTML(page_text)
-xpath('xpath表达式')
-xpath表达式:
- /:最左边表示从根节点开始定位如(/html)
放在两个标签中间表示为一个层级,相当于BeautifulSoup中的 >
-//: 最左边表示从任意位置开始定位
放在两个标签之间表示多个层级,相当于BS中的空格
-属性定位://div[@class="song"] 直接定位到class为song的div标签(返回值为list类型)
-索引定位://div[@class="song"]/p[3] 定位到class为songdiv标签下的第3个p标签(返回值为list类型,且索引是从1开始的)
#只提取class为clearfix mt20 downlist的div下的ul下的第九个li标签,此时列表只有一个元素,直接用下述语句表示
li = new_tree.xpath('//div[@class="clearfix mt20 downlist"]/ul/li[9]')[0]
href = li.xpath('./a/@href')[0]
-取文本:
-/text() 获取的是标签中直系的文本内容
a/text() : 头条新闻
-//text() 过去的是标签中非直系的文本内容(该标签下所有的文本内容)
li/text() : None
li//text() :头条新闻
-取属性:
/@attrName href = li.xpath('./a/@href')[0] 取出该li标签下a标签的href属性,因为返回值是list类型,且只有一个元素,所以加0直接取出来