BeautifulSoup库的简单入门
-
简介
在解析爬虫爬取到的HTML页面时,一般采取的方法有两种,一种是通过xpath的方式来获取要定位的元素对象,优点是速度快,直接。但是xpath的定位方式的语法需要有学习成本。 另外一种就是beautifulSoup库。 一般在解析页面的时候可能需要两种方式搭配使用。本文将介绍beautifulSoup库的简单使用方法。
-
安装
通过pip 安装
pip install beautifulsoup4
-
使用
-
引入:
from bs4 import BeautifulSoup
一般要分析的网络资源有两种,一种是下载好的html文本文件,另外一种是直接从网络上获取的数据流(这里的描述可能不太准确)。
对于第一种的待解析文本,我们使用
soup = BeautifulSoup(open('test.html'), 'html.parser')
对于直接解析网络数据流的方式,我们采用代码
session = cloudscraper.create_scraper() # 为了绕开cloudflare 5秒 反爬的限制,用cloudscraper 代替 requests 库 response = session.get(url=url) soup = BeautifulSoup(response.text, 'html.parser')
这样我们就得到了一个
soup
对象。-
soup
对象的常用方法介绍-
soup.prettify()
格式化输出网页文本内容 -
find_all(name, attrs)
查找页面中所有的指定元素name
参数: 标签名, 如div
,a
,span
等attrs
参数: 属性, 是个字典类型-
获取页面元素的标签
如我们要获取页面中的
a
标签,就可以采用soup.find_all(name="a")
的方式获取页面中的所有a
标签,当然,一般页面中会存在多个a
标签,所以这个函数的返回值会是一个列表,可以通过循环的方式拿到自己需要的那个a
标签。 -
获取指定标签的属性
如果我们需要获取
id
为nr_title
的a
标签,那么就可以使用find_all(name="a", attrs={'id':'nr_title'})
, 当然,如果还有其他的限制条件,都可以添加到attrs
参数中去。
同样的还有一个
find()
方法,使用方法和find_all()
类似,一般用于对单个标签元素的查找。 -
-
-
标签对象介绍
每一个标签对象都有一个
attrs
属性,以键值对的方式返回该标签所具有的所有属性,如:id
,name
,class
herf
等, 比如想要获取a
标签的href
属性(爬虫中最常用的操作方法),就可以使用:href = a['href']
-
以上基本上搭配xpath
, 页面上的所有元素就都可以获取的到。剩下的逻辑就是如果爬取和下载了。
最后附上爬取某小说网站小说的源代码:
# !/usr/bin/python
# -*- coding:UTF-8 -*-
"""
* 本程序的主要功能如下:
* 1. 爬取 余华 《许三观卖血记》
* 2.
* @author: Kenny Li
* @file: spider2.py
* @time: 2021-7-19 15:02
* e-Mail: yifei1193@163.com
"""
import os
import cloudscraper
from bs4 import BeautifulSoup
from utils.settings import ROOT_DIR
# 为了绕开cloudflare 5秒 反爬的限制,用cloudscraper 代替 requests 库
session = cloudscraper.create_scraper()
def get_chapter(url):
# 获取目录部分所有章节的URL
response = session.get(url=url)
soup = BeautifulSoup(response.text, 'html.parser')
tags_a = soup.find_all(name='ul')[1].find_all(name='a')
all_charpter_list = []
for a in tags_a:
all_charpter_list.append(a['href'])
return all_charpter_list
def spider(url, fp):
# 开始逐个页面爬取并写入到文本文件中
response = session.get(url=url)
soup = BeautifulSoup(response.text, 'html.parser')
title = soup.find_all(name='h1', attrs={'id': 'nr_title'})[0].text
print('{}的url是:\n{}'.format(title,url))
div = soup.find(name='div', attrs={'id': 'nr1'})
content = div.find_all(name='p')
title = "\u3000\u3000\u3000\u3000\u3000\u3000\u3000★★★★★ {} ★★★★★".format(title)
fp.write(title)
fp.write('\r\n\r\n')
for p in content:
fp.write('\u3000\u3000{}'.format(p.text))
fp.write('\r\n')
fp.write('\r\n')
print('{}爬取完成!'.format(title))
if __name__ == '__main__':
url = 'https://www.xxx.com/xusanguanmaixueji/'
book_name = "许三观卖血记"
book_path = os.path.join(ROOT_DIR,'output/{}.txt'.format(book_name))
with open((book_path), "a", encoding='utf8') as fp:
# with open(os.path.join(ROOT_DIR, 'output/许三观卖血记.txt'), "a", encoding='utf8') as fp:
href = get_chapter(url)
for h in href:
# print(h)
spider(h, fp)
print("全书爬取完成!书籍存储目录为:{}".format(book_path))
fp.close()