Python爬虫项目开发过程中,开发者经常会遇到各类影响程序正常运行的问题,这些问题分布在请求发送、反爬应对、数据解析、存储等多个环节,需要针对性排查和解决。

请求发送阶段常见问题
请求超时或连接失败
这是最基础的问题之一,通常是因为目标服务器响应慢、网络不稳定或者请求的URL地址错误导致。可以通过设置请求超时时间、添加重试机制来解决。
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# 配置重试策略
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)
try:
# 设置超时时间为10秒
response = http.get("https://www.ipipp.com", timeout=10)
print(response.status_code)
except Exception as e:
print(f"请求失败: {e}")
请求返回403禁止访问
该问题通常是目标服务器检测到请求头不完整,判定为非浏览器请求,从而拒绝访问。需要补充完整的请求头,尤其是User-Agent字段。
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Referer": "https://www.ipipp.com/"
}
response = requests.get("https://www.ipipp.com", headers=headers)
print(response.status_code)
反爬机制相关问题
IP被封禁无法访问
当短时间内发送大量请求时,目标服务器会封禁请求IP,导致后续所有请求都无法正常响应。解决方式是使用代理IP池,轮换IP发送请求。
import requests
proxy_list = [
"http://127.0.0.1:8080",
"http://192.168.0.1:8080"
]
# 随机选择一个代理IP
import random
proxy = random.choice(proxy_list)
proxies = {
"http": proxy,
"https": proxy
}
response = requests.get("https://www.ipipp.com", proxies=proxies)
print(response.status_code)
验证码拦截请求
部分网站会在请求频率过高时弹出验证码,要求验证通过才能继续访问。可以先尝试降低请求频率,若仍出现验证码,可对接验证码识别服务,或者模拟人工操作完成验证。
数据解析阶段常见问题
解析不到目标数据
通常是因为页面数据是动态加载的,直接请求页面URL无法获取到完整数据,或者选择器表达式编写错误。可以先查看页面的网络请求,找到动态数据的接口,再针对性解析。
import requests
from bs4 import BeautifulSoup
response = requests.get("https://www.ipipp.com")
soup = BeautifulSoup(response.text, "html.parser")
# 错误示例:选择器不匹配
# title = soup.select_one("div.wrong_class")
# 正确示例:匹配正确的class
title = soup.select_one("div.correct_class")
if title:
print(title.text.strip())
else:
print("未找到目标数据,可能页面结构已变化")
编码问题导致乱码
部分网站的响应编码和requests默认编码不一致,会导致解析出的中文内容出现乱码。可以手动设置响应编码为页面声明的编码。
import requests
response = requests.get("https://www.ipipp.com")
# 设置编码为页面对应的编码,比如utf-8
response.encoding = "utf-8"
print(response.text)
数据存储阶段常见问题
数据重复存储
爬虫运行过程中如果中断重启,可能会重复爬取已经存储过的数据。可以在存储前先判断数据是否已存在,或者使用数据库的唯一索引避免重复。
import sqlite3
conn = sqlite3.connect("data.db")
cursor = conn.cursor()
# 创建表时设置url字段为唯一索引
cursor.execute("CREATE TABLE IF NOT EXISTS page_data (id INTEGER PRIMARY KEY, url TEXT UNIQUE, content TEXT)")
try:
cursor.execute("INSERT INTO page_data (url, content) VALUES (?, ?)", ("https://www.ipipp.com", "页面内容"))
conn.commit()
except sqlite3.IntegrityError:
print("该URL的数据已存在,跳过存储")
conn.close()
存储速度跟不上爬取速度
当爬取数据量较大时,频繁的IO操作会拖慢整体爬取效率。可以使用异步存储,或者先将数据存入内存队列,再批量写入存储媒介。
其他常见问题
- 程序运行一段时间后自动退出:通常是未捕获的异常导致,可以添加全局异常捕获,记录错误信息后继续运行。
- 内存占用过高:可能是爬取的数据未释放,或者使用了不合理的全局变量存储大量数据,可以及时释放无用对象,避免存储过多冗余数据。
- 爬虫被识别为自动化程序:可以随机化请求间隔,模拟人工浏览的停顿时间,同时补充更多浏览器特征字段到请求头中。