使用urllib.request请求图片返回404错误,但浏览器可正常访问
明明浏览器能打开图片,为啥urllib请求返回404?
这种情况我碰到过好多次,基本都是请求头没带够必要标识,被网站的反爬机制给拦了。浏览器访问时会自动给请求加一堆头部信息,服务器会认为是真人在操作,就正常返回内容;但urllib默认的请求头太“朴素”,一眼就被识别成程序爬虫,直接扔给你404。
具体来说,常见的问题点有两个:
- 缺失User-Agent:urllib默认的User-Agent是类似
Python-urllib/3.6的字符串,很多网站一看到这个就知道是程序在爬,直接拒绝。而浏览器的User-Agent会标明自己是Chrome、Firefox这类正规浏览器,服务器就会放行。 - 其他头部信息不足:少数网站还会检查Referer(请求来源页面)、Accept(可接受的内容格式)这类字段,如果没有也可能被拦截。
解决方法:给请求加上浏览器风格的请求头
用urllib的话可以这么写:
import urllib.request target_url = "https://i.redd.it/53tfh959wnv41.jpg" # 模拟Chrome浏览器的请求头信息 custom_headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8' } # 构造带自定义头部的请求对象 request = urllib.request.Request(target_url, headers=custom_headers) # 发送请求并保存图片 with urllib.request.urlopen(request) as resp: with open("photo.jpg", "wb") as img_file: img_file.write(resp.read())
要是觉得urllib写起来麻烦,用requests库会更省心,代码更简洁:
import requests target_url = "https://i.redd.it/53tfh959wnv41.jpg" custom_headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } resp = requests.get(target_url, headers=custom_headers) with open("photo.jpg", "wb") as img_file: img_file.write(resp.content)
至于为啥同站点其他图片能正常请求?大概率是那些图片的反爬策略没这么严格,或者你的请求刚好符合了服务器的宽松规则,但这张图片的服务器做了更严格的校验,必须带正确的请求头才能访问。
内容的提问来源于stack exchange,提问作者smart_beaver
相关产品推荐
相关产品推荐

