import re import requests from lxml import etree headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" } # 定义小说首页地址 index_url = 'https://www.biquge11.cc/read/12972/' # 发送网络请求 response = requests.get(index_url, headers=headers) # 筛选链接和标题 info_list = re.findall('<dd><a href ="(.*?)">(.*?)</a></dd>', response.text) # 去除前面6个数据 info_list = info_list[6:] # 遍历列表,得到每章的部分链接和标题 for info in info_list: # 从元组中取出部分链接进行拼接,获取每章的页面链接 url = 'https://www.biquge11.cc' + info[0] # 获取数据 response = requests.get(url, headers=headers) html_data = etree.HTML(response.text) # xpath筛选出文本数据,并将数据列表转换成字符串 text_list = html_data.xpath('//div[@id="chaptercontent"]/text()') text = ''.join(text_list) # 添加标题行 book_text = '\n\n' + info[1] + '\n\n' # 去除广告文本 book_text += text.replace('请收藏本站:https://www.biquge11.cc。笔趣阁手机版:https://m.biquge11.cc ', '').replace(' ', '\n') print("正在下载:" + info[1]) print(book_text) # 保存到文件 with open('斗破苍穹.txt', 'a', encoding='utf-8') as file: file.write(book_text) 这歌代码在jupyter 中运行但是出来只有标题
时间: 2025-06-10 19:06:52 浏览: 8
<think>好的,我现在需要分析用户提供的Python代码,找出为什么运行后只有章节标题而没有正文内容的原因。用户提到在Jupyter中运行,但输出只有标题。首先,我会通读代码,理解其结构和逻辑。
代码的主要功能是从一个小说网站抓取各章节内容并保存到文本文件。首先,它导入必要的库:re、requests和lxml的etree。然后设置请求头,访问小说首页,用正则表达式提取章节链接和标题,跳过前6个条目。接着遍历每个章节链接,拼接完整URL,请求页面内容,使用XPath提取正文,处理文本后写入文件。
用户的问题是,生成的文本文件只有标题,没有正文内容。可能的原因有几个方面:
1. **XPath表达式问题**:可能XPath路径不正确,无法正确提取到正文内容,导致text_list为空。需要检查网页结构,确认章节内容所在的div的id是否为“chaptercontent”,是否有其他嵌套结构。
2. **网站结构变化或反爬机制**:可能目标网页的HTML结构发生了变化,或者服务器检测到爬虫行为,返回了不同的内容,比如验证页面或动态加载的内容,导致无法获取正文。
3. **请求头或Cookie问题**:虽然代码中设置了User-Agent,但可能网站需要其他头信息或Cookie才能正确响应,尤其是如果网站有反爬措施的话。
4. **正则表达式过滤问题**:在提取章节链接时使用的正则表达式可能不准确,导致获取的链接不正确,请求章节页面时返回错误内容。
5. **文本处理问题**:在替换或拼接文本时,可能错误地过滤或处理了正文内容,导致最终结果为空。
6. **文件写入模式问题**:使用追加模式'a'写入文件,可能之前有残留数据,但更可能的是内容本身的问题。
接下来,我需要逐步验证这些可能性。首先,检查XPath是否正确。用户代码中使用的是`//div[@id="chaptercontent"]/text()`,这假设正文在id为chaptercontent的div下的直接文本节点。如果实际内容在更深层的标签内,比如<p>标签,那么可能需要调整XPath,例如使用`//div[@id="chaptercontent"]//text()`来获取所有嵌套文本。
其次,检查请求是否成功。在代码中,请求章节页面后是否检查了response的状态码?比如,可能返回403或404,导致html_data为空,进而text_list为空。可以添加print(response.status_code)来确认请求是否成功。
另外,处理文本时,替换了特定广告文本,但可能广告文本的格式有变化,导致替换不完全,但不会导致整个正文消失。但若text本身为空,替换后的结果自然也是空。
可能的解决方案包括:
- 修改XPath表达式,确保能正确提取正文内容。
- 检查网页结构是否变化,是否需要处理动态加载的内容。
- 添加异常处理和状态码检查,确保请求成功。
- 使用更稳健的解析方法,如BeautifulSoup代替正则表达式和XPath。
例如,如果章节内容被包裹在<p>标签内,XPath可能需要调整为`//div[@id="chaptercontent"]//p/text()`,或者使用更通用的`//div[@id="chaptercontent"]//text()`来获取所有文本节点。
此外,用户可能在Jupyter中运行时,路径或文件权限有问题,导致写入失败,但用户反馈有标题,说明文件写入是成功的,只是内容为空,所以问题更可能出在正文提取环节。
总结,最可能的原因是XPath表达式未能正确匹配到正文内容,导致text_list为空,从而book_text只有标题部分。需要调整XPath或检查网页结构。</think>以下是代码问题的分析及解决方案:
**问题定位**:
通过分析,正文内容未获取的主要原因是XPath路径不准确。原代码使用:
```python
text_list = html_data.xpath('//div[@id="chaptercontent"]/text()')
```
实际网页中正文内容通常包含多个`<p>`标签或换行符,直接子文本节点可能为空。
**解决方案**:
1. **修改XPath表达式**:
```python
text_list = html_data.xpath('//div[@id="chaptercontent"]//text()')
```
使用`//text()`获取所有嵌套文本节点
2. **添加请求状态验证**:
```python
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"请求失败,状态码:{response.status_code}")
continue
```
3. **完整修正代码**:
```python
import re
import requests
from lxml import etree
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
}
index_url = 'https://www.biquge11.cc/read/12972/'
response = requests.get(index_url, headers=headers)
response.encoding = 'utf-8' # 显式设置编码
info_list = re.findall(r'<dd><a href="(.*?)">(.*?)</a></dd>', response.text)[6:]
for info in info_list:
url = 'https://www.biquge11.cc' + info[0]
try:
response = requests.get(url, headers=headers, timeout=10)
response.encoding = 'utf-8'
if response.status_code != 200:
print(f"章节 {info[1]} 请求失败,状态码:{response.status_code}")
continue
html_data = etree.HTML(response.text)
# 修正后的XPath
text_list = html_data.xpath('//div[@id="chaptercontent"]//text()')
if not text_list:
print(f"章节 {info[1]} 内容为空,检查XPath")
continue
text = ''.join(text_list).replace('请收藏本站:https://www.biquge11.cc。笔趣阁手机版:https://m.biquge11.cc', '')
text = text.replace('\u3000', '\n').strip() # 处理全角空格
book_text = f'\n\n{info[1]}\n\n{text}'
print(f"正在下载:{info[1]}")
with open('斗破苍穹.txt', 'a', encoding='utf-8') as f:
f.write(book_text)
except Exception as e:
print(f"下载 {info[1]} 时出错:{str(e)}")
```
**改进说明**:
1. 增加编码声明:`response.encoding = 'utf-8'` 确保正确解码
2. 添加异常处理:网络请求超时、状态码异常等情况
3. 优化文本处理:处理Unicode全角空格`\u3000`
4. 增加错误提示:当章节内容为空时给出明确提示
5. 使用原始字符串(r-string)处理正则表达式
**验证建议**:
1. 单独测试某个章节URL,打印response.text确认是否包含有效内容
2. 在Jupyter中逐步运行代码,检查每个步骤的输出
3. 检查生成文件是否有写入权限
4. 考虑添加延迟避免被封:在循环内添加`time.sleep(1)`
如果仍然无法获取内容,可能是网站启用了反爬机制(如:需要Cookies或JavaScript渲染),建议:
- 添加Referer头
- 使用Selenium模拟浏览器
- 检查是否有动态加载内容
阅读全文
相关推荐



















