Beautiful Soup
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。
它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。
BeautifulSoup 不仅支持 HTML 解析器,还支持一些第三方的解析器,如 lxml,XML,html5lib 但是需要安装相应的库。如果我们不安装,则 Python 会使用 Python 默认的解析器,其中 lxml 解析器更加强大,速度更快,推荐安装。
官方文档
安装
1 | # 速度慢推荐淘宝源https://mirrors.aliyun.com/pypi/simple |
2 | pip install bs4 |
3 | # 顺带安装好用的解析器 |
4 | pip install lxml |
5 | pip install html5lib |
解析器优缺点
解析器 使用方法 优势 劣势 Python标准库 BeautifulSoup(markup, “html.parser”) Python的内置标准库
执行速度适中
文档容错能力强Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 lxml HTML 解析器 BeautifulSoup(markup, “lxml”) 速度快
文档容错能力强需要安装C语言库 lxml XML 解析器 BeautifulSoup(markup, “xml”) 速度快
唯一支持XML的解析器需要安装C语言库 html5lib BeautifulSoup(markup, “html5lib”) 最好的容错性
以浏览器的方式解析文档
生成HTML5格式的文档速度慢
不依赖外部扩展推荐使用lxml作为解析器,因为效率更高。
在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定。- 提示
如果一段HTML或XML文档格式不正确的话,那么在不同的解析器中返回的结果可能是不一样的
- 提示
使用
将一段文档传入BeautifulSoup的构造方法,就能得到一个文档的对象, 可以传入一段字符串或一个文件句柄。
1 | from bs4 import BeautifulSoup |
2 | ''' |
3 | 1.文档被转换成Unicode,并且HTML的实例都被转换成Unicode编码 |
4 | 2.Beautiful Soup选择最合适的解析器来解析这段文档,如果手动指定解析器那么Beautiful Soup会选择指定的解析器来解析文档 |
5 | 3.Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象, |
6 | 所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment |
7 | ''' |
8 | soup = BeautifulSoup(open("index.html")) |
9 | |
10 | soup = BeautifulSoup("<html>data</html>") |
常用方法
find_all
find
prettify
按照标准的缩进格式的结构输出
1
from bs4 import BeautifulSoup
2
soup = BeautifulSoup(html_doc, 'html.parser')
3
print(soup.prettify())
使用实战
随意找了个大牛博客爬一爬,大牛勿怪,只用于测试效果
1 | ''' |
2 | pip installl requests |
3 | pip installl bs4 |
4 | pip install lxml |
5 | ''' |
6 | import requests |
7 | from bs4 import BeautifulSoup |
8 | |
9 | def get_data(url): |
10 | ''' |
11 | 根据url获取数据 |
12 | :param url: 网站url |
13 | :return: |
14 | ''' |
15 | # 伪装浏览器(随意打开浏览器调试模式,抓取浏览器的http的headers取得User-Agent信息) |
16 | headers = {'User-Agent': |
17 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) ' |
18 | 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'} |
19 | r = requests.get(url, headers=headers) |
20 | # 设置网页数据编码格式,一般utf-8 |
21 | r.encoding = 'utf-8' |
22 | return r |
23 | |
24 | def data_handle(data): |
25 | ''' |
26 | 数据提取(爬虫最重要的一步,每个网站信息都不一样,所有基本都需要自己去分析网页信息) |
27 | 利用谷歌浏览器的检查功能,查看Elements,慢慢分析 |
28 | :param data: |
29 | :return: |
30 | ''' |
31 | soup = BeautifulSoup(data,'lxml') |
32 | blog_info = {} |
33 | # 获取博客基本信息 |
34 | # <h1 id="page-title" class="asset-name entry-title">敏捷开发入门教程</h1> |
35 | title = soup.find("h1",class_ = 'asset-name entry-title').string |
36 | # <p class="vcard author">作者: <a class="fn url" href="http://www.ruanyifeng.com">阮一峰</a></p> |
37 | author = soup.find('p',class_ = 'vcard author').a.string |
38 | date_time = soup.find('abbr',class_ = 'published').string |
39 | |
40 | # 获取博客文章的全部内容 |
41 | context = soup.find('div',id = 'main-content').get_text() |
42 | |
43 | # 获取博客所有<a>标签的链接 |
44 | links = [] |
45 | for link in soup.find_all('a'): |
46 | links.append(link.get('href')) |
47 | |
48 | # 获取所有图片 |
49 | imgs = [] |
50 | for img in soup.find_all('img'): |
51 | imgs.append(img.get('src')) |
52 | |
53 | blog_info.update({ |
54 | 'title':title, |
55 | 'author':author, |
56 | 'date_time':date_time, |
57 | 'context':context, |
58 | 'links':links, |
59 | 'imgs':imgs |
60 | }) |
61 | |
62 | return blog_info |
63 | |
64 | if __name__ == '__main__': |
65 | # 随意找一个网页爬一爬 |
66 | url = 'http://www.ruanyifeng.com/blog/2019/03/agile-development.html' |
67 | # 获取网页信息 |
68 | res = get_data(url) |
69 | |
70 | # 提取需要的网页信息 |
71 | info = data_handle(res.text) |
72 | |
73 | # 信息入库(csv、mysql、MongoDB都行) |
74 | print(info) |
75 | with open('/Users/Pocket/自我提升道路/爬虫/test_data/day-01.txt','a+') as f: |
76 | f.write(info.get('title') + '\n') |
77 | f.write(info.get('author') + '\n') |
78 | f.write(info.get('date_time') + '\n') |
79 | f.write(info.get('context')) |