Python爬虫遇urllib.error.HTTPError 404错误,求解决方案
解决urllib.error.HTTPError: 404 Not Found问题
嘿,我来帮你看看这个404的问题!你遇到的情况挺常见的——浏览器能正常访问目标链接,但用urllib爬取就返回404,大多是因为请求头不够“像真人”,或者urllib的默认处理逻辑和浏览器有差异。下面几个方案你可以挨个试试:
1. 补全更完整的请求头信息
浏览器发送的请求头远不止User-Agent这一项,很多服务器会检查Accept、Accept-Language这类字段来判断请求是否合法。你可以把请求头补得更贴近真实浏览器,试试修改这部分代码:
from urllib.request import urlopen, Request from bs4 import BeautifulSoup as soup import json atd_url = 'https://courses.lumenlearning.com/catalog/achievingthedream' # 补充更贴近浏览器的请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Referer': 'https://courses.lumenlearning.com/', 'Connection': 'keep-alive' } res = Request(atd_url, headers=headers) uClient = urlopen(res) page_html = uClient.read() uClient.close() # 后面的解析代码保持不变就行
2. 检查是否存在重定向问题
有些网站会悄悄对请求做重定向,虽然urllib默认会处理重定向,但如果请求头不全,可能导致重定向失败。你可以打开浏览器访问目标链接,看看地址栏最终显示的URL和你代码里的是否一致——如果不一样,直接用最终的URL替换掉代码里的地址试试。
3. 改用requests库(强烈推荐!)
说实话,urllib用起来有点繁琐,requests库是Python爬虫的主流选择,它默认处理重定向,而且请求头的设置更灵活,还能自动处理很多细节。下面是用requests改写后的完整代码,你可以直接用:
import requests from bs4 import BeautifulSoup as soup import json atd_url = 'https://courses.lumenlearning.com/catalog/achievingthedream' # 只需要简单设置User-Agent就行,requests会自动补其他必要的头 headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36' } # 发送请求,自动处理重定向 response = requests.get(atd_url, headers=headers) response.raise_for_status() # 这行代码会在请求失败时直接抛出错误,方便排查 page_html = response.text # 解析部分和你原来的差不多,我加了strip()去除多余空格,看起来更干净 page_soup = soup(page_html, "html.parser") containers = page_soup.findAll("div", {"class": "book-info"}) data = [] for container in containers: item = {} item['type'] = "Course" item['title'] = container.h2.text.strip() item['author'] = container.p.text.strip() item['link'] = container.p.a["href"] item['source'] = "Achieving the Dream Courses" item['base_url'] = "https://courses.lumenlearning.com/catalog/achievingthedream" data.append(item) # 加上indent=4,生成的JSON文件会更易读 with open("./json/atd-lumen.json", "w") as writeJSON: json.dump(data, writeJSON, ensure_ascii=False, indent=4)
4. 用curl命令测试请求
你也可以在终端里用curl命令模拟请求,看看服务器返回什么:
curl -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36" https://courses.lumenlearning.com/catalog/achievingthedream
如果curl返回404,那可能是服务器对你的IP有限制(比如反爬);如果返回正常,那就是代码里的请求头还需要调整。
先试试上面的前两个方案,尤其是改用requests库,应该能解决你的问题!
内容的提问来源于stack exchange,提问作者brawlins4




