第二十七天
爬虫学习(二)
1、回顾
网页解析器
python中常见的网页解析器:
1、正则表达式
2、python自带的html.parser
3、BeautifulSoup第三方模块
4、lxml模块
先来看下BeautifulSoup第三方模块网页解析器
2、BeautifulSoup网页解析器
BeautifulSoup网页解析器,是结构化解析,其实就是DOM树。并且Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为UTF-8编码。
2.1、BeautifulSoup安装
1、pip install beautifulsoup4安装;
2、使用工具安装;
2.2、BeautifulSoup4语法
1、创建BeautifulSoup对象
2、利用find、finda_all等方法按照节点名称、节点属性、节点文字搜索节点
3、进而可以访问节点名称、属性、文字等
from bs4 import BeautifulSoup
#网页字符串
html_doc = """
<html>
<head>
<title>BeautifulSoup测试</title>
</head>
<body>
<div>
<a href = 'http://www.baidu.com'>百度</a>
</div>
<div>
<a href = 'http://www.sougou.com'>搜狗</a>
</div>
</body>
</html>
"""
#1、根据Html网页字符串创建BeautifulSoup dom对象
soup = BeautifulSoup(
html_doc, # Html文档字符串
'html.parser', # Html默认解析器
from_encoding='utf-8' # Html文档编码
)
# find(name,attrs,string)
# 利用find、finda_all等方法按照节点名称、节点属性、节点文字搜索节点
links = soup.find_all('a')
# 访问节点名称、属性、文字等
for link in links:
print(link.name,link['href'],link.get_text())
当然也可以使用find方法获取某一个超链接。
link = soup.find('a',href = 'http://www.baidu.com')
print(link.name,link['href'],link.get_text())
在BeautifulSoup使用中,最厉害的是可以使用正则表达式。
link = soup.find('a',href = re.compile(r'bai'))
print(link.name,link['href'],link.get_text())
# a http://www.baidu.com 百度
2.3、第三方解析器的使用
Beautiful Soup 在解析时实际上依赖解析器,它除了支持 Python 标准库中的 HTML 解析器外,还支持一些第三方解析器,这里以lxml为例。
注意:使用lxml需要提前安装lxml。
html = """
<html><head><title>lxml</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title) # 获得网页title标签
print(type(soup.title)) # 获得类型
print(soup.title.string) # 获得网页标题
print(soup.p) # 获得第一个p标签
print(soup.p.name) # 获得第一个p标签标签名
print(soup.p.attrs['class']) # 获得第一个p标签class属性值
print(soup.p['class']) # 获得第一个p标签class属性值 简写
简单总结
1、获取标签名
soup.title.name
2、获得属性
soup.p.attrs['class']
soup.p['class']
3、获取内容
soup.p.string
soup.p.get_text()
4、嵌套选择
soup.head.title.string #获得网页标题
5、子节点和子孙节点
选取节点元素之后,如果想要获取它的直接子节点,可以调用 contents 属性;
html = """
<html><head><title>lxml</title></head>
<body>
<p class="p1">这是p标签
<a href="#" class="link" id="link1">第一个a标签
<span>第一个a标签下的span标签</span>
</a>
<a href="#" class="link" id="link2">第二个a标签</a>
<a href="#" class="link" id="link3">第三个a标签</a>
</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
children = soup.p.contents
print(children)
返回结果是列表形式。p 节点里既包含文本,又包含节点,最后会将它们以列表形式统一返回。
如果想要获得子孙节点,需要children属性
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
children = list(soup.p.children)
print(children)
6、父节点和祖先节点
获取某个节点元素的父节点,可以调用 parent 属性;
如果想获取所有的祖先节点,可以调用 parents 属性。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
link_span = soup.find('span',attrs=['class','link1_span1'])
print(link_span)
parent = link_span.parent
print(parent)
parents = link_span.parents
print(parents)
7、兄弟节点
next_sibling 和 previous_sibling 分别获取节点的下一个和上一个兄弟元素,next_siblings 和 previous_siblings 则分别返回所有前面和后面的兄弟节点的生成器。
2.4、方法选择器的使用
Beautiful Soup 还为我们提供了一些查询方法,来选择对应的元素,使用方法相对前面所说的属性应该更加的快捷。
find_all()方法
查询所有符合条件的元素。给它传入一些属性或文本,就可以得到符合条件的元素。
find_all(name , attrs , recursive , text , **kwargs)
1、根据节点名name来查询元素
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
links = soup.find_all(name='a')
for link in links:
print(link.get_text())
2、除了根据节点名查询,我们也可以传入一些属性attrs来查询
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
links = soup.find_all(name='a',attrs=['class','link'])
for link in links:
print(link.get_text())
3、text 参数可用来匹配节点的文本,传入的形式可以是字符串,可以是正则表达式对象。
from bs4 import BeautifulSoup
import re
soup = BeautifulSoup(html, 'lxml')
links = soup.find_all(text=re.compile('标签'))
for link in links:
print(link)
# 获得所有含有标签的文本
find()方法
find()方法的使用大体上同find_add()一样,只不过返回结果不再是列表形式,而是第一个匹配的节点元素。
其他方法
除了上述find_all()方法与find()方法外,还有其他的查询方法,例如
find_parent()方法、返回父节点
find_parents()方法、返回祖先节点
find_next_sibling()方法、返回第一个兄弟节点
find_next_siblings()方法、返回所有兄弟节点
find_previous_sibling()方法、返回上一个兄弟
find_previous_siblings()方法、返回所有前面兄弟
...
2.5、css选择器
Beautiful Soup 还提供了另外一种选择器,那就是 CSS 选择器,使用select方法,传入对应的css选择器即可。
from bs4 import BeautifulSoup
import re
soup = BeautifulSoup(html, 'lxml')
links = soup.select('.link') # 获得所有class=link的标签
for link in links:
print(link)
span = soup.select('#link1>span')[0]
print(span.string)
网友评论