跳到主要内容Python 爬虫高频问题与解决方案 | 极客日志Python算法
Python 爬虫高频问题与解决方案
Python 爬虫开发中的 30 个高频问题及解决方案,涵盖 SSL 证书验证、JSONP 解析、URL 参数提取、反爬拦截(IP 封禁、UA 检测)、动态页面抓取、数据解析与存储异常等核心场景。内容包括 HTTPError 处理、正则匹配、路径编码、列表操作、缩进错误修复以及虚拟滚动翻页、JS 加密数据抓取等进阶问题的实战代码示例,帮助开发者快速定位并解决常见报错。
魔法巫师0 浏览 本文整理了 Python 爬虫开发中的 30 个高频问题及对应解决方案,覆盖 SSL 证书验证、JSONP 数据解析、URL 参数提取等基础场景,也针对反爬拦截(IP 封禁、User-Agent 检测)、动态页面抓取、数据解析/存储异常等核心痛点提供实战代码。包含 HTTPError: Forbidden、unicode 路径编码、正则匹配失败等具体报错的解决方法,还详解了虚拟滚动导致的翻页数据重复、JS 加密数据抓取等进阶问题,所有方案均附可直接复用的代码示例。
1. SSL 证书验证
爬取 HTTPS 网站或接口时,如果遇到不受信任的 SSL 证书,可以添加以下代码来忽略 SSL 证书验证:
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
2. JSONP 数据解析
爬取 JSONP 接口时,返回的数据需要去掉 callback 名称和外层括号。可以通过以下方式过滤:
import re
import requests
getOneSongInfoCallback = json.loads(re.match(r".*?({.*}).*", requests.get(url, headers=headers).text)[1])
3. URL 参数提取
import urllib.parse as parse
parse_query = parse.urlparse(url).query
qs = parse.parse_qs(parse_query)
4. 反爬拦截处理
网站可能会通过验证码、User-Agent 检查、IP 封禁等方式阻止爬虫。
- 设置合理的请求头,模拟浏览器行为,包括 User-Agent、Referer 等。
- 使用代理 IP 或轮换 IP 地址,避免 IP 被封禁。
- 对于验证码,可以尝试使用验证码识别服务,或手动处理。
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
'Referer': 'http://www.example.com'
}
proxies = {
'http': 'http://your_proxy_ip:port',
'https': 'http://your_proxy_ip:port'
}
response = requests.get(url, headers=headers, proxies=proxies)
5. 动态页面抓取
问题: 许多网站使用 JavaScript 动态生成内容,简单的 HTTP 请求无法获取这些数据。
解决方案:
- 使用 Selenium 等自动化测试工具模拟浏览器行为,抓取动态内容。
- 分析 Ajax 请求,使用 requests 库模拟发送 Ajax 请求。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(url)
content = driver.page_source
driver.quit()
6. 数据解析问题
问题: HTML、JSON、XML 等格式的数据解析错误,可能是因为网页结构变化或解析库不支持某些特性。
解决方案:
- 使用 BeautifulSoup、lxml 等库解析 HTML。
- 使用 json 库解析 JSON 数据。
- 使用 xml 库、ElementTree 等解析 XML 数据。
- 定期检查和更新选择器,以适应网页结构的变化。
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
data = soup.select('.class')
7. 网络请求问题
问题: 请求超时、连接错误、IP 被封禁等。
解决方案:
- 设置合理的超时时间。
- 检查网络连接,确保目标网站可访问。
- 使用代理 IP 或轮换 IP,避免 IP 被封禁。
- 合理设置请求间隔,避免频繁请求导致 IP 被封。
import requests
import time
try:
response = requests.get(url, headers=headers, proxies=proxies, timeout=5)
response.raise_for_status()
except requests.RequestException as e:
print(f"请求错误:{e}")
time.sleep(2)
8. 数据存储问题
问题: 写入文件失败、数据库连接问题等。
解决方案:
- 使用 try-except 语句捕获异常,并进行错误处理或重试操作。
- 确保文件路径正确,文件具有写权限。
- 检查数据库连接配置,确保数据库可访问。
import csv
try:
with open('data.csv', 'w', encoding='utf-8') as file:
writer = csv.writer(file)
except IOError as e:
print(f"IO 错误:{e}")
9. HTTPError: Forbidden
这个主要就是爬豆瓣的时候,访问可能太频繁了,被认出来是爬虫,就拒绝访问了。
解决方法:
- 换个 IP,不过我是手机热点,重连了依然如此,更换代理 IP 也是如此,可能是我代码的问题。
- 把代码里面 agent 的部分换一下,比如我的之前是:
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36')],换成:opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0')] 就可以访问了,更换一个浏览器,然后打开审查元素,在里面找的。
10. nothing to repeat 的问题
11. 写入 txt 的问题
with open('D:\\test.txt','a',encoding='utf-8') as f:
text = '\n'+zifuchuanbianliang
f.write(text)
差不多就是这个意思,里面的 a 就是接着写,w 就是覆盖。
12. Unicode escape 错误
这个主要就是 python 里面不能用/这个斜杠代表路径,如果代表路径需要用\反斜杠,因为/正斜杠代表转义字符,是 python 自己保留的。
13. 正则表达式排除特定字符串
输入:'一二三四五六七八九十,一二三四五六七八九十,一二三四哈六七八九十'
输出:" '三四五六' , '三四五六' "
那就可以这么写:三[^哈]{0,6}六
[^哈]就是任意不包括哈的字符(串)的意思。
14. 删除字符串的首尾
主要就是用于爬下来了特定信息,但是想把格式去掉,只包含有效信息。
str.strip() 是删掉所有位置的特定字符串
str.lstrip() 是删掉前面位置的特定字符串
str.rstrip() 是删掉末尾位置的特定字符串
15. 'type' object is not subscriptable
这个主要就是下标格式错误,应该是圆括号,用了下标。这个是很初级的错误。
16. 删除掉列表当中指定的元素
while aa in a:
a.remove(aa)
17. unindent does not match any outer indentation level
这个好像是制表符和空格混用了,缩进格式的问题。只需要在出问题的语句前后用几下 tab 就好了。
18. IP 被封或访问频率太高被拦截
19. 正确使用 XPath 之后并没有输出
解决方案之一: XPath 只能提取未注释的代码,改用正则表达式即可。
20. 容易被反爬搞死
解决方案之一: headers 中都要带上 User-Agent,而 Cookie 能不带则不带。
21. 类型错误:需要类似字节的对象,而不是字符串
解决方案之一: str 通过 encode() 方法可以编码为指定的 bytes;PS:反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是 bytes。要把 bytes 变为 str,就需要用 decode() 方法。
22. GBK 编码错误
with open('%s.html' % title, 'w', encoding='utf-8') as f:
f.write(rep)
23. 输出结果是字节类型,json 对象无法正常显示
解决方案之一: 使用 json.loads 方法即可。
24. URL 乱码问题
网址复制到 py 文件中,却变成了'乱码'???
解决方案之一: 调用 urllib.parse.unquote 进行 URL 解码即可。
25. URL 地址不规范
解决方案之一: 分析 URL 时,我们一般从第二页开始分析,而不是第一页。
26. Cookie 管理问题
不想 Cookie 中携带自身账号内容???
解决方案之一: 利用浏览器的无痕窗口功能,进入网页再取 Cookie 即可。
27. 爬取下载的图片打不开
原因:链接变量名引用错误。
措施:查看正确链接变量名并修正。
28. 数据一致性:翻页的'幽灵重复'诡异现象
第二页数据与第一页相同,翻页后元素定位失败,滚动加载时数据缺失。
根本原因:现代网页普遍采用虚拟滚动技术,DOM 中仅保留可视区域元素。
解决方案:
def scroll_to_bottom(driver, delay=2):
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(delay)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
- 方式二、API 直接抓取
通过开发者工具分析网络请求,找到数据接口:
import requests
def fetch_api_data(url, params):
headers = {
"User-Agent": "Mozilla/5.0...",
"X-Requested-With": "XMLHttpRequest"
}
response = requests.get(url, headers=headers, params=params)
return response.json()["data"]["list"]
def wait_for_new_content(driver, original_elements, timeout=10):
start_time = time.time()
while time.time() - start_time < timeout:
new_elements = driver.find_elements_by_css_selector(".item")
if len(new_elements) > len(original_elements):
return new_elements
time.sleep(0.5)
raise TimeoutError("新内容未加载")
29. 反爬虫机制:使用 JavaScript 加密数据
问题描述: 一些网站会对传输的数据进行 JavaScript 加密,防止直接获取敏感数据。
解决方法:
- 分析加密逻辑:通过浏览器的开发者工具,查看 JavaScript 加密的过程,手动模拟解密过程。
- 使用 PyExecJS 或 PyV8 解析 JavaScript:通过执行 JavaScript 代码来解密数据。
- 模拟前端请求:有时通过模拟前端与后端交互的过程,可以绕过这种加密机制。
30. 访问网页返回数据异常
- 增加 time.sleep() 时延,避免短时间频繁访问。
- 更新 headers 头,比如 cookies,看是否有新增参数。
- 看请求网页 api 是否有发生变化,重新抓包。
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown 转 HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
- HTML 转 Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online