02 爬虫数据解析之re,xpath,beautifulsoup
一.正则匹配
简单用法演示:
字符:
print(re.findall(".","abccc31223dn哈哈")) ### . 匹配除了换行符以外的任意字符,搭配re.S可搭配任意字符(包括空行)#['a', 'b', 'c', 'c', 'c', '3', '1', '2', '2', '3', 'd', 'n', '哈', '哈']
print(re.findall("ab[c,d]f","ab,f")) #匹配集合中任意一个字符,注意逗号不是分隔符,[]不需要分隔符
print(re.findall("ab\df","ab5f")) #数字[0 - 9]
print(re.findall("ab\Df","ab5f")) #非数字 结果为[]
print(re.findall("ab\wf","ab_f")) #数字、字母、下划线、中文 结果:['ab_f']
print(re.findall("ab\Wf","ab$f")) #非\w也就是非(数字、字母、下划线、中文 ) 结果为:['ab$f']
print(re.findall("ab\sf","ab f")) # 所有的空白字符包,括空格、制表符、换页符等等 结果为:['ab f']
print(re.findall("ab\Sf","ab f")) # \S 非空白 结果为:[] 量词:
print(re.findall("abc*","abccc")) #['abccc'] 任意多次 >=0 贪婪匹配
print(re.findall("abc?","abccc")) #['abc'] 可有可无 0次或者1次 惰性匹配
print(re.findall("abc+","ab")) #至少1次 >=1 没有匹配不成功
print(re.findall("abc{3}","abcc")) #固定m次 不够匹配不成功,超过了m个剩下的字符不要
print(re.findall("abc{3,}","abccccc")) #至少m次 不够匹配不成功,超过了m个剩下的字符全要
print(re.findall("abc{3,5}","abccccccc")) #固定3-5次不够匹配不成功,超过3-5的字符不要 边界:
print(re.findall("^(.*?)c$","abccdsac")) #: 以某某结尾
print(re.findall("^a(.*?)$","abccdsac")) #: 以某某开头 分组:(ab)
贪婪模式: .*
非贪婪(惰性)模式: .*? re.I : 忽略大小写
re.M :多行匹配
re.S :单行匹配 re.sub(正则表达式, 替换内容, 字符串)
二.Xpath
如何使用xpath?
1.下载:pip install lxml
2.导包:from lxml import etree 3.将html文档或者xml文档转换成一个etree对象,然后调用对象中的方法查找指定的节点 2.1 本地文件:tree = etree.parse(文件名)
tree.xpath("xpath表达式") 2.2 网络数据:tree = etree.HTML(网页内容字符串)
tree.xpath("xpath表达式")
xpath用法展示参考如下:
1.文档文件
# 文本:
doc='''
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>测试bs4</title>
</head>
<body>
<div>
<p>百里守约</p>
</div>
<div class="song">
<p>李清照</p>
<p>王安石</p>
<p>苏轼</p>
<p>柳宗元</p>
<a href="http://www.song.com/" title="赵匡胤" target="_self">
<span>this is span</span>
宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
<a href="" class="du">总为浮云能蔽日,长安不见使人愁</a>
<img src="http://www.baidu.com/meinv.jpg" alt="" />
</div>
<div class="tang">
<ul>
<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
<li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
<li><a href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
<li><a href="http://www.sina.com" class="du">杜甫</a></li>
<li><a href="http://www.dudu.com" class="du">杜牧</a></li>
<li><b>杜小月</b></li>
<li><i>度蜜月</i></li>
<li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>
</ul>
</div>
</body>
</html>
'''
2.xpath查询实例
from lxml import etree
etree.parse("github.html") #用于打开文件 parse
tree=etree.HTML(doc) #打开HTML文档 用.HTML即可 注意在使用xpath,方法是 // 代表打开的整个文档 /代表下一级
属性定位:
找到class属性值为song的div标签
ret = tree.xpath("//div[@class='song']") 层级&索引定位:
找到class属性值为tang的div的直系子标签ul下的第二个子标签li下的直系子标签a的网址
ret = tree.xpath("//div[@class='tang']/ul/li[2]/a/@href")
print(ret) 逻辑运算:
#找到href属性值为空且class属性值为du的a标签
ret = tree.xpath('//a[@class="du" and @href=""]')
print(ret) 模糊匹配:
查找属性title包含ng的a标签的内容
ret = tree.xpath('//a[contains(@title,"ng")]/text()') #注意:在contains和starts-with 中@xx和格式是以逗号,分开的
print(ret)
查找属性title以qin开始的a标签的内容
ret=tree.xpath("//a[starts-with(@title,'qin')]/text()")
print(ret) 取文本:
# /表示获取某个标签下的文本内容
# //表示获取某个标签下的文本内容和所有子标签下的文本内容 ret = tree.xpath('div[@class="song"]/p[1]/text()')
ret = tree.xpath('div[@class="tang"]//text()') 取属性:
ret = tree.xpath('div[@class="tang"]//li[2]/a/@href')
三:Beautifulsoup(BS)
概念:简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:
'''
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
'''
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.你可能在寻找 Beautiful Soup3 的文档,Beautiful Soup 3 目前已经停止开发,官网推荐在现在的项目中使用Beautiful Soup 4。
解析器:
Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装。
下面具体介绍BS的语法以及相应操作:
1.使用流程
- 导包:from bs4 import BeautifulSoup
- 使用方式:可以将一个html文档,转化为BeautifulSoup对象,然后通过对象的方法或者属性去查找指定的节点内容
(1)转化本地文件:
- soup = BeautifulSoup(open('本地文件'), 'lxml')
(2)转化网络文件:
- soup = BeautifulSoup('字符串类型或者字节类型', 'lxml')
(3)打印soup对象显示内容为html文件中的内容
2.基本方法总结:
(1)根据标签名查找
- soup.a 只能找到第一个符合要求的标签
(2)获取属性
- soup.a.attrs 获取a所有的属性和属性值,返回一个字典
- soup.a.attrs['href'] 获取href属性
- soup.a['href'] 也可简写为这种形式
(3)获取内容
- soup.a.string
- soup.a.text
- soup.a.get_text()
【注意】如果标签还有标签,那么string获取到的结果为None,而其它两个,可以获取文本内容
(4)find:找到第一个符合要求的标签
- soup.find('a') 找到第一个符合要求的
- soup.find('a', title="xxx")
- soup.find('a', alt="xxx")
- soup.find('a', class_="xxx")
- soup.find('a', id="xxx")
(5)find_all:找到所有符合要求的标签
- soup.find_all('a')
- soup.find_all(['a','b']) 找到所有的a和b标签
- soup.find_all('a', limit=2) 限制前两个
(6)根据选择器选择指定的内容
select:soup.select('#feng')
- 常见的选择器:标签选择器(a)、类选择器(.)、id选择器(#)、层级选择器
- 层级选择器:
div .dudu #lala .meme .xixi 下面好多级
div > p > a > .lala 只能是下面一级
【注意】select选择器返回永远是列表,需要通过下标提取指定的对象
3.基本方法示例:
from bs4 import BeautifulSoup
soup=BeautifulSoup(html_doc,"lxml")
查找第一个a标签对象
print(soup.a)
print(type(soup.a)) # 查找到的标签类型为:<class 'bs4.element.Tag'> 是一个标签对象 ################################################## 一 Tag对象的操作 ###################################################
------------------->> 属性操作
print(soup.a.attrs) #返回一个字典 结果:{'href': 'http://example.com/elsie', 'class': ['sister'], 'id': 'link1'}
print(soup.a.attrs["href"]) #结果为:http://example.com/elsie
print(soup.a.attrs["class"]) #结果为:['sister']
print(soup.a.attrs.get("id")) #结果为:link1
建议取法:
print(soup.a["href"]) # http://example.com/elsie ------------------->> 文本操作
print(soup.a.text) # Elsie
print(soup.a.get_text()) # Elsie #text和get_text() 取得的结果是一样的.调用方式不一样而已
print(soup.a.string) # Elsie #注意:text和string正常情况下取得的结果是一样,但取得的标签内含有多个标签取内容时:text全部取出 string不取
print(soup.p.text) # The Dormouse's story123
print(soup.p.string) # None
4.有关find_all和all,以及selector的具体使用
# 两个重要的搜索方法:find,find_all()
################################################ 二 find,find_all()########################################### #------------------------------>> 2.1 find_all()
# 1.取出文本中所有a标签,并循环打印连接和属性
# for link in soup.find_all("a"):
# print(link["href"],link['class'])
'''
#结果为:
http://example.com/elsie ['sister']
http://example.com/lacie ['sister']
http://example.com/tillie ['sister']
''' #相应参数: find_all(self, name=None, attrs={}, recursive=True, text=None,limit=None, **kwargs): #------------------>> 2.1.1 name参数:name的五种过滤器: 字符串、正则表达式、列表、True、方法
#1.1、字符串:即标签名
# print(soup.find_all("a")) # name="a" #1.2、正则表达式
# import re
# print(soup.find_all(re.compile('^p'))) #找出p开头的标签,结果有body和b标签 '''
知识补充:re.compile()在正则表达式中的应用
cd = re.compile('abc{2}')
ret = re.findall(cd,"abccc")
print(ret) ''' #1.3、列表:如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有<a>标签和<b>标签:
# print(soup.find_all(["a","b"])) # name=["a","b"] 查找a标签和b标签 #1.4、True:可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
# print(soup.find_all(True))
# for tag in soup.find_all(True):
# print(tag.name) #1.5、方法:如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
# def has_class_but_no_id(tag):
# return tag.has_attr('class') and not tag.has_attr('id')
# print(soup.find_all(has_class_but_no_id)) #------------------>> 2.1.2 属性参数 attrs={}
# print(soup.find_all("a",attrs={"class":"sister","id":"link2"}))
# print(soup.find_all("a",id="link2"))
# print(soup.find_all("a",class_="sister")) #因为class是关键字,需要查找的话在class加下划线,形式为:class_ #------------------>> 2.1.3 文本参数
# print(soup.find_all("a",text="Elsie")) #------------------>> 2.1.4 limit参数
# print(soup.find_all("a",limit=2)) #limit主要限制查找的条数 #------------------>> 2.1.5 recursive参数
#recursive:调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,
# 如果只想搜索tag的直接子节点,可以使用参数 recursive=False . # print(soup.find_all("div",recursive=False)) ##结果为[],因为第一层没有div
# print("----------------")
# print(soup.body.find_all("div",recursive=False)) #有结果 因为当前层为body 也就是说只找第一层,下面的层次不管有没有都不会去找了 # 局部查找
# print(soup.div.find_all(recursive=False)) ##只找div的子标签,子孙标签不管 ################################################ 2.2 find() # print(soup.find("a")) # 等同于 soup.a
# find参数和find_all完全一样,但find只找一个标签 ################################################ 三 selector ################################################## # 这个selector等同于css选择器 # print(soup.select(".sister"))
# print(soup.select("#link2"))
# print(soup.select(".c1 a"))
详细请参考:https://www.cnblogs.com/pyedu/p/10303283.html
02 爬虫数据解析之re,xpath,beautifulsoup的更多相关文章
- python爬虫的页面数据解析和提取/xpath/bs4/jsonpath/正则(1)
一.数据类型及解析方式 一般来讲对我们而言,需要抓取的是某个网站或者某个应用的内容,提取有用的价值.内容一般分为两部分,非结构化的数据 和 结构化的数据. 非结构化数据:先有数据,再有结构, 结构化数 ...
- python爬虫--数据解析
数据解析 什么是数据解析及作用 概念:就是将一组数据中的局部数据进行提取 作用:来实现聚焦爬虫 数据解析的通用原理 标签定位 取文本或者属性 正则解析 正则回顾 单字符: . : 除换行以外所有字符 ...
- 070.Python聚焦爬虫数据解析
一 聚焦爬虫数据解析 1.1 基本介绍 聚焦爬虫的编码流程 指定url 基于requests模块发起请求 获取响应对象中的数据 数据解析 进行持久化存储 如何实现数据解析 三种数据解析方式 正则表达式 ...
- 爬虫-数据解析-bs4
1.数据解析 解析: 根据指定的规则对数据进行提取 作用: 实现聚焦爬虫 数据解析方式: - 正则表达式 - bs4 - xpath 数据解析的通用原理: 数据解析需要作用在页面源码中(一组html标 ...
- python爬虫数据解析之BeautifulSoup
BeautifulSoup是一个可以从HTML或者XML文件中提取数据的python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. BeautfulSoup是python爬虫三 ...
- python爬虫的页面数据解析和提取/xpath/bs4/jsonpath/正则(2)
上半部分内容链接 : https://www.cnblogs.com/lowmanisbusy/p/9069330.html 四.json和jsonpath的使用 JSON(JavaScript Ob ...
- python爬虫数据解析的四种不同选择器Xpath,Beautiful Soup,pyquery,re
这里主要是做一个关于数据爬取以后的数据解析功能的整合,方便查阅,以防混淆 主要讲到的技术有Xpath,BeautifulSoup,PyQuery,re(正则) 首先举出两个作示例的代码,方便后面举例 ...
- 爬虫-数据解析-xpath
xpath 解析 模块安装 : pip install lxml xpath的解析原理 实例化一个etree类型的对象,且将页面源码数据加载到该对象中 需要调用该对象的xpath方法结合着不同形式的x ...
- Python网络爬虫数据解析的三种方式
request实现数据爬取的流程: 指定url 基于request发起请求 获取响应的数据 数据解析 持久化存储 1.正则解析: 常用的正则回顾:https://www.cnblogs.com/wqz ...
随机推荐
- luogu P2713 罗马游戏
思路 模拟就好 左偏树合并 并查集寻找 代码 #include <bits/stdc++.h> #define FOR(i,a,b) for(int i=a;i<=b;++i) us ...
- 洛谷1968美元汇率 dp
P1968 美元汇率 dp 题目描述 在以后的若干天里戴维将学习美元与德国马克的汇率.编写程序帮助戴维何时应买或卖马克或美元,使他从100美元开始,最后能获得最高可能的价值. 输入输出格式 输入格式: ...
- Java8 函数式接口-Functional Interface
目录 函数式接口: JDK 8之前已有的函数式接口: 新定义的函数式接口: 函数式接口中可以额外定义多个Object的public方法一样抽象方法: 声明异常: 静态方法: 默认方法 泛型及继承关系 ...
- Win10 快捷命令收集
桌面相关 Win+D:显示桌面 Win+Tab:虚拟桌面切换器 Win+Ctrl+D 新建桌面 Win+Ctrl+左/右 :移动虚拟桌面 Win+m :最小化窗口 Win键 + Ctrl + F4 关 ...
- SpringBoot 统一异常处理
统一异常处理: @ControllerAdvice public class GlobalExceptionHandler { private Logger logger = LoggerFactor ...
- Mysql的timestamp字段默认值设置问题
参考: https://www.cnblogs.com/mxwz/p/7520309.html https://www.jb51.net/article/50878.htm https://blog. ...
- P3273 [SCOI2011]棘手的操作
吐槽 上午风浔凌julao问我的神题 操作又多又毒瘤又棘手... 然后bzoj题号正好是2333,2333333333 思路 貌似只有我是这么写的 线段树合并, 每个线段树存每个连通块的信息,维护点的 ...
- Symbol在对象中的作用
Symbol的打印 我们先声明一个Symbol,然后我们在控制台输出一下. var g = Symbol('jspang'); console.log(g); console.log(g.toStri ...
- 测试常用的Linux命令总结
列出常用的命令和最常用的用法,排名不分先后:) 1. find在/home目录下查找以.txt结尾的文件名find /home -name "*.txt"同上,但忽略大小写find ...
- Qt实在太漂亮了
我很久之前就想用Qt,无奈对c++不熟悉,学习代价太大.想使用pyqt曲线救国,搞了好久的环境后放弃了.昨天又看了个很漂亮的qt例子,太漂亮了,让我很想进圈子.就从现在开始吧!!