01 前言
经过前两篇的学习,现在手感正火热吧。
爬虫(一) – 带你了解爬虫最基本概念,一文即可实践
爬虫(二)–正则表达式
想要使用好爬虫,就需要很好的解析你所找到的代码,使用Beautiful Soup 4
,俗称BS4,可以轻松实现。
官方文档:https://beautifulsoup.readthedocs.io/zh_CN/latest/
02 BeautifulSoup库
2.1 概念及整体输出
BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库,一个分析HTML或XML文件的解析器。通常用来分析网页结构,抓取相应的Web文档。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,"html.parser")
print(soup.prettify())
soup.prettify()
将soup内容格式化输出,用BeautifulSoup 解析HTML文档时,它会将HTML文档类似DOM文档树
一样处理。
注意:假设HTML源码标签对是缺少结束标签的,即没有和标签,但是使用
prettify()
函数输出的结果可以自动补齐结束标签,这是BeautifulSoup的一个优点:BeautifulSoup即使得到了一个损坏的标签,它也产生一个转换DOM树,并尽可能和您原文档内容含义一致,这种措施通常能够帮助您更正确地搜集数据。
2.2 BeautifulSoup对象
BeautifulSoup官方文档将所有的对象归纳为以下四种:
Tag
:包括Name和Attributes,
#Name
print(tag.name) # 输出标签名
print(tag.string) # 输出标签的内容
#Attributes
print(tag.attrs) # 以键值对的方式输出标签的class和id
print(tag['class']) # 得到class的值
获得最初始的标签内容:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,"html.parser")
# 获取HTML的标题,包括自身标签全部输出
head = soup.head
print('头部:', head)
# 头部: <head><title>BeautifulSoup技术</title></head>
注意,这种直接.head的方式只能获得对应的第一个标签,想要获得所有的标签内容,还是需要后续学到的
finid_all()
函数。
NavigableString
实例:soup.a[‘class’].string,获得第一个遍历到的,具有class类的超链接标签内容。BeautifulSoup
BeautifulSoup对象表示的是一个文档的全部内容。
print(type(soup))
# <class 'BeautifulSoup.BeautifulSoup'>
Comment
Comment对象是一个特殊类型的NavigableString对象,它用于处理注释对象。
实例:
markup = "<b><!-- This is a comment code. --></b>"
soup = BeautifulSoup(markup, "html.parser")
comment = soup.b.string
print(comment)
2.3 得到html标签里面的内容的方法
1、已知想要获得的信息的具体位置,只得到一个内容
soup = BeautifulSoup(html)
# 方法一:获得第二个a标签下的内容,已知标签所在位置
print(soup.select('a')[1].string)
# 方法二,已知标签所在位置
print(soup.find('a').contents[1])
2、位置信息未知,只得到一个内容
# 或者,未知标签所在位置,只知道你要找的class,再利用正则表达式提取文字
dufu_text = soup.find('a', {'class': 'poet1'}).text
dufu_two_chars = re.search(r'(\S\S)', dufu_text).group(1)
print(dufu_two_chars) # 输出:杜甫的两个字“杜甫”
# 或者
dufu_text = soup.find('a', class_ = 'poet1')
print(dufu_text.text)
3、位置信息未知,得到所有内容
# 位置标签所在位置,使用find_all方法,必须使用列表遍历的方式输出
dufu_text = soup.find_all('a', class_ = 'poet1')
for dufu in dufu_text:
print(dufu.text)
4、想要得到超链接标签下的url
links = soup.find_all('a',class_ = 'poet1')
# 按照列表的形式取出
for link in links:
print(link.get('href'))
# 或者如下
for index, link in enumerate(links1):
href = link['href']
print(f"Index: {index}, Href: {href}")
2.4 最便捷语句find_all()详解
find_all()
函数是BeautifulSoup库中用于查找文档中所有符合条件的元素的函数。它可以接受多个参数,用于指定要搜索的元素的特定属性和属性值。下面是find_all()函数的参数详解:
name
参数:指定要搜索的标签名称或标签列表。可以是字符串或正则表达式对象。如果不指定此参数,则返回文档中的所有标签。
正则表达式:find_all(re.compile(“正则表达式”))
attrs
参数:指定要搜索的元素的属性和属性值。可以是字典类型或关键字参数。字典类型的键是属性名,值是属性值。如果关键字参数用于传递属性和属性值,则属性名称作为关键字,属性值作为值。
dufu_text = soup.find_all(‘a’, attrs = {‘class’: ‘poet1’})
-
recursive参数:指定是否在文档的子孙节点中递归搜索。默认值为True,表示递归搜索。如果设置为False,则只搜索文档的直接子节点。
-
string
参数:指定要搜索的元素的文本内容。可以是字符串或正则表达式对象。如果指定此参数,则只返回包含指定文本的元素。
soup.find_all(string=[“Tillie”, “Elsie”, “Lacie”])
-
limit参数:指定返回的结果数量的限制。默认值为None,表示返回所有结果。如果设置了限制,则返回最多指定数量的结果。
-
**kwargs参数:用于传递其他参数,例如CSS选择器等,例如:
soup.find_all(“a”, class_=“poet”,id=‘link1’)
2.5 遍历文档树
参考了下列文档:
1、https://blog.csdn.net/Eastmount/article/details/109497225
- 获得第一个子节点:
children
或者contents
,
真正使用的时候,一般使用find_all,而不用这些节点,这些节点是为了让结构更清晰。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,"html.parser")
print(soup.head.contents) # 输出hrad标签下的第一个子标签
for contents in soup.head.contents:
print(contents)
- 如果需要获取多个节点内容时,则使用
strings
属性:
for content in soup.head.strings:
print(content)
- 输出的字符串可能包含多余的空格或换行,这里需要使用
stripped_strings
方法去除多余的空白内容,代码如下:
for content in soup.stripped_strings:
print(content)
其他文档树的节点,搜索文档树与遍历文档树类似,包括父节点、子节点、兄弟节点等,推荐从官网自行学习。一般来说都是使用
find_all
03 BOM和DOM
为了学好使用BS4,很有必要了解BOM和DOM,原来想写在一起的,后来发现可能需要单独研究,本篇暂时就到这里结束啦,下一篇更新BOM和DOM,后续持续教你写爬虫~