Python学习

作者: 逛逛_堆栈 | 来源:发表于2021-04-20 17:09 被阅读0次

第二十七天

爬虫学习(二)

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)

相关文章

网友评论

    本文标题:Python学习

    本文链接:https://www.haomeiwen.com/subject/hghvlltx.html