使用 BeautifulSoup 爬取网页内容
1. 安装依赖
在开始使用 BeautifulSoup
之前,需要安装必要的依赖包:
pip install beautifulsoup4 lxml requests
2. 基本使用方法
以下是使用 BeautifulSoup
解析网页内容的基本代码:
from bs4 import BeautifulSoup
import requests
if __name__ == "__main__":
url = "https://example.com" # 替换为目标网址
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
page_text = requests.get(url=url, headers=headers).text
soup = BeautifulSoup(page_text, 'lxml')
3. 常用方法
3.1 输出标签名 tagName
的第一组标签内容
使用 soup.a
或 soup.div
获取 HTML 中第一个 <a>
或 <div>
标签:
print(soup.a) # 输出第一个 <a> 标签
print(soup.div) # 输出第一个 <div> 标签
3.2 使用 find()
查找标签
find()
方法用于查找第一个符合条件的标签:
# 查找第一个 <div> 标签
print(soup.find('div'))
# 查找 class 为 'song' 的 <div> 标签
print(soup.find('div', class_='song'))
3.3 使用 find_all()
查找所有匹配标签
find_all()
方法返回所有符合条件的标签,结果为列表:
# 查找所有 <a> 标签
print(soup.find_all('a'))
# 查找 class 为 'link' 的所有 <a> 标签
print(soup.find_all('a', class_='link'))
3.4 使用 CSS 选择器查找标签
select()
方法支持 CSS 选择器查找标签,返回所有符合条件的标签列表:
# 查找所有 class 为 'content' 的标签
print(soup.select('.content'))
# 查找 id 为 'main' 的标签内的直接子元素
print(soup.select('#main > div > a'))
# 查找所有层级的 <ul> -> <li> -> <a> 标签
print(soup.select('ul li a'))
选择器说明:
>
:选择直接子元素。- 空格:选择所有层级的子元素。
4. 提取内容和属性
4.1 提取标签中的文本内容
.text
或.get_text()
:提取标签及其子标签的所有文本内容。.string
:提取标签的直接文本内容。
tag = soup.select('.content')[0] # 假设存在符合条件的标签
print(tag.text) # 获取标签内所有文本内容
print(tag.get_text()) # 功能类似 .text
print(tag.string) # 获取标签的直接文本内容
4.2 提取标签属性
可以像访问字典一样提取标签的属性值:
# 提取 <a> 标签的 href 属性
a_tag = soup.select('a')[0] # 假设存在符合条件的标签
print(a_tag['href'])
5. 注意事项
-
编码问题
如果网页内容显示乱码,可以尝试手动设置编码:page_text = requests.get(url=url, headers=headers).content.decode('utf-8')
-
反爬机制
如果目标网站存在反爬机制,可以尝试以下方法:- 设置请求头中的
User-Agent
。 - 增加请求间隔,避免频繁访问。
- 使用代理 IP。
- 设置请求头中的
-
异常处理
为避免因网络或数据格式问题导致程序中断,可以添加异常处理:try: response = requests.get(url=url, headers=headers, timeout=10) response.raise_for_status() except requests.exceptions.RequestException as e: print(f"Error: {e}")
实战体验
- 目标:爬取指定小说网站的部分指定的小说
import os
import requests
from bs4 import BeautifulSoup
if __name__ == "__main__":
if not os.path.exists('novel/'):
os.mkdir('novel/')
book_name = input('输入小说名称(全拼)')
url = f'https://www.zhonghuadiancang.com/wenxueyishu/{book_name}/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'
}
response = requests.get(url=url, headers=headers)
response.encoding = 'utf-8'
page_text = response.text
soup = BeautifulSoup(page_text, 'lxml')
novel_path = 'novel/' + book_name + '.txt'
chapter_list = soup.find('ul', class_='list-group').select('li')
with open(novel_path, 'w', encoding='utf-8') as fp:
for i in chapter_list:
novel_title = i.a.string
fp.write(novel_title + '\n')
chapter = requests.get(i.a['href'], headers=headers)
chapter.encoding = 'utf-8'
chapter_data = BeautifulSoup(chapter.text, 'lxml')
chapter_data_list = chapter_data.find('div',class_="panel-body").p
for j in chapter_data_list:
fp.write(j.string + '\n')
print(novel_title)
print('爬取完毕')
- 代码效果描述:逐步爬取指定小说的章节,并在代码所在文件夹中生成一个novel文件夹,其中包含小说的txt文件
- 找到novel文件夹中的txt文件,效果如下: