# 注:参考于Day3 - 6.bs4解析具体使用讲解_哔哩哔哩_bilibili
import requests
from bs4 import BeautifulSoup
url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
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, headers=headers).text
soup = BeautifulSoup(page_text, 'lxml')
li_list = soup.select(".book-mulu > ul > li")
proxies = {
'http': 'http://your_proxy_address',
'https': 'https://your_proxy_address',
}
with open('sanguoyanyi.txt', 'a', encoding='utf-8') as f:
for li in li_list:
title = li.a.string
new_url = 'https://www.shicimingju.com' + li.a['href']
try:
# 设置超时时间,避免长时间等待
detail_page_text = requests.get(url=new_url, headers=headers, proxies=proxies, timeout=10).text
detail_soup = BeautifulSoup(detail_page_text, 'lxml')
detail_tags = detail_soup.find('div', class_='chapter-content')
if detail_tags:
content = detail_tags.text
f.write(title + '\n' + content + '\n')
print(title, '爬取成功!!')
else:
print(f"获取 {title} 内容失败 (URL: {new_url})")
except requests.exceptions.Timeout:
print(f"请求 {new_url} 超时,跳过该章节")
except requests.exceptions.RequestException as e:
print(f"请求 {new_url} 时出现异常:{e}")
soup = BeautifulSoup(page_text, 'lxml')
BeautifulSoup
通过 lxml
解析器解析 page_text
,并生成一个 soup
对象,方便你对 HTML 进行操作和数据提取。
li_list = soup.select(".book-mulu > ul > li")
soup.select()
使用 CSS 选择器选择所有.book-mulu > ul > li
元素,这些元素代表《三国演义》章节的目录列表。.book-mulu
是包含章节目录的div
的类名,ul
是无序列表,li
是列表项。
proxies = {
'http': 'http://your_proxy_address',
'https': 'https://your_proxy_address',
}
proxies
是代理设置。如果你需要通过代理访问网页,可以在这里配置代理地址。your_proxy_address
是你代理服务器的地址。如果不需要代理,可以忽略这个部分。
with open('sanguoyanyi.txt', 'a', encoding='utf-8') as f:
with open()
打开一个名为 sanguoyanyi.txt
的文件,以追加(a
模式)方式写入内容,encoding='utf-8'
用于确保正确处理中文字符。f
是文件对象,用来写入数据。
for li in li_list:
这是一个循环,遍历所有从目录页提取的章节链接列表。
title = li.a.string
li.a.string
提取每个 li
标签中的超链接文本,也就是章节标题,并将其存储在 title
变量中。
new_url = 'https://www.shicimingju.com' + li.a['href']
通过 li.a['href']
获取章节详情页的相对链接,并将其拼接为完整的 URL(以 https://www.shicimingju.com
为前缀),存储在 new_url
变量中。
try:
detail_page_text = requests.get(url=new_url, headers=headers, proxies=proxies, timeout=10).text
- 使用
requests.get()
请求new_url
,获取章节详情页的内容,添加了timeout=10
参数来设置超时时间(10秒),避免请求卡住。响应的文本存储在detail_page_text
中。 try-except
用于捕获请求过程中的异常,如超时或网络问题。
detail_soup = BeautifulSoup(detail_page_text, 'lxml')
再次使用 BeautifulSoup
对章节详情页的 HTML 进行解析,生成 detail_soup
对象。
detail_tags = detail_soup.find('div', class_='chapter-content')
detail_soup.find()
找到详情页中类名为 chapter-content
的 div
标签,该标签包含章节的具体内容。
if detail_tags:
content = detail_tags.text
f.write(title + '\n' + content + '\n')
print(title, '爬取成功!!')
如果找到了 chapter-content
标签,提取其中的文本内容,并将章节标题和内容写入文件 sanguoyanyi.txt
。同时,打印成功信息。
else:
print(f"获取 {title} 内容失败 (URL: {new_url})")
如果没有找到 chapter-content
标签,打印获取内容失败的信息。
except requests.exceptions.Timeout:
print(f"请求 {new_url} 超时,跳过该章节")
如果请求超时,捕获 Timeout
异常,并打印超时信息,跳过该章节。
except requests.exceptions.RequestException as e:
print(f"请求 {new_url} 时出现异常:{e}")
捕获其他所有请求异常,并打印异常信息,帮助调试。