使用BeautifulSoup从URL列表提取文章标题和正文时遇索引错误求助
解决BeautifulSoup提取文章内容时的索引错误
错误原因
直接通过content[0]或title[16]访问列表元素时,若soup.findAll()未找到匹配的HTML元素,会返回空列表,此时访问索引就会触发IndexError。比如部分页面可能没有td-post-content类的正文容器,或者entry-title元素数量不足16个。
解决方案
1. 先验证请求是否成功
在解析页面之前,确认HTTP请求返回状态码为200(请求成功),避免解析无效的页面内容。
2. 安全访问元素,避免空列表索引
- 对于单个目标元素(比如正文、标题),优先用
soup.find()替代soup.findAll(),find()找不到元素时返回None,可先判断是否存在再提取文本。 - 如果必须用
findAll(),先检查列表长度是否大于目标索引,再进行访问。
3. 加入异常捕获,避免循环中断
用try-except块捕获可能的异常,确保单个页面解析失败时,循环能继续处理下一个URL。
4. 优化代码结构
将请求头headers定义在循环外,避免重复创建;用df.iterrows()遍历DataFrame更简洁直观。
修改后的代码示例
# 把headers提到循环外,避免重复定义 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'} for idx, row in df.iterrows(): url = row.values[0] try: page = requests.get(url, headers=headers) # 验证请求是否成功 if page.status_code != 200: print(f"URL {url} 请求失败,状态码:{page.status_code}") continue soup = BeautifulSoup(page.content, 'html.parser') # 提取正文:用find()安全获取元素 content_elem = soup.find(attrs={'class':'td-post-content'}) content = content_elem.text.strip() if content_elem else "未找到正文内容" # 提取标题:先判断列表长度是否满足索引需求 title_elems = soup.findAll(attrs={'class':'entry-title'}) # 原代码用了title[16],索引从0开始,需确保列表至少有17个元素 if len(title_elems) >= 17: title = title_elems[16].text.strip() else: # 备选方案:取第一个标题元素,或提示未找到 title = title_elems[0].text.strip() if title_elems else "未找到标题" print(f"标题:{title}") print(f"正文预览:{content[:200]}...") except Exception as e: print(f"处理URL {url} 时出错:{str(e)}") continue
额外提示
- 不同页面的HTML结构可能不一致,建议用浏览器开发者工具(F12)检查目标页面的正文和标题实际对应的选择器,确保选择器准确。
- 如果多个页面结构差异大,可以针对不同域名或页面类型编写不同的提取逻辑。
内容的提问来源于stack exchange,提问作者Ashish Sharma
相关产品推荐
相关产品推荐

