| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Python知识库 -> python爬虫学习笔记之数据提取 -> 正文阅读 |
|
[Python知识库]python爬虫学习笔记之数据提取 |
参考博客:python爬虫学习笔记_fdk少东家的博客-CSDN博客1、XPath语法和lxml库1.01、什么是XPath?
1.02、XPath工具
1.03、XPath语法:选取节点: XPath使用路径表达式来选取XML文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
谓语: 谓语用来查找某个特定节点或者包含某个指定的值的节点,被嵌套在方括号中。 在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
?通配符:
选取多个路径: 通过在路径表达式中使用 示例如下:
运算符:
lxml是一个HTML/XML的解析器,主要的功能是如何解析和提取HTML/XML数据。 lxml和正则一样,也是用C实现的,是一款高性能的Python HTML/XML解析器,我们可以利用之前学习的XPath语法,来快速定位特定元素以及节点信息。 lxml python官方文档:lxml - Processing XML and HTML with Python 需要安装C语言库,可使用pip install lxml。 我们可以利用他来解析HTML代码,并且在解析HTML代码的时候,如果HTML代码不规范,他会自动的进行补全。示例代码如下: 从字符串中读取HTML代码:
从文件中读取HTML代码: 假设存在一个hello.html文件。利用
注意:? 1.05、在lxml中使用XPath语法:1.获取所有li标签:
2.获取所有li元素下的所有class属性的值:
3.获取li标签下href为
4.获取li标签下href为
注意事项: 1.使用
2.获取文本,是通过
3.在某个标签下,再执行
2、
|
解析工具 | 解析速度 | 使用难度 |
---|---|---|
BeautifulSoup | 最慢 | 最简单 |
lxml | 快 | 简单 |
正则 | 最快 | 最难 |
Beautiful Soup
将复杂HTML
文档转换成一个复杂的树形结构,每个节点都是python
对象,所有对象都可以归纳为4种:
Tag
:BeautifulSou
中所有的标签都是Tag
类型,并且BeautifulSou
的对象其实本质上也是一个Tag
类型。所以其实一些方法比如:find
、find_all
并不是BeautifulSou
的,而是Tag
的。NavigatableString
:继承自python
中的str
,用起来和str一样。BeautifulSouP
:继承自Tag
。用来生成BeautifulSou
树的。对于一些查找方法,比如:find
、select
这些,其实还是Tag
的。Comment
:继承自NavigableString
。通俗点讲就是HTML
中的一个个的标签
soup = BeautifulSoup(html,'lxml')
table = soup.find('table')
print(type(table))
我们可以利用soup
加标签名轻松的获取这些标签的内容,这些对象的类型是bs4.element.Tag
。但是注意,他查找的是在所有内容中的第一个符合条件的要求的标签。如果要查询所有的标签,后面会进行介绍。
Tag
有两个重要的属性,分别为name
和attrs
。
print(soup.name)
# [document] # soup对象本身比较特殊,他的name即为[document]
print(soup.head.name)
# head #对于其他内部标签,输出的值为标签本身的名称。
print(soup.p.attrs)
#{'class':['title'],'name':'dromouse'}
#在这里,我们把p标签的所有属性打印输出,得到的类型是个字典
print(soup.p['class']) #soup.p.get('class)
# ['title'] #还可以利用get方法,传入属性的名称,二者等价。
soup.p['class'] = "newClass"
print(soup.p) #还可以对这些属性和内容进行修改
如果拿到标签后,还想获取标签中的内容。那么可以通过tag.string
获取标签中的文字。
print(soup.p.string)
# The Document's story
print(type(soup.p.string))
# <class 'bs4.element.NavigableString'>thon
BeautifulSoup
对象表示的是一个文档的全部内容,大部分时候,可以把它当作Tag
对象,它支持遍历文档树和搜索文档树中描述的大部分方法。
因为BeautifulSoup
对象并不是真正的HTML
和XML
的Tag
,所以它没有name
和attribute
属性,但有时查看它的name
属性是很方便的。所以BeautifulSoup
对象包含了一个值为'[document]'
的特殊属性.name
。
soup.name
# '[document]'
Tag
、NavigableString
、BeautifulSoup
几乎覆盖了html
和xml
中所有的内容,但是还有一些特殊对象,容易让人担心内容是文档的注释部分:
markup = "<b><!--Hey,buddy.want to buy a used parser?--></b>"
soup = BeautifulSoup(markup)
comment = soup.b.string
print(type(comment))
# <class 'bs4.element.Comment'>
Comment
对象是一个特殊类型的NavigableString
对象。
搜索文档书,一般用的比较多的方法就是两个方法,一个是find,一个是find_all。find方法是找到第一个满足条件的标签后立即返回,只返回一个元素。find_all方法是把所以满足条件的表签都返回。
实例演示:
1.获取所有tr标签
trs = soup.find_all('tr')
for tr in trs:
print(tr)
2.获取第二个tr标签
tr = soup.find_all('tr',limit=2)[1]
3.获取所有class等于even的tr标签
trs = soup.find_all('tr',attrs={'class':'even'})
for tr in trs:
print(tr)
4.将所有id等于test,class也等于test的a标签提取出来。
aList = soup.find_all('a',id='test',class='test')
# 也可以使用attrs属性选择
for a in aList:
print(a)
5.获取所有a标签的href属性
aList = soup.find_all('a')
for a in aList:
# 1.通过下标操作的方式
print(a['href'])
# 2.通过attrs属性的方式
print(a.attrs['href'])
6.获取所有职位信息(纯文本)
trs = soup.find_all('tr')[1:]
zhiwei = {}
for tr in trs:
# tds = tr.find_all('td')
# title = tds[0].string
# city = tds[1].string
# zhiwei['title'] = title
# zhiwei['city'] = city
infos = list(tr.stripped_strings)
zhiwei['title'] = infos[0]
zhiwei['city'] = infos[1]
print(zhiwei)
使用以上方法可以方便的找出元素,但有时候使用css选择器的方法可以更加方便。使用css选择器的语法,应该使用select方法。一下列出几种常用的css选择器方法:
1.通过标签名查找:
print(soup.select('a'))
2.通过类名查找:
通过类名查找,则应该在类名前面加一个.
。比如查找class=sister
的标签。
tg = soup.select('.sister')
3.通过id查找:
通过id查找,一个在id名字前面加#
号。
print(soup.select('#idname'))
?4.组合查找:
组合查找即和写class文件时,标签名与类名、id名进行组合原理一样,例如查找p标签中,id等于link1的内容,二者需要用空格分开:
print(soup.select('p #link1'))
直接子标签查找,这使用>
分隔:
print(soup.select('head>title'))
5.通过属性查找:
查找时还可以加入属性元素,属性需要用中括号括起来,注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到。
print(soup.select('a[href="http://example.com/elsie"]'))
6.获取内容
soup = BeautifulSoup(html,'lxml')
print(type(soup.select('title')))
print(soup.select('title')[0].get_text())
for title in soup.select('title'):
print(title.get_text())
attrs
属性,将所有的属性以及对于的值房子啊一个字典中传给attrs
属性。limit
参数。进行限制。# 1.通过下标操作的方式
print(a['href'])
# 2.通过attrs属性的方式
print(a.attrs['href'])
返回某个标签下的直接子元素。其中也包括字符串。他们的区别是:contents
返回的是一个列表,children
返回的是一个迭代器。
soup = BeautifulSoup(html,'lxml')
head_tag = soup.head
# 返回所有的子节点的列表
print(head_tag.contents)
# 返回所有的子节点的迭代器
for child in head_tag.children:
print(child)
如果tag
中包含多个字符串,可以使用.strings
来循环获取:
for string in soup.strings:
print(string)
什么是正则表达式(通俗理解):按照一定的规则,从某个字符串中匹配出想要的数据。这个规则就是正则表达式。
###3.01、正则表达式符号:
1.[]
:
2.^
:
3.$
:
?4.\
:
1.反斜杠后面可以加不同的字符以表示不同的特殊意义。
也可以用于取消所有的元字符,即当转义字符。
符号 | 含义 |
---|---|
. | 匹配除’\n’之外的任何单个字符,如果要匹配包括’\n’在内的任何字符,使用‘[.\n]’ |
\d | 匹配任何十进制数,相当于类[0-9] |
\D | 匹配任何非数字字符;相当于类[ ^0-9] |
\s | 匹配任何空白字符,相当于类[\t\n\r\f\v] |
\S | 匹配任何非空白字符,相当于类[ ^\t\n\r\f\v] |
\w | 匹配任何字母数字字符,相当于类[a-zA-Z0-9_] |
\W | 匹配任何非字母数字字符,相当于类[ ^a-zA-Z0-9_] |
5. 重复:
6.*
:
?7.+
:
?8.?
:
?9.{m,n}
:
?10.()
分组:
()
来进行多种正则的选择。匹配时优先返回分组的值。?11.|
:
1.匹配某个字符串:
text = 'hello'
ret = re.march('he',text)
print(ret.group())
>>he
以上便可以在hello
中,匹配出he
。
在正则表达式中,有些字符串是有特殊意义的字符。因此如果想要匹配这些字符,那么就必须使用反斜杠进行转义。比如$
代表的是以…结尾,如果想要匹配$
,那么就必须使用\$
。
text = 'apple price is \$99,orange is $88'
ret = re.search('\$(\d+)',text)
print(ret.group())
>>$99
原生字符串:
在正则表达式中,\
是专门用来转义的。在python
中\
也是用来转义的。因此如果想要在普通字符串中匹配出\
,那么要给出4个\
。
text = 'apple \c'
ret = re.search('\\\\c',text)
print(ret.group())
因此要使用原生字符串就可以解决这个问题:
text = 'apple \c'
ret = re.search(r'\\c',text)
print(ret.group())
re.compile()
函数compile函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
语法格式为:re.compile(pattern[, flags])
pattern:一个字符串形式的正则,字符串前加r
,反斜杠就不会被当作转义字符。
flags:可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数如下:
符号 | 含义 |
---|---|
re.I | 忽略大小写 |
re.L | 表示特殊字符集\w, \W, \b, \B, \s, \S 依赖于当前环境 |
re.M | 多行模式 |
re.S | 即为. 并且包括换行符在内的任意字符(单纯的. 不包括换行符) |
re.U | 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库 |
re.X | 为了增加可读性,忽略空格和 # 后面的注释 |
方法/属性 | 作用 |
---|---|
match() | 在字符串刚开始的位置匹配,如果想要匹配换行符,传入一个flags=re.DOTALL 就可以了。 |
search() | 扫描字符串,找到这个RE匹配的位置 |
findall() | 找到RE匹配的所有子串,并把它们作为一个列表返回 |
finditer() | 找到RE匹配的所有子串,并把它们作为一个迭代器返回 |
如果没有匹配到,match()和search()将返回None,如果成功,返回一个‘MatchObject’实例 。
MatchObject实例方法(即匹配成功后使用的方法):
方法/属性 | 作用 |
---|---|
group() | 返回被RE匹配的字符串。 |
start() | 返回匹配开始的位置。 |
end() | 返回匹配结束的位置 |
span() | 返回一个元组包含匹配(开始,结束) |
在正则表达式中,可以对过滤到的字符串进行分组。分组使用()
。
group
:和group(0)
是等价的,返回的是整个满足条件的字符串。groups
:返回的是里面的子组。索引从1开始。group(1)
:返回的是第一个子组,可以传入多个。实例如下:
text = 'apple price is $99,orange price is $10'
ret = re.search(r'.*(\$\d+).*(\$\d+)',text)
print(ret.group())
print(ret.group(0))
print(ret.group(1))
print(ret.group(2))
print(ret.groups())
从开始的位置进行匹配。如果开始的位置没有匹配到,直接报错。
text = 'hello'
ret = re.match('h',text)
print(ret.group())
>>h
如果第一个字母不是h
,那么就会失败。
text = 'ahello'
ret = re.match('h',text)
print(ret.group())
>>AttributeError:'NoneType' object has no attribute 'group'
如果想要匹配换行的数据,那么就要传入一个flag=re.DOTALL
,就可以匹配换行符了。
text = 'abc\nabc'
ret = re.match('abc.+abc',text,re.DOTALL)
print(ret.group())
在字符串中找满足条件的字符。如果找到了,就返回。只会返回第一个满足条件的。
text = 'apple price is $99,orange price is $88'
ret = re.search('\d+',text)
print(ret.group())
>>99
找出满足条件的,返回的是一个列表。
text = 'apple price is $99,orange price is $88'
ret = re.search('\d+',text)
print(ret.group())
>>['99','88']
re模块提供了re.sub()用于替换字符串中的匹配项。
语法:re.sub(pattern,repl,string,count=0,flags=0)
参数:
返回结果比re.sub()多了一个替换次数。
split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
re.split(pattern, string[, maxsplit=0, flags=0])
pattern:匹配的正则表达式
string:要匹配的字符串
maxsplit:分割次数,maxsplit=1分割一次,默认为0,不限次数。
import re
s = '123+456-789*111'
re.split(r'[\+\-\*]',s)
>['123','456','789','111']
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/16 2:35:19- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |