如何在requests.urlretrieve中携带Cookie下载受保护的.torrent文件
我来帮你梳理下问题所在,以及对应的解决办法:
第一个错误的原因
你用request.urlretrieve时传data=cookies是完全错误的——urlretrieve的data参数是用来传递POST请求的表单数据的,而且要求是字节类型,你传了字符串组成的Cookie字典,自然会触发「字符串和字节无法拼接」的类型错误。另外,urlretrieve要传Cookie的话,得通过headers参数把Cookie拼写成字符串传进去,不过这种方式不如用requests库来得方便。
第二个代码的问题
你改用requests.session()后,没有把之前验证有效的Cookie传给session或者get请求,相当于你发起了一个未携带认证信息的请求,站点自然返回404页面,所以你下载的其实是错误提示的HTML,而不是真正的torrent文件。
正确的解决方案
既然你之前用requests.get带Cookie能成功爬取页面,那下载torrent文件也用同样的逻辑就行,直接给get请求带上你的Cookie字典,然后把响应内容写入文件:
方案1:直接带Cookie发起请求
import requests from bs4 import BeautifulSoup # 你的有效Cookie字典 cookies = {'uid': '232323', 'pass': '31321231jh12j3hj213hj213hk', '__cfduid': 'kj123kj21kj31k23jkl21j321j3kl213kl21j3'} # 构造下载URL(假设你已经正确获取到torrent_url的后半段) torrent_url = 'https://www.somesite.com/' + torrent_url filename = torrent_url.split('/')[-1] save_as = f'torrents/{filename}.torrent' try: # 带上Cookie发起GET请求,stream=True适合下载大文件 response = requests.get(torrent_url, cookies=cookies, stream=True) # 先检查响应状态码,确认请求成功 response.raise_for_status() with open(save_as, 'wb') as f: for chunk in response.iter_content(chunk_size=1024): if chunk: f.write(chunk) print(f"Download successful for: {filename}") except requests.exceptions.RequestException as e: print(f"Error: {e}")
方案2:用Session维持会话(更推荐)
如果后续还有多个需要认证的请求,用Session会更方便,它会自动保存和携带Cookie:
import requests from bs4 import BeautifulSoup # 创建Session对象 session = requests.Session() # 把Cookie添加到Session的cookie jar里 session.cookies.update({ 'uid': '232323', 'pass': '31321231jh12j3hj213hj213hk', '__cfduid': 'kj123kj21kj31k23jkl21j321j3kl213kl21j3' }) # 先爬取页面(Session会自动保存后续需要的Cookie) try: page_response = session.get(s_string) page_response.raise_for_status() soup = BeautifulSoup(page_response.content, 'html.parser') # 这里处理爬取逻辑,获取torrent_url的后半段 # ... except requests.exceptions.RequestException as e: print(f"Failed to fetch page: {e}") # 下载torrent文件 torrent_url = 'https://www.somesite.com/' + torrent_url filename = torrent_url.split('/')[-1] save_as = f'torrents/{filename}.torrent' try: torrent_response = session.get(torrent_url, stream=True) torrent_response.raise_for_status() with open(save_as, 'wb') as f: for chunk in torrent_response.iter_content(chunk_size=1024): if chunk: f.write(chunk) print(f"Download successful for: {filename}") except requests.exceptions.RequestException as e: print(f"Download error: {e}")
额外建议
有些站点会验证请求的User-Agent,如果上面的代码还是不行,可以给请求加上浏览器的User-Agent头,模拟真实浏览器请求:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } # 在get请求里加上headers参数 response = requests.get(torrent_url, cookies=cookies, headers=headers, stream=True) # 或者给Session添加默认headers session.headers.update(headers)
只要你的Cookie是有效的(和浏览器里的一致),加上正确的请求参数,应该就能成功下载到可用的torrent文件了。
内容的提问来源于stack exchange,提问作者Nanoni
相关产品推荐
相关产品推荐

